avr_racer
14.11.2014, 17:52
Hallo Bastler aller Welt,
hier mal ein wenig Quelltext um einen/mehrere DS18S20 anzusprechen.
AVRStudio 4.19 730
Atmega8
STK500
Inhalt:
1. ds1820_init.asm
2. ds1820.asm
3. uart_std.asm
4. EEprom.asm
5. zeitschleifen.asm
Über pc_ser:
wird die Adresse des DS ausgelesen und im EEprom gespeichert.
Achtung zum auslesen nur immer einen DS am Pin
ds_mess_adr:
hier werden alle Slaves gleichzeitig angesprochen um die Temperaturmessung zu starten und anhand aller Adressen,
die im EEprom stehen, die Temps ausgelesen, umgewandelt, im SRAM 3bytig vorgehalten (Vozeichen,Grad,Halbegrad)
und dann über die Uart verschickt
ds_mess:
ist nur für einen Sensor am Bus vorgesehen über den Befehl SKIP_ROM + Ausgabe über UART
temp_rs232:
Ausgabe an UART wie folgt DS01 +22.50°C usw
Wünsche viel Spaß damit
ds1820_init.asm
;###########################################
;# Projekt: DS18S20 + UART #
;# #
;# #
;# Taktfrequenz des AVR: 4 MHz #
;# #
;# CS-SOFT #
;###########################################
.include "m8def.inc" ;Atmega8
.def math1h = r8
.def math1l = r9
.def math2h = R10
.def math2l = r11
.def matherghh = r12
.def mathergh = r13
.def mathergl = r14
.def mathergll = r15
.def temp0 = r16 ;
.def temp1 = r17 ;
.def temp2 = r18
.def temp3 = r19 ;
.def temp4 = r20
.def cnt = r21
.equ cpu = 4000000
.equ Baud = 9600
.equ UBRRx = cpu/(16*Baud)-1
/*
;**********LCD Port mit 74HC164
.equ port_lcd_x = portd
.equ ddrx_lcd_x = ddrd
; Pinbelegungen
; STD
.equ SClock = 2 ;LCD ;;;
.equ SRS = 2
.equ SData = 4 ;74164 ;;;;;so Kann die HW angeschlossen sein
.equ SRW = 4
.equ Light = 5 ;LCD ;;;;;
.equ SEnable = 6 ;74164 ;;;
;**********LCD-Port parallel für LCD-Simulationssoftware HapSim
.equ port_lcd_x = portd ;auch für parallel notwendig
.equ ddrx_lcd_x = ddrd ;auch für parallel notwendig
.equ st_port_lcd_x = portb
.equ st_ddrx_lcd_x = ddrb
; Pinbelegungen
; STD ;
.equ RS = 0 ;
.equ RW = 1
.equ Light = 2 ;
.equ Enable = 3 ;
;Entry Set
.equ SH = 0 ;1 = Display shift 0 = not shifted
.equ ID = 1 ;1 = increase 0 = decrease
.equ HES = 2 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;DISPLAY on/off
.equ B = 0 ;1 = Blink 0 = no Blink
.equ C = 1 ;1 = Cursor on 0 = Cursor off
.equ D = 2 ;1 = Disp on 0 = Disp off
.equ HD = 3 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;Shift
.equ RL = 2 ;1 = right shift 0 = left shift
.equ SC = 3 ;1 = Disp shift 0 = Cursor move
.equ HS = 4 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;SET Function
.equ F = 2 ;1 = 5x10 0 = 5x7
.equ N = 3 ;1 = 2line(4line) 0 = 1line
.equ DL = 4 ;1 = 8bit int 0 = 4bit interface
.equ HSF = 5 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
*/
;****DS18S20 auf port -->
.equ ddrx_ds = ddrc ;
.equ portx_ds = portc ;hier änder falls anderer Port
.equ pinx_ds = pinc ;
.equ pin_ds_x = 0 ;hier auf welchen Pin
.equ dsIDrng = $0080 ;Speicherbereich für DS-ID's = Y-Pointer wird nur temporär genutzt
.equ dstemp = $0090 ;Speicherbereich für Temp mit Kommastelle = Y-Pointer
;**********SRAM
.equ erg_k = $0060 ;erg_k wird bis zu 4 weiteren bytes genutzt sprich erg_k+4
.equ ocr2s = $0065 ;für T2
.equ ocra1h = $0066 ;;;;;
.equ ocra1l = $0067 ;;;;;;;; für T1 A channel
.equ ocrb1h = $0068 ;;;;;
.equ ocrb1l = $0069 ;;;;;;;; für T1 B channel
.equ icr1xh = $006a ;;;;;
.equ icr1xl = $006b ;;;;;;;; für T1 ICR
.equ hadc = $006c ;adc
.equ ladc = $006d ;adc
.equ eep_adrh = $006e ;eeprom
.equ eep_adrl = $006f ;eeprom
.equ LTC_wertH = $0070
.equ LTC_wertL = $0071
.equ Poti0 = $0072 ;Potentiometer 0
.equ ploudr = $0073 ;poti für lautstärke rechts
.equ ploudl = $0074 ;poti für lautstärke links
.equ phigh = $0075 ;poti für höhen
.equ pbass = $0076 ;poti für bass
.equ halbeh = $0077 ;
.equ halbel = $0078
.equ temp_lsb = $0080 ;
.equ temp_msb = $0081 ;
.equ th_register = $0082 ;
.equ tl_register = $0083 ;
.equ res_byte4 = $0084 ;
.equ res_byte5 = $0085 ;
.equ cnt_remain = $0086 ;
.equ cnt_per_c = $0087 ;
.equ crc = $0088 ;gesperrt ID wird ausgelesen aber nicht gespeichert
.equ dsnmax = $0089
;***************************Einsprungadressen***** ******************
.cseg
.org $0000
rjmp stack
.org $0001 ;1
reti;rjmp INT_0
.org $0002 ;2
reti;rjmp INT_1
.org $0003 ;3
reti;rjmp INT_OC2
.org $0004 ;4
reti;rjmp INT_OVF2
.org $0005 ;5
reti;rjmp INT_ICP1
.org $0006 ;6
reti;rjmp INT_OC1A
.org $0007 ;7
reti;rjmp INT_OC1B
.org $0008 ;8
reti;rjmp INT_OVF1
.org $0009 ;9
reti;rjmp INT_OVF0
reti ;a keine SPI Routinen
.org $000b ;b
reti;rjmp INT_URXC
.org $000c ;c
reti;rjmp INT_UDRE
.org $000d ;d
reti;rjmp INT_UTXC
.org $000e ;e
reti;rjmp adc_rdy
.org $000f ;f
reti;rjmp eeprom_rdy
.org $0010 ;10
reti;rjmp ac_int
reti ;11 keine 2wireRoutinen
reti ;12 keine SPMRoutinen
;***************************Init mit allem drumdran*****************
stack: ldi temp1,high(ramend) ;Stackpointer festlegen
out sph, temp1
ldi temp1,low(ramend) ;Stackpointer festlegen
out spl, temp1
rcall sram
ldi temp0,(1<<pb0|1<<pb1|1<<pb2|1<<pb3)
out portb,temp0
rcall usart_init ;Uart initalisieren
rcall werbe1_rs ;Werbung
; rcall wait1s
;***********************masterprogramm************ *******************
start: sbis pinb,0
rcall pc_ser ;SerienNummer erfassen 1nes Sensor und in EEP speichern und Ausgabe RS232
sbis pinb,2
rcall ds_mess_adr ;Temp von n-Sensoren mit Adresse auslesen und Ausgabe RS232
sbis pinb,3
rcall ds_mess ;Temp 1nes Sensors auslesen und Ausgabe RS232
rjmp start
;*******************Über RS232 Anzeige SerialNummer**************************
pc_ser: rcall wait150ms ;warten
rcall txt_adr_rs ;Txt an RS232
rcall ds18_get_ser ;Adresse + EEP
rcall adr_hex_ASCII_rs ;Ausgabe auf RS232
ret
;******************Messung mehrerer Sensoren über Adresse + Temp auf LCD*****
ds_mess_adr:
rcall wait150ms ;warten
rcall ds18_t_adr ;TempAdress lesen
rcall temp_rs232 ;Ausgabe auf RS232
ret
;******************Messung eines Sensors + Temp auf LCD**********************
ds_mess:rcall wait150ms ;warten
rcall ds18_t_skip_rom ;Temp 1 Sensors
rcall temp_rs232_1 ;Ausgabe auf RS232
ret
;*******************Asugabe auf RS232****************************************
temp_rs232:
clr cnt ;löschen
rcall rd_ds_n ;Anzahl der DS laden
rcall load_dstemp_Y ;Temperaturspeicherbereich laden
temp_rs232_2:
rcall txt_DSn_rs ;Textausgabe
inc cnt ;+1
push cnt ;on stack
mov temp1,cnt ;moven
rcall zahl_out_rs1 ;Ausgabe Zahl
rcall leer_zeichen_rs232 ;leerzeichen
ld temp1,y ;von fester Adr laden
rcall data_transmit ;senden
subi temp1,$20 ;+- Zeichen zerstören sonst wird endlos gespeichert
st y+,temp1 ;zurückspeichern y+1
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_punkt_rs
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_grad_cel_rs
rcall enter_rs232 ;Enter1
pop cnt ;from stack
lds temp1,dsnmax ;Sensoranzahl
cp cnt,temp1 ;vergleich
brne temp_rs232_2 ;!= spring
rcall enter_rs232 ;Enter2
ret
temp_rs232_1:
rcall load_dstemp_Y ;Temperaturbereich laden
rcall txt_DSn_rs ;Textausgabe
ldi temp1,$01 ;
rcall zahl_out_rs1 ;Ausgabe Zahl
rcall leer_zeichen_rs232
ld temp1,y ;von fester Adr laden
rcall data_transmit ;senden
subi temp1,$20 ;+- Zeichen zerstören sonst wird endlos im Ram gespeichert
st y+,temp1 ;zurückspeichern y+1
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_punkt_rs
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_grad_cel_rs
rcall enter_rs232 ;Enter1
ret
;**********************Masterclr****************** *********************
sram: clr temp0
ldi yl,low(SRAM_START)
ldi yh,high(SRAM_START) ;Masterclr des Sram's über
sram2: st y+,temp0 ;die indirekte Adressierung
cpi yl,$a0 ;bis zur zelle x löschen
brne sram2
ret
;*******************Ausgabe RS232************************************
werbe1_rs:
ldi zh,high(out1*2)
ldi zl,low(out1*2)
rcall txt_out_rs
rcall enter_rs232
ret
txt_adr_rs:
ldi zh,high(out2*2)
ldi zl,low(out2*2)
rcall txt_out_rs
ret
txt_DSn_rs:
ldi zh,high(out3*2)
ldi zl,low(out3*2)
rcall txt_out_rs
ret
txt_grad_cel_rs:
ldi zh,high(out4*2)
ldi zl,low(out4*2)
rcall txt_out_rs
ret
txt_punkt_rs:
ldi zh,high(out5*2)
ldi zl,low(out5*2)
rcall txt_out_rs
ret
;****************DatenBank************************ ******************
out1: .db "DS18S20 + RS232",$ff
out2: .db "DS Adr: ",$ff
out3: .db "DS",$ff
out4: .db "°C",$ff
out5: .db ".",$ff
;*************************weitere*includedata***** ******************
.include "ds1820.asm" ;ds1820
;.include "j:\etronik\Software3\sonstiges\origin\lcd_KS0066_K S0070_8bit.asm" ;LCD-Routinen
;.include "l:\etronik\Software3\sonstiges\origin\lcd_KS0066_K S0070_8bit_HapSim.asm"
.include "j:\etronik\Software3\sonstiges\origin\EEprom.asm"
.include "j:\etronik\Software3\sonstiges\origin\uart_std.asm"
.include "j:\etronik\Software3\sonstiges\origin\zeitschleife n.asm"
;*************************ENDE******************** ******************
ds1820
;dssensonsor auf portX pinY
;*************************temp eines sensors auslesen******************
ds18_t_skip_rom:
cli
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves +
rcall convert_t ;start tempmessung
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves+vorbereitung der tempmessung
rcall read_scratchpad ;Sensor auslesen tempim temp_lsb, vorzeichen im temp_msb
rcall ds_reset
rcall Diven_2 ;Div /2 mit Beachtung Vorzeichen
sei
ret
;*******************mehrere sensoren anhand adresse auslesen***********
ds18_t_adr:
cli
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves +
rcall convert_t ;start tempmessung
clr zl ;
clr zh ;pointer clr
sts eep_adrl,zl ;
sts eep_adrh,zh ;
rcall rd_ds_n ;anzahl ds aus eeprom holen = Durchläufe
lds cnt,dsnmax ;cnt = dsnmax
ds18_t_adr2:
rcall adr_ee_sr ;adresse von eeprom in sram laden
rcall ds18_get_t_adr ;sendet adressen um temp zu lesen
rcall Diven_2 ;Div /2 mit Beachtung Vorzeichen
dec cnt ;-1
cpi cnt,$00 ;=?
brne ds18_t_adr2 ;!= zu label springen
sei
ret
ds18_get_t_adr:
rcall ds_reset ;wer ist da???
rcall match_rom ;adresse senden
rcall read_scratchpad ;auslesen
rcall ds_reset ;
ret
;*****************************uniqe-serial*****************************
ds18_get_ser:
rcall ds_reset ;wer ist da???
rcall read_rom ;Befehl senden um adresse lesen
rcall adr_sr_ee ;DS-Adress von SRAM -> EEProm
ret
;*********************adresse in EEprom ablegen************************
adr_sr_ee:
clr zl
clr zh
sts eep_adrl,zl
sts eep_adrh,zh ;immer auf anfang setzen
rcall load_ID_rng_Y ;Speicherbereich laden
adr_sr_ee2:
rcall eeprom_read ;von erster adresse lesen
cpi temp0,$10 ;wenn keine $10
brne adr_sr_ee3 ;dann springe
rcall nxt_adr_eep ;nächste eeprom-ZEILE!!!!!
lds temp0,eep_adrh
cpi temp0,$01 ;= $100 = 256/8byte = N-Sensoren
breq eeprom_voll
rjmp adr_sr_ee2 ;sonst ist ein sensor schon abgespeichert
adr_sr_ee3:
ld temp0,y+ ;von pointer y laden
rcall eeprom_write ;schreibe wert von y in eeprom
rcall adr_cnt ;nächste adresse vorbereiten
cpi yl,dsIDrng+8 ;yl = stopadresse ?
brne adr_sr_ee3 ;wenn != stopadresse zu label
lds temp0,dsnmax ;sonst weiter
inc temp0 ;wieviele sensoren abgespeichert wurden
sts dsnmax,temp0
rcall wr_ds_n ;und anzahl der DS in eeprom speichern
ret
eeprom_voll:
ldi temp1,0b10010100
; rcall out_max_sens ;hier könnte ein Anzeige realisiert werden
rcall nxt_adr_eem ;weil max. Anzahl der sensoren erreicht ist
ret
nxt_adr_eep:
adiw zh:zl,$10 ;EEP ADR plus
sts eep_adrl,zl
sts eep_adrh,zh
ret
nxt_adr_eem:
sbiw zh:zl,$10 ;EEP ADR minus
sts eep_adrl,zl
sts eep_adrh,zh
ret
;*********************************Adresse von ee in sram*****************
adr_ee_sr: ;adresse muss vorher in eep_adrh:l geladen werden in dem programm was dieses aufruft
rcall load_ID_rng_Y ;weil adr_ee_sr wird auch zum auslesen weiter Sensoren genutzt
adr_ee_sr_1:
rcall eeprom_read ;auslesen der adr beginnend mit family code (10h)
st y+,temp0 ;8byte in sram schreiben
rcall adr_cnt ;neu adresse hoch zählen eeprom spalte
cpi yl,dsIDrng+8 ;yl = stoppadresse ??
brne adr_ee_sr_1 ;nein
rcall nxt_adr_eep ;sonst neue adresse laden
ret
;********************Pointer setzen**************************************
load_ID_rng_Y:
ldi yl,low(dsIDrng) ;ID's speichern
ldi yh,high(dsIDrng)
ret
load_dstemp_Y:
ldi yh,high(dstemp) ;Temperaturbereich
ldi yl,low(dstemp)
ret
;*********************Anzahl der DS's von eeprom lesen feste Adresse*****
rd_ds_n:lds temp1,eep_adrl
lds temp2,eep_adrh
push temp1
push temp2
ldi temp0,$0f
sts eep_adrl,temp0
clr temp2
sts eep_adrh,temp2
rcall eeprom_read
sts dsnmax,temp0
pop temp2
pop temp1
sts eep_adrh,temp2
sts eep_adrl,temp1
ret
;********************Anzahl der DS's in eeprom schreiben feste Adresse****
wr_ds_n:lds temp1,eep_adrl
lds temp2,eep_adrh
push temp1
push temp2
ldi temp1,$0f
sts eep_adrl,temp1
clr temp2
sts eep_adrh,temp2
lds temp0,dsnmax
rcall eeprom_write
pop temp2
pop temp1
sts eep_adrh,temp2
sts eep_adrl,temp1
ret
;***ansprechen aller slave's, tempmessung auslösen aller sensoren*******
;***nachfolgend muss keine adr gesendet werden nur 1slave einfache******
;***kommunikation ohne adr zu senden ***********************************
skip_rom:
ldi temp1,$cc
rcall write_command ;read or write
ret
;**************************read rom 64bits=8byte*********************
read_rom:
ldi temp1,$33 ;Befehl
rcall write_command ;senden
rcall lesen ;Adresse lesen 0 -> 7 + 8tes byte = CRC!!!!!!!!!!!!
ret
;**************************Adressierung mit 64bit********************
match_rom:
ldi temp1,$55 ;Befehl
rcall write_command ;senden Achtung Adresse ohne CRC senden also nur 8/9byte senden
rcall schreiben ;8bytes schreiben
ret
;*******************write_scratchpad(schreiben Th und Tl 2byte)******
write_scratchpad:
ldi temp1,$4e ;Befehl
rcall write_command ;senden
rcall load_ID_rng_Y ;lese/schreib Pointer laden
write_scratchpad2:
ld temp1,y+ ;laden
rcall write_command ;Bytes senden
cpi yl,temp_lsb+2 ;Vergleich auf +2
brne write_scratchpad2
ret
;*******************read_scratchpad(auslesen der 9byte)**************
read_scratchpad:
ldi temp1,$be ;Befehl
rcall write_command ;senden
rcall lesen ;9bytes lesen
ret
;***********Convert---T temperaturmessung starten im ds**************
convert_t:
ldi temp1,$44 ;Befehl
rcall write_command ;senden
rcall wait6us
cbi ddrx_ds,pin_ds_x
rcall wait9us
sei ;Global INT-Freigabe
rcall wait750ms ;unterdrückung 85.00 im disp.
convert_t1:
sbis pinx_ds,pin_ds_x
rjmp convert_t1
cli ;Global INT-Sperre
ret
;*********************auslesen******************** *********************
lesen: rcall load_ID_rng_Y ;lese/schreib Pointer laden
lesen_2:rcall read_bit ;Bytes lesen
st y+,temp3 ;speichern
cpi yl,temp_lsb+9 ;Vergleich auf +9
brne lesen_2
ret
;*********************schreiben******************* *******************
schreiben:
rcall load_ID_rng_Y ;lese/schreib Pointer laden
schreiben_2:
ld temp1,y+ ;laden
rcall write_command ;Bytes lesen
cpi yl,temp_lsb+8 ;Vergleich auf +8
brne schreiben_2
ret
;*****************************RESETPULS*********** **********************
ds_reset:
sbi ddrx_ds,pin_ds_x
cbi portx_ds,pin_ds_x ;puls senden
rcall wait500us ;
cbi ddrx_ds,pin_ds_x ;freigabe für DS
rcall wait70us
wait_puls:
sbic pinx_ds,pin_ds_x
rjmp wait_puls ;falls bus high zurück
wait_puls_end: ;auf Antwort warten
sbis pinx_ds,pin_ds_x
rjmp wait_puls_end ;falls bus low zurück
ret
;************************Unterprogramme*********** *******************
;Byte schreiben
write_command:
ldi temp2,$08 ;8Bits
write_command1:
sbrs temp1,0
rcall write_0 ;schreibe 1
sbrc temp1,0
rcall write_1 ;schreibe 0
lsr temp1 ;hier schiebbefehl von ror auf lsr geändert sonst
dec temp2 ;wenn ror muss unter read_bit clc eingefügt werden
brne write_command1 ;hatte auf UniqueSerial keinen einfluss weil kein bit im C
ret ;stand
write_1:cbi portx_ds,pin_ds_x
sbi ddrx_ds,pin_ds_x
rcall wait6us
cbi ddrx_ds,pin_ds_x
rcall wait64us
ret
write_0:cbi portx_ds,pin_ds_x
sbi ddrx_ds,pin_ds_x
rcall wait60us
cbi ddrx_ds,pin_ds_x
rcall wait10us
ret
;Byte lesen
read_bit:
clc ;
clr temp3 ;datenwort in temp3
ldi temp4,$08 ;8bits
read_bit0:
lsr temp3 ;hier ror zu lsr geändertvweil bei temp ein bit zuviel
cbi portx_ds,pin_ds_x ;DS anstupsen um
sbi ddrx_ds,pin_ds_x ;nächstes Bit zu holen
rcall wait6us ;warten
cbi ddrx_ds,pin_ds_x ;Pin für DS freigeben
rcall wait9us ;warten
sbis pinx_ds,pin_ds_x ;abfrage auf
rjmp read_bit1 ;0 lesen
ldi temp2,$80 ;1 lesen
add temp3,temp2
rjmp read_bit2
read_bit1:
ldi temp2,$00
add temp3,temp2
read_bit2:
rcall wait55us
dec temp4
brne read_bit0
ret
;*****Division /2 liest erst MSB für +- dann Berechnen ************
Diven_2:rcall load_dstemp_Y ;startadress für Bereich wo die Temps gespeichert werden
rcall Diven_3
Diven_22:
lds temp0,temp_msb
cpi temp0,$ff ;Vergleich auf Minus
breq diven_minus
diven_plus:
ldi temp0,'+'
st y+,temp0
lds temp0,temp_lsb
lsr temp0
st y+,temp0
rcall diven_komma
st y+,temp0
ret
diven_minus:
ldi temp0,'-'
st y+,temp0
lds temp0,temp_lsb
neg temp0
lsr temp0
st y+,temp0
rcall diven_komma
st y+,temp0
ret
diven_komma:
in temp1,SREG
sbrc temp1,SREG_C
rcall set_half
sbrs temp1,SREG_C
rcall clr_half
ret
set_half:
ldi temp0,$32
ret
clr_half:
clr temp0
ret
Diven_3:ld temp0,y
cpi temp0,'+'
breq Diven_31
cpi temp0,'-'
breq Diven_31
ret
Diven_31:
adiw yh:yl,$03
rjmp Diven_3
;***********************Zeiteschleifen************ *******************
uart_std.asm
;************************Unterprogramme*********** *******************
rx: rcall data_received ;warte auf daten von PC
cpi temp1,' ' ;vergleich auf leerzeichen
brne rx ;sonst wenn falsch warte weiter
ldi temp1,'*' ;
rcall data_transmit ;sende * als ack
ret
tx: rcall wait150ms
ldi temp1,'T'
rcall data_transmit ;sende T
ldi temp1,'S'
rcall data_transmit ;sende S
ldi temp1,'T'
rcall data_transmit ;sende T
ret
;**************Zeichen AUSGABE PC**************************************
txt_out_rs_debug:
rcall debug_pnt ;Pointer für Debug laden wird alles in SRAM ab Adresse $0060 geschrieben
txt_out_rs:
lpm temp1,z+ ;!!! muss in der .db *2 genommen werden
cpi temp1,$ff
breq txt_out_rs_end
;st x+,temp1 ;nur einschalten wenn debug angesprungen wird
rcall data_transmit ;z.b.: ldi ZH,high(out0*2)
rjmp txt_out_rs
txt_out_rs_end:
ret
debug_pnt:
ldi xh,high($0060)
ldi xl,low($0060)
ret
;***********This is an ENTER omg*******************************************
enter_rs232:
ldi temp1,$0d
rcall data_transmit
ldi temp1,$0a
rcall data_transmit
ret
leer_zeichen_rs232:
ldi temp1,' '
rcall data_transmit
ret
;***************************ZahlenAusgabe********* ****************************
temp_rs_load:
ld mathergll,y+ ;alles in die Mathregs laden
clr mathergl
clr mathergh
clr matherghh
rcall hex_dez ;Zahlenwandlung
push yh ;on stack anderer AdressBereich
push yl ;on stack
rcall load_Y_ergk4 ;ERGK + 4 = $0064 wird nur ein byte ausglesen
rcall zahl_out_rs ;Dez in ASCII + Ausgabe
pop yl ;from stack
pop yh ;from stack
ret
zahl_out_rs: ;Ausgabe 2er Zahlen
ld temp1,y
zahl_out_rs1:
mov temp2,temp1
swap temp1
andi temp1,$0f
ori temp1,$30
rcall data_transmit
;Ausgbabe 1er Zahl
mov temp1,temp2
andi temp1,$0f
ori temp1,$30
rcall data_transmit
ret
;**********Speicherpunkte wieviele Stellen ausgegeben werden sollen*********
load_Y_ergk:
ldi yh,high(erg_k)
ldi yl,low(erg_k) ;speicherpunkt laden
ret
load_Y_ergk1:
ldi yh,high(erg_k+1)
ldi yl,low(erg_k+1) ;speicherpunkt laden
ret
load_Y_ergk2:
ldi yh,high(erg_k+2)
ldi yl,low(erg_k+2) ;speicherpunkt laden
ret
load_Y_ergk3:
ldi yh,high(erg_k+3)
ldi yl,low(erg_k+3) ;speicherpunkt laden
ret
load_Y_ergk4:
ldi yh,high(erg_k+4)
ldi yl,low(erg_k+4) ;speicherpunkt laden
ret
;*****************Wandlung von 1A-hex in 1A-ASCII = 31 , 41 Anzeige ist 1 A
adr_hex_ASCII_rs:
rcall load_ID_rng_Y ;Bereich laden der gewandelt und ausgegeben werden soll
pc_ser2:ld temp1,y+ ;erstes byte
mov temp2,temp1 ;byte sichern
swap temp1 ;swapen
andi temp1,$0f ;ausanden
cpi temp1,$0a ;vergleich ob >= 10
brsh pc_ser21 ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
subi temp1,-$30 ;wenn nein mach HexZahl zu ASCII-Zahl
rjmp pc_ser22
pc_ser21:
subi temp1,-$37 ;HexBuchstabe zu ASCII-Buschstabe
pc_ser22:
rcall data_transmit ;und ab damit zum PC
mov temp1,temp2 ;gesichertes byte laden
andi temp1,$0f ;ausanden
cpi temp1,$0a ;vergleich ob >= 10
brsh pc_ser31 ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
subi temp1,-$30 ;wenn nein mach HexZahl zu ASCII-Zahl
rjmp pc_ser32
pc_ser31:
subi temp1,-$37 ;HexBuchstabe zu ASCII-Buschstabe
pc_ser32:
rcall data_transmit ;und ab damit zum PC
rcall leer_zeichen_rs232 ;leerzeichen
cpi yl,dsIDrng+8 ;ENDE ?
brne pc_ser2 ;nein
rcall enter_rs232 ;wenn ja mach noch ein ENTER
ret
hier mal ein wenig Quelltext um einen/mehrere DS18S20 anzusprechen.
AVRStudio 4.19 730
Atmega8
STK500
Inhalt:
1. ds1820_init.asm
2. ds1820.asm
3. uart_std.asm
4. EEprom.asm
5. zeitschleifen.asm
Über pc_ser:
wird die Adresse des DS ausgelesen und im EEprom gespeichert.
Achtung zum auslesen nur immer einen DS am Pin
ds_mess_adr:
hier werden alle Slaves gleichzeitig angesprochen um die Temperaturmessung zu starten und anhand aller Adressen,
die im EEprom stehen, die Temps ausgelesen, umgewandelt, im SRAM 3bytig vorgehalten (Vozeichen,Grad,Halbegrad)
und dann über die Uart verschickt
ds_mess:
ist nur für einen Sensor am Bus vorgesehen über den Befehl SKIP_ROM + Ausgabe über UART
temp_rs232:
Ausgabe an UART wie folgt DS01 +22.50°C usw
Wünsche viel Spaß damit
ds1820_init.asm
;###########################################
;# Projekt: DS18S20 + UART #
;# #
;# #
;# Taktfrequenz des AVR: 4 MHz #
;# #
;# CS-SOFT #
;###########################################
.include "m8def.inc" ;Atmega8
.def math1h = r8
.def math1l = r9
.def math2h = R10
.def math2l = r11
.def matherghh = r12
.def mathergh = r13
.def mathergl = r14
.def mathergll = r15
.def temp0 = r16 ;
.def temp1 = r17 ;
.def temp2 = r18
.def temp3 = r19 ;
.def temp4 = r20
.def cnt = r21
.equ cpu = 4000000
.equ Baud = 9600
.equ UBRRx = cpu/(16*Baud)-1
/*
;**********LCD Port mit 74HC164
.equ port_lcd_x = portd
.equ ddrx_lcd_x = ddrd
; Pinbelegungen
; STD
.equ SClock = 2 ;LCD ;;;
.equ SRS = 2
.equ SData = 4 ;74164 ;;;;;so Kann die HW angeschlossen sein
.equ SRW = 4
.equ Light = 5 ;LCD ;;;;;
.equ SEnable = 6 ;74164 ;;;
;**********LCD-Port parallel für LCD-Simulationssoftware HapSim
.equ port_lcd_x = portd ;auch für parallel notwendig
.equ ddrx_lcd_x = ddrd ;auch für parallel notwendig
.equ st_port_lcd_x = portb
.equ st_ddrx_lcd_x = ddrb
; Pinbelegungen
; STD ;
.equ RS = 0 ;
.equ RW = 1
.equ Light = 2 ;
.equ Enable = 3 ;
;Entry Set
.equ SH = 0 ;1 = Display shift 0 = not shifted
.equ ID = 1 ;1 = increase 0 = decrease
.equ HES = 2 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;DISPLAY on/off
.equ B = 0 ;1 = Blink 0 = no Blink
.equ C = 1 ;1 = Cursor on 0 = Cursor off
.equ D = 2 ;1 = Disp on 0 = Disp off
.equ HD = 3 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;Shift
.equ RL = 2 ;1 = right shift 0 = left shift
.equ SC = 3 ;1 = Disp shift 0 = Cursor move
.equ HS = 4 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;SET Function
.equ F = 2 ;1 = 5x10 0 = 5x7
.equ N = 3 ;1 = 2line(4line) 0 = 1line
.equ DL = 4 ;1 = 8bit int 0 = 4bit interface
.equ HSF = 5 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
*/
;****DS18S20 auf port -->
.equ ddrx_ds = ddrc ;
.equ portx_ds = portc ;hier änder falls anderer Port
.equ pinx_ds = pinc ;
.equ pin_ds_x = 0 ;hier auf welchen Pin
.equ dsIDrng = $0080 ;Speicherbereich für DS-ID's = Y-Pointer wird nur temporär genutzt
.equ dstemp = $0090 ;Speicherbereich für Temp mit Kommastelle = Y-Pointer
;**********SRAM
.equ erg_k = $0060 ;erg_k wird bis zu 4 weiteren bytes genutzt sprich erg_k+4
.equ ocr2s = $0065 ;für T2
.equ ocra1h = $0066 ;;;;;
.equ ocra1l = $0067 ;;;;;;;; für T1 A channel
.equ ocrb1h = $0068 ;;;;;
.equ ocrb1l = $0069 ;;;;;;;; für T1 B channel
.equ icr1xh = $006a ;;;;;
.equ icr1xl = $006b ;;;;;;;; für T1 ICR
.equ hadc = $006c ;adc
.equ ladc = $006d ;adc
.equ eep_adrh = $006e ;eeprom
.equ eep_adrl = $006f ;eeprom
.equ LTC_wertH = $0070
.equ LTC_wertL = $0071
.equ Poti0 = $0072 ;Potentiometer 0
.equ ploudr = $0073 ;poti für lautstärke rechts
.equ ploudl = $0074 ;poti für lautstärke links
.equ phigh = $0075 ;poti für höhen
.equ pbass = $0076 ;poti für bass
.equ halbeh = $0077 ;
.equ halbel = $0078
.equ temp_lsb = $0080 ;
.equ temp_msb = $0081 ;
.equ th_register = $0082 ;
.equ tl_register = $0083 ;
.equ res_byte4 = $0084 ;
.equ res_byte5 = $0085 ;
.equ cnt_remain = $0086 ;
.equ cnt_per_c = $0087 ;
.equ crc = $0088 ;gesperrt ID wird ausgelesen aber nicht gespeichert
.equ dsnmax = $0089
;***************************Einsprungadressen***** ******************
.cseg
.org $0000
rjmp stack
.org $0001 ;1
reti;rjmp INT_0
.org $0002 ;2
reti;rjmp INT_1
.org $0003 ;3
reti;rjmp INT_OC2
.org $0004 ;4
reti;rjmp INT_OVF2
.org $0005 ;5
reti;rjmp INT_ICP1
.org $0006 ;6
reti;rjmp INT_OC1A
.org $0007 ;7
reti;rjmp INT_OC1B
.org $0008 ;8
reti;rjmp INT_OVF1
.org $0009 ;9
reti;rjmp INT_OVF0
reti ;a keine SPI Routinen
.org $000b ;b
reti;rjmp INT_URXC
.org $000c ;c
reti;rjmp INT_UDRE
.org $000d ;d
reti;rjmp INT_UTXC
.org $000e ;e
reti;rjmp adc_rdy
.org $000f ;f
reti;rjmp eeprom_rdy
.org $0010 ;10
reti;rjmp ac_int
reti ;11 keine 2wireRoutinen
reti ;12 keine SPMRoutinen
;***************************Init mit allem drumdran*****************
stack: ldi temp1,high(ramend) ;Stackpointer festlegen
out sph, temp1
ldi temp1,low(ramend) ;Stackpointer festlegen
out spl, temp1
rcall sram
ldi temp0,(1<<pb0|1<<pb1|1<<pb2|1<<pb3)
out portb,temp0
rcall usart_init ;Uart initalisieren
rcall werbe1_rs ;Werbung
; rcall wait1s
;***********************masterprogramm************ *******************
start: sbis pinb,0
rcall pc_ser ;SerienNummer erfassen 1nes Sensor und in EEP speichern und Ausgabe RS232
sbis pinb,2
rcall ds_mess_adr ;Temp von n-Sensoren mit Adresse auslesen und Ausgabe RS232
sbis pinb,3
rcall ds_mess ;Temp 1nes Sensors auslesen und Ausgabe RS232
rjmp start
;*******************Über RS232 Anzeige SerialNummer**************************
pc_ser: rcall wait150ms ;warten
rcall txt_adr_rs ;Txt an RS232
rcall ds18_get_ser ;Adresse + EEP
rcall adr_hex_ASCII_rs ;Ausgabe auf RS232
ret
;******************Messung mehrerer Sensoren über Adresse + Temp auf LCD*****
ds_mess_adr:
rcall wait150ms ;warten
rcall ds18_t_adr ;TempAdress lesen
rcall temp_rs232 ;Ausgabe auf RS232
ret
;******************Messung eines Sensors + Temp auf LCD**********************
ds_mess:rcall wait150ms ;warten
rcall ds18_t_skip_rom ;Temp 1 Sensors
rcall temp_rs232_1 ;Ausgabe auf RS232
ret
;*******************Asugabe auf RS232****************************************
temp_rs232:
clr cnt ;löschen
rcall rd_ds_n ;Anzahl der DS laden
rcall load_dstemp_Y ;Temperaturspeicherbereich laden
temp_rs232_2:
rcall txt_DSn_rs ;Textausgabe
inc cnt ;+1
push cnt ;on stack
mov temp1,cnt ;moven
rcall zahl_out_rs1 ;Ausgabe Zahl
rcall leer_zeichen_rs232 ;leerzeichen
ld temp1,y ;von fester Adr laden
rcall data_transmit ;senden
subi temp1,$20 ;+- Zeichen zerstören sonst wird endlos gespeichert
st y+,temp1 ;zurückspeichern y+1
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_punkt_rs
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_grad_cel_rs
rcall enter_rs232 ;Enter1
pop cnt ;from stack
lds temp1,dsnmax ;Sensoranzahl
cp cnt,temp1 ;vergleich
brne temp_rs232_2 ;!= spring
rcall enter_rs232 ;Enter2
ret
temp_rs232_1:
rcall load_dstemp_Y ;Temperaturbereich laden
rcall txt_DSn_rs ;Textausgabe
ldi temp1,$01 ;
rcall zahl_out_rs1 ;Ausgabe Zahl
rcall leer_zeichen_rs232
ld temp1,y ;von fester Adr laden
rcall data_transmit ;senden
subi temp1,$20 ;+- Zeichen zerstören sonst wird endlos im Ram gespeichert
st y+,temp1 ;zurückspeichern y+1
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_punkt_rs
rcall temp_rs_load ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
rcall txt_grad_cel_rs
rcall enter_rs232 ;Enter1
ret
;**********************Masterclr****************** *********************
sram: clr temp0
ldi yl,low(SRAM_START)
ldi yh,high(SRAM_START) ;Masterclr des Sram's über
sram2: st y+,temp0 ;die indirekte Adressierung
cpi yl,$a0 ;bis zur zelle x löschen
brne sram2
ret
;*******************Ausgabe RS232************************************
werbe1_rs:
ldi zh,high(out1*2)
ldi zl,low(out1*2)
rcall txt_out_rs
rcall enter_rs232
ret
txt_adr_rs:
ldi zh,high(out2*2)
ldi zl,low(out2*2)
rcall txt_out_rs
ret
txt_DSn_rs:
ldi zh,high(out3*2)
ldi zl,low(out3*2)
rcall txt_out_rs
ret
txt_grad_cel_rs:
ldi zh,high(out4*2)
ldi zl,low(out4*2)
rcall txt_out_rs
ret
txt_punkt_rs:
ldi zh,high(out5*2)
ldi zl,low(out5*2)
rcall txt_out_rs
ret
;****************DatenBank************************ ******************
out1: .db "DS18S20 + RS232",$ff
out2: .db "DS Adr: ",$ff
out3: .db "DS",$ff
out4: .db "°C",$ff
out5: .db ".",$ff
;*************************weitere*includedata***** ******************
.include "ds1820.asm" ;ds1820
;.include "j:\etronik\Software3\sonstiges\origin\lcd_KS0066_K S0070_8bit.asm" ;LCD-Routinen
;.include "l:\etronik\Software3\sonstiges\origin\lcd_KS0066_K S0070_8bit_HapSim.asm"
.include "j:\etronik\Software3\sonstiges\origin\EEprom.asm"
.include "j:\etronik\Software3\sonstiges\origin\uart_std.asm"
.include "j:\etronik\Software3\sonstiges\origin\zeitschleife n.asm"
;*************************ENDE******************** ******************
ds1820
;dssensonsor auf portX pinY
;*************************temp eines sensors auslesen******************
ds18_t_skip_rom:
cli
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves +
rcall convert_t ;start tempmessung
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves+vorbereitung der tempmessung
rcall read_scratchpad ;Sensor auslesen tempim temp_lsb, vorzeichen im temp_msb
rcall ds_reset
rcall Diven_2 ;Div /2 mit Beachtung Vorzeichen
sei
ret
;*******************mehrere sensoren anhand adresse auslesen***********
ds18_t_adr:
cli
rcall ds_reset ;wer ist da???
rcall skip_rom ;ansprechen aller slaves +
rcall convert_t ;start tempmessung
clr zl ;
clr zh ;pointer clr
sts eep_adrl,zl ;
sts eep_adrh,zh ;
rcall rd_ds_n ;anzahl ds aus eeprom holen = Durchläufe
lds cnt,dsnmax ;cnt = dsnmax
ds18_t_adr2:
rcall adr_ee_sr ;adresse von eeprom in sram laden
rcall ds18_get_t_adr ;sendet adressen um temp zu lesen
rcall Diven_2 ;Div /2 mit Beachtung Vorzeichen
dec cnt ;-1
cpi cnt,$00 ;=?
brne ds18_t_adr2 ;!= zu label springen
sei
ret
ds18_get_t_adr:
rcall ds_reset ;wer ist da???
rcall match_rom ;adresse senden
rcall read_scratchpad ;auslesen
rcall ds_reset ;
ret
;*****************************uniqe-serial*****************************
ds18_get_ser:
rcall ds_reset ;wer ist da???
rcall read_rom ;Befehl senden um adresse lesen
rcall adr_sr_ee ;DS-Adress von SRAM -> EEProm
ret
;*********************adresse in EEprom ablegen************************
adr_sr_ee:
clr zl
clr zh
sts eep_adrl,zl
sts eep_adrh,zh ;immer auf anfang setzen
rcall load_ID_rng_Y ;Speicherbereich laden
adr_sr_ee2:
rcall eeprom_read ;von erster adresse lesen
cpi temp0,$10 ;wenn keine $10
brne adr_sr_ee3 ;dann springe
rcall nxt_adr_eep ;nächste eeprom-ZEILE!!!!!
lds temp0,eep_adrh
cpi temp0,$01 ;= $100 = 256/8byte = N-Sensoren
breq eeprom_voll
rjmp adr_sr_ee2 ;sonst ist ein sensor schon abgespeichert
adr_sr_ee3:
ld temp0,y+ ;von pointer y laden
rcall eeprom_write ;schreibe wert von y in eeprom
rcall adr_cnt ;nächste adresse vorbereiten
cpi yl,dsIDrng+8 ;yl = stopadresse ?
brne adr_sr_ee3 ;wenn != stopadresse zu label
lds temp0,dsnmax ;sonst weiter
inc temp0 ;wieviele sensoren abgespeichert wurden
sts dsnmax,temp0
rcall wr_ds_n ;und anzahl der DS in eeprom speichern
ret
eeprom_voll:
ldi temp1,0b10010100
; rcall out_max_sens ;hier könnte ein Anzeige realisiert werden
rcall nxt_adr_eem ;weil max. Anzahl der sensoren erreicht ist
ret
nxt_adr_eep:
adiw zh:zl,$10 ;EEP ADR plus
sts eep_adrl,zl
sts eep_adrh,zh
ret
nxt_adr_eem:
sbiw zh:zl,$10 ;EEP ADR minus
sts eep_adrl,zl
sts eep_adrh,zh
ret
;*********************************Adresse von ee in sram*****************
adr_ee_sr: ;adresse muss vorher in eep_adrh:l geladen werden in dem programm was dieses aufruft
rcall load_ID_rng_Y ;weil adr_ee_sr wird auch zum auslesen weiter Sensoren genutzt
adr_ee_sr_1:
rcall eeprom_read ;auslesen der adr beginnend mit family code (10h)
st y+,temp0 ;8byte in sram schreiben
rcall adr_cnt ;neu adresse hoch zählen eeprom spalte
cpi yl,dsIDrng+8 ;yl = stoppadresse ??
brne adr_ee_sr_1 ;nein
rcall nxt_adr_eep ;sonst neue adresse laden
ret
;********************Pointer setzen**************************************
load_ID_rng_Y:
ldi yl,low(dsIDrng) ;ID's speichern
ldi yh,high(dsIDrng)
ret
load_dstemp_Y:
ldi yh,high(dstemp) ;Temperaturbereich
ldi yl,low(dstemp)
ret
;*********************Anzahl der DS's von eeprom lesen feste Adresse*****
rd_ds_n:lds temp1,eep_adrl
lds temp2,eep_adrh
push temp1
push temp2
ldi temp0,$0f
sts eep_adrl,temp0
clr temp2
sts eep_adrh,temp2
rcall eeprom_read
sts dsnmax,temp0
pop temp2
pop temp1
sts eep_adrh,temp2
sts eep_adrl,temp1
ret
;********************Anzahl der DS's in eeprom schreiben feste Adresse****
wr_ds_n:lds temp1,eep_adrl
lds temp2,eep_adrh
push temp1
push temp2
ldi temp1,$0f
sts eep_adrl,temp1
clr temp2
sts eep_adrh,temp2
lds temp0,dsnmax
rcall eeprom_write
pop temp2
pop temp1
sts eep_adrh,temp2
sts eep_adrl,temp1
ret
;***ansprechen aller slave's, tempmessung auslösen aller sensoren*******
;***nachfolgend muss keine adr gesendet werden nur 1slave einfache******
;***kommunikation ohne adr zu senden ***********************************
skip_rom:
ldi temp1,$cc
rcall write_command ;read or write
ret
;**************************read rom 64bits=8byte*********************
read_rom:
ldi temp1,$33 ;Befehl
rcall write_command ;senden
rcall lesen ;Adresse lesen 0 -> 7 + 8tes byte = CRC!!!!!!!!!!!!
ret
;**************************Adressierung mit 64bit********************
match_rom:
ldi temp1,$55 ;Befehl
rcall write_command ;senden Achtung Adresse ohne CRC senden also nur 8/9byte senden
rcall schreiben ;8bytes schreiben
ret
;*******************write_scratchpad(schreiben Th und Tl 2byte)******
write_scratchpad:
ldi temp1,$4e ;Befehl
rcall write_command ;senden
rcall load_ID_rng_Y ;lese/schreib Pointer laden
write_scratchpad2:
ld temp1,y+ ;laden
rcall write_command ;Bytes senden
cpi yl,temp_lsb+2 ;Vergleich auf +2
brne write_scratchpad2
ret
;*******************read_scratchpad(auslesen der 9byte)**************
read_scratchpad:
ldi temp1,$be ;Befehl
rcall write_command ;senden
rcall lesen ;9bytes lesen
ret
;***********Convert---T temperaturmessung starten im ds**************
convert_t:
ldi temp1,$44 ;Befehl
rcall write_command ;senden
rcall wait6us
cbi ddrx_ds,pin_ds_x
rcall wait9us
sei ;Global INT-Freigabe
rcall wait750ms ;unterdrückung 85.00 im disp.
convert_t1:
sbis pinx_ds,pin_ds_x
rjmp convert_t1
cli ;Global INT-Sperre
ret
;*********************auslesen******************** *********************
lesen: rcall load_ID_rng_Y ;lese/schreib Pointer laden
lesen_2:rcall read_bit ;Bytes lesen
st y+,temp3 ;speichern
cpi yl,temp_lsb+9 ;Vergleich auf +9
brne lesen_2
ret
;*********************schreiben******************* *******************
schreiben:
rcall load_ID_rng_Y ;lese/schreib Pointer laden
schreiben_2:
ld temp1,y+ ;laden
rcall write_command ;Bytes lesen
cpi yl,temp_lsb+8 ;Vergleich auf +8
brne schreiben_2
ret
;*****************************RESETPULS*********** **********************
ds_reset:
sbi ddrx_ds,pin_ds_x
cbi portx_ds,pin_ds_x ;puls senden
rcall wait500us ;
cbi ddrx_ds,pin_ds_x ;freigabe für DS
rcall wait70us
wait_puls:
sbic pinx_ds,pin_ds_x
rjmp wait_puls ;falls bus high zurück
wait_puls_end: ;auf Antwort warten
sbis pinx_ds,pin_ds_x
rjmp wait_puls_end ;falls bus low zurück
ret
;************************Unterprogramme*********** *******************
;Byte schreiben
write_command:
ldi temp2,$08 ;8Bits
write_command1:
sbrs temp1,0
rcall write_0 ;schreibe 1
sbrc temp1,0
rcall write_1 ;schreibe 0
lsr temp1 ;hier schiebbefehl von ror auf lsr geändert sonst
dec temp2 ;wenn ror muss unter read_bit clc eingefügt werden
brne write_command1 ;hatte auf UniqueSerial keinen einfluss weil kein bit im C
ret ;stand
write_1:cbi portx_ds,pin_ds_x
sbi ddrx_ds,pin_ds_x
rcall wait6us
cbi ddrx_ds,pin_ds_x
rcall wait64us
ret
write_0:cbi portx_ds,pin_ds_x
sbi ddrx_ds,pin_ds_x
rcall wait60us
cbi ddrx_ds,pin_ds_x
rcall wait10us
ret
;Byte lesen
read_bit:
clc ;
clr temp3 ;datenwort in temp3
ldi temp4,$08 ;8bits
read_bit0:
lsr temp3 ;hier ror zu lsr geändertvweil bei temp ein bit zuviel
cbi portx_ds,pin_ds_x ;DS anstupsen um
sbi ddrx_ds,pin_ds_x ;nächstes Bit zu holen
rcall wait6us ;warten
cbi ddrx_ds,pin_ds_x ;Pin für DS freigeben
rcall wait9us ;warten
sbis pinx_ds,pin_ds_x ;abfrage auf
rjmp read_bit1 ;0 lesen
ldi temp2,$80 ;1 lesen
add temp3,temp2
rjmp read_bit2
read_bit1:
ldi temp2,$00
add temp3,temp2
read_bit2:
rcall wait55us
dec temp4
brne read_bit0
ret
;*****Division /2 liest erst MSB für +- dann Berechnen ************
Diven_2:rcall load_dstemp_Y ;startadress für Bereich wo die Temps gespeichert werden
rcall Diven_3
Diven_22:
lds temp0,temp_msb
cpi temp0,$ff ;Vergleich auf Minus
breq diven_minus
diven_plus:
ldi temp0,'+'
st y+,temp0
lds temp0,temp_lsb
lsr temp0
st y+,temp0
rcall diven_komma
st y+,temp0
ret
diven_minus:
ldi temp0,'-'
st y+,temp0
lds temp0,temp_lsb
neg temp0
lsr temp0
st y+,temp0
rcall diven_komma
st y+,temp0
ret
diven_komma:
in temp1,SREG
sbrc temp1,SREG_C
rcall set_half
sbrs temp1,SREG_C
rcall clr_half
ret
set_half:
ldi temp0,$32
ret
clr_half:
clr temp0
ret
Diven_3:ld temp0,y
cpi temp0,'+'
breq Diven_31
cpi temp0,'-'
breq Diven_31
ret
Diven_31:
adiw yh:yl,$03
rjmp Diven_3
;***********************Zeiteschleifen************ *******************
uart_std.asm
;************************Unterprogramme*********** *******************
rx: rcall data_received ;warte auf daten von PC
cpi temp1,' ' ;vergleich auf leerzeichen
brne rx ;sonst wenn falsch warte weiter
ldi temp1,'*' ;
rcall data_transmit ;sende * als ack
ret
tx: rcall wait150ms
ldi temp1,'T'
rcall data_transmit ;sende T
ldi temp1,'S'
rcall data_transmit ;sende S
ldi temp1,'T'
rcall data_transmit ;sende T
ret
;**************Zeichen AUSGABE PC**************************************
txt_out_rs_debug:
rcall debug_pnt ;Pointer für Debug laden wird alles in SRAM ab Adresse $0060 geschrieben
txt_out_rs:
lpm temp1,z+ ;!!! muss in der .db *2 genommen werden
cpi temp1,$ff
breq txt_out_rs_end
;st x+,temp1 ;nur einschalten wenn debug angesprungen wird
rcall data_transmit ;z.b.: ldi ZH,high(out0*2)
rjmp txt_out_rs
txt_out_rs_end:
ret
debug_pnt:
ldi xh,high($0060)
ldi xl,low($0060)
ret
;***********This is an ENTER omg*******************************************
enter_rs232:
ldi temp1,$0d
rcall data_transmit
ldi temp1,$0a
rcall data_transmit
ret
leer_zeichen_rs232:
ldi temp1,' '
rcall data_transmit
ret
;***************************ZahlenAusgabe********* ****************************
temp_rs_load:
ld mathergll,y+ ;alles in die Mathregs laden
clr mathergl
clr mathergh
clr matherghh
rcall hex_dez ;Zahlenwandlung
push yh ;on stack anderer AdressBereich
push yl ;on stack
rcall load_Y_ergk4 ;ERGK + 4 = $0064 wird nur ein byte ausglesen
rcall zahl_out_rs ;Dez in ASCII + Ausgabe
pop yl ;from stack
pop yh ;from stack
ret
zahl_out_rs: ;Ausgabe 2er Zahlen
ld temp1,y
zahl_out_rs1:
mov temp2,temp1
swap temp1
andi temp1,$0f
ori temp1,$30
rcall data_transmit
;Ausgbabe 1er Zahl
mov temp1,temp2
andi temp1,$0f
ori temp1,$30
rcall data_transmit
ret
;**********Speicherpunkte wieviele Stellen ausgegeben werden sollen*********
load_Y_ergk:
ldi yh,high(erg_k)
ldi yl,low(erg_k) ;speicherpunkt laden
ret
load_Y_ergk1:
ldi yh,high(erg_k+1)
ldi yl,low(erg_k+1) ;speicherpunkt laden
ret
load_Y_ergk2:
ldi yh,high(erg_k+2)
ldi yl,low(erg_k+2) ;speicherpunkt laden
ret
load_Y_ergk3:
ldi yh,high(erg_k+3)
ldi yl,low(erg_k+3) ;speicherpunkt laden
ret
load_Y_ergk4:
ldi yh,high(erg_k+4)
ldi yl,low(erg_k+4) ;speicherpunkt laden
ret
;*****************Wandlung von 1A-hex in 1A-ASCII = 31 , 41 Anzeige ist 1 A
adr_hex_ASCII_rs:
rcall load_ID_rng_Y ;Bereich laden der gewandelt und ausgegeben werden soll
pc_ser2:ld temp1,y+ ;erstes byte
mov temp2,temp1 ;byte sichern
swap temp1 ;swapen
andi temp1,$0f ;ausanden
cpi temp1,$0a ;vergleich ob >= 10
brsh pc_ser21 ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
subi temp1,-$30 ;wenn nein mach HexZahl zu ASCII-Zahl
rjmp pc_ser22
pc_ser21:
subi temp1,-$37 ;HexBuchstabe zu ASCII-Buschstabe
pc_ser22:
rcall data_transmit ;und ab damit zum PC
mov temp1,temp2 ;gesichertes byte laden
andi temp1,$0f ;ausanden
cpi temp1,$0a ;vergleich ob >= 10
brsh pc_ser31 ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
subi temp1,-$30 ;wenn nein mach HexZahl zu ASCII-Zahl
rjmp pc_ser32
pc_ser31:
subi temp1,-$37 ;HexBuchstabe zu ASCII-Buschstabe
pc_ser32:
rcall data_transmit ;und ab damit zum PC
rcall leer_zeichen_rs232 ;leerzeichen
cpi yl,dsIDrng+8 ;ENDE ?
brne pc_ser2 ;nein
rcall enter_rs232 ;wenn ja mach noch ein ENTER
ret