PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ASM Ds18s20 + uart



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

avr_racer
14.11.2014, 22:30
das muss noch in die uart_std.asm mit eingefügt werden irgendwie reicht Zeichenvorrat nicht :o


;*************************AUSGBAE zahlen********************************
;**********Wandlungsvorbereitung von HEX in DEZ******
hex_dez: push xl
push xh
push zl
push zh
mov zh,matherghh ;highhigh ;wenn ZH=ff>>LCD=42949967295
mov zl,mathergh ;highlow ;wenn ZL=ff>>LCD=16777215 bei ZH=0
mov xh,mathergl ;high ;wenn XH=ff>>LCD=65535 bei ZH:ZL=0
mov xl,mathergll ;low ;wenn xl=ff>>LCD=255 bei XH=0
push yl
push yh
rcall load_Y_ergk ;Speicherbereich laden
ldi cnt,$ff ;
num_1000000000: ;Milliarden
inc cnt
subi xh, byte2(1000000000)
sbci zl, byte3(1000000000)
sbci zh, byte4(1000000000)
brcc num_1000000000
swap cnt
st y,cnt
ldi cnt,$0a
num_100000000: ;100Millionen
dec cnt ;+1
subi xh, byte2(-100000000)
sbci zl, byte3(-100000000)
sbci zh, byte4(-100000000)
brcs num_100000000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichern
ldi cnt,$ff ;
num_10000000: ;10Millionen
inc cnt
subi xl, byte1(10000000)
sbci xh, byte2(10000000)
sbci zl, byte3(10000000)
sbci zh, 0
brcc num_10000000
swap cnt
st y,cnt
ldi cnt,$0a
num_1000000: ;1Million
dec cnt ;+1
subi xl, byte1(-1000000) ;
sbci xh, byte2(-1000000) ;vergleich auf >1000000
sbci zl, byte3(-1000000)
brcs num_1000000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichernn
ldi cnt,$ff ;
num_100000: ;100Tausend
inc cnt
subi xl, byte1(100000)
sbci xh, byte2(100000)
sbci zl, byte3(100000)
brcc num_100000
swap cnt
st y,cnt
ldi cnt,$0a
num_10000: ;10Tausend
dec cnt ;+1
subi xl, byte1(-10000) ;
sbci xh, byte2(-10000) ;vergleich auf >10000
sbci zl, byte3(-10000)
brcs num_10000 ;ja
ld temp0,y
or cnt,temp0
st y+,cnt ;fertig speichern
ldi cnt,$ff
num_1000: ;Tausender
inc cnt
subi xl, low(1000)
sbci xh, high(1000)
brcc num_1000
swap cnt
st y,cnt
ldi cnt,$0a
num_100:dec cnt ;100
subi xl, low(-100)
sbci xh, high(-100)
brcs num_100
ld temp0,y
or cnt,temp0
st y+,cnt
ldi cnt,$ff
num_10: inc cnt ;Zehner + Einer
subi xl, 10
brcc num_10
subi xl, -10
swap cnt
or cnt,xl
st y+,cnt
pop yh
pop yl
pop zh
pop zl
pop xh
pop xl
ret

;************************uart_init mit RX interrupt**********************
usart_init:
ldi temp0,(0<<URSEL)
out UCSRC,temp0
clr temp0
out UBRRH,temp0
ldi temp0,UBRRx ;9600 Baud einstellen PDF S.133 table52
out UBRRL,temp0

rcall char_size8 ;8 zeichen, 1 stoppbit

ldi temp0,(0<<U2X|0<<MPCM) ;no DoubleSpeed, no MultiProzComMode
out UCSRA,temp0

ret

char_size5:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=5bit(UCSZ2=0)
out UCSRB,temp0 ;
ret

char_size6:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=6bit(UCSZ2=0)
out UCSRB,temp0
ret

char_size7:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0 ;
ret

char_size8:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2) ;enable RX u TX <=7bit(UCSZ2=0)
out UCSRB,temp0
ret

char_size9:
ldi temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
out UCSRC,temp0
ldi temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|1<<UCSZ2) ;enable RX u TX <=9bit(UCSZ2=1)
out UCSRB,temp0
ret

;************************uart_deinit************** ******************
usart_all_aus:
clr temp0
out UCSRB,temp0
out UCSRC,temp0
out UBRRL,temp0
out UBRRH,temp0
ret

usart_ofln: ;wenn unterprogramme nicht
clr temp0 ;gestört werden dürfen
out UCSRB,temp0 ;nur usart offline
ret

;**********************daten_senden*************** ******************
INT_UTXC:
;siehe data_transmit;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-lese-schleife implementieren
;um weitere daten zu senden die dann an temp1>>>UDR weitergegeben werden
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
reti
;(polling)
data_transmit:
sbis UCSRA,UDRE ;**
rjmp data_transmit ;**
out UDR,temp1 ; Put LSB data (r17) into buffer, tranceived data
ret

;**********************daten_empfangen **********************
INT_URXC:
in temp1,UDR ; Put data from buffer into r17, received Data
;siehe data_received;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt im INT selbst könnte man ne art daten-schreib-schleife implementieren
;um weitere daten zu senden die dann an UDR>>>temp1 weitergegeben werden
reti
;(polling)
data_received:
sbis UCSRA,RXC ;**
rjmp data_received ;**
in temp1,UDR ; Put data from buffer into r17, received Data
ret

;********************DatenRegisterLeereInterrupt** *********************
INT_UDRE:
;SOLANGE dieses register leer ist wird diese routine aufgerufen
;also eigentlich immer wenn UDR=0
reti


eeprom.asm


;*************************************
eeprom_init:
ldi temp0,(1<<EERIE)
out EECR,temp0
sei
ret

eeprom_rdy:
;siehe eeprom_write ;** man kann in der wartezeit andere sachen erledigen
;bis der int kommt, um dann weitere daten an den eeprom zum schreiben zu senden
;nur bei eeprom schreiben möglich
reti

;Adreessierung im eeprom
adr_cnt:lds temp0,eep_adrl
inc temp0
cpi temp0,$ff
breq adr_cnt2
sts eep_adrl,temp0
ret
adr_cnt2:
clr temp0
sts eep_adrl,temp0
lds temp0,eep_adrh
inc temp0
sts eep_adrh,temp0
cpi temp0,$02
breq error_eeprom
ret
error_eeprom:
;voll
ret

EEPROM_write:
sbic EECR,EEWE ;** falls eewe im eecr noch gesetzt
rjmp EEPROM_write ;** spring zu zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
out EEDR,r16 ;zu speichernder wert
sbi EECR,EEMWE ;sperrt eeprom master write enable
sbi EECR,EEWE ;setze EEWE um eeprom zu schreiben
ret

EEPROM_read:
sbic EECR,EEWE ;falls eewe im eecr noch gesetzt
rjmp EEPROM_read ;springe zurück
lds r18,eep_adrh
out EEARH, r18 ;highbyte der adr
lds r17,eep_adrl
out EEARL, r17 ;lowbyte der adr
sbi EECR,EERE ;sperrt lesen des eeproms
in r16,EEDR ;zu lesender wert
ret


zeitschleifen.asm


;************************zeitschleifen************ ******************************
wait1us:nop
ret

wait6us:push xh
push xl
ldi xh,$00
ldi xl,$02
rjmp z_loop2

wait9us:push xh
push xl
ldi xh,$00
ldi xl,$04
rjmp z_loop2

wait10us:
push xh
push xl
ldi xh,$00
ldi xl,$05
rjmp z_loop2

wait25us:
push xh
push xl
ldi xh,$00
ldi xl,$15
rjmp z_loop2

wait50us:
push xh
push xl
ldi xh,$00
ldi xl,$2e
rjmp z_loop2

wait55us:
push xh
push xl
ldi xh,$00
ldi xl,$33
rjmp z_loop2

wait58us:
push xh
push xl
ldi xh,$00
ldi xl,$36
rjmp z_loop2

wait60us:
push xh
push xl
ldi xh,$00
ldi xl,$37
rjmp z_loop2

wait64us:
push xh
push xl
ldi xh,$00
ldi xl,$3c
rjmp z_loop2

wait70us:
push xh
push xl
ldi xh,$00
ldi xl,$42
rjmp z_loop2

wait100us:
push xh
push xl
ldi xh,$00
ldi xl,$60
rjmp z_loop2

wait500us:
push xh
push xl
ldi xh,$01
ldi xl,$f0
rjmp z_loop2

wait1ms:push xh
push xl
ldi xh,$03
ldi xl,$e4
rjmp z_loop2

wait10ms:push xh
push xl
ldi xh,$27
ldi xl,$0b
rjmp z_loop2

wait150ms:
ldi temp0,$0f
rjmp waitx10ms

wait750ms:
ldi temp0,$4b
rjmp waitx10ms

wait1s: ldi temp0,$64
rjmp waitx10ms



z_loop2:sbiw xh:xl,$01
brne z_loop2
pop xl
pop xh
ret

waitxms:rcall wait1ms
dec temp0
brne waitxms
ret

waitx10ms:
rcall wait10ms
dec temp0
brne waitx10ms
ret