Code:
;************************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
;*********************Textausgabe aus DB***********************************
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(RSdebug)
ldi xl,low(RSdebug)
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*************************
zahl_rs_load_out_xy:
rcall hex_dez ;Zahlenwandlung
push yh ;on stack anderer AdressBereich
push yl ;on stack
rcall load_Y_ergk1 ;Startbyte ; load_Y_ergk(n) (5Byte), n=1(4byte), n=2(3byte), n=3(2byte), n=4(1byte)
ldi temp3,high(erg_k+3)
ldi temp4,low(erg_k+3); Ende
rjmp zahl_rs_load_out2
zahl_rs_load_out:
; 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_ergk2 ;maximale Ausgabe an Zahlen also 5Byte; load_Y_ergk1(4byte),2(3byte),3(2byte),4(1byte)
ldi temp3,high(erg_k+5)
ldi temp4,low(erg_k+5)
zahl_rs_load_out2:
rcall zahl_out_rsx ;Dez in ASCII + Ausgabe
cp yl,temp4 ;
brne zahl_rs_load_out2
pop yl ;from stack
pop yh ;from stack
ret
zahl_out_rsx: ;RSX Ausgabe mit Variabler BYTEZAHL durch load_Y_ergk festgelegt
ld temp1,y+
rjmp zahl_out_rs
zahl_out_rs1: ;rs Ausgabe 2er Zahlen = 1Byte
ld temp1,y ; nur um 1byte auszugeben
zahl_out_rs: ;wird nur rs1 angesprungen müssen die Daten vorher geladen werden
mov temp2,temp1
swap temp1
andi temp1,$0f
ori temp1,$30
rcall data_transmit ;Zehnerausgabe
;Ausgbabe 1er Zahl
mov temp1,temp2
andi temp1,$0f
ori temp1,$30
rcall data_transmit ;Einerausgabe
ret
;*****************Wandlung von 1A-hex in 1A-ASCII = 31 , 41 Anzeige ist 1 A
adr_hex_ASCII_rs: ;Daten vorher in Temp1 laden
pc_ser2: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
rcall enter_rs232 ;wenn ja mach noch ein ENTER
ret
;************************uart_init mit RX interrupt**********************
usart_init:
ldi temp0,high (UBRR0)
ldi temp1,low (UBRR0)
sts UBRR0H,temp0 ;9600 Baud einstellen PDF S.133 table52
sts UBRR0L,temp1
rcall char_size8 ;8 zeichen, 1 stoppbit
lds temp0,UCSR0A
ori temp0,(0<<U2X0|0<<MPCM0) ;no DoubleSpeed, no MultiProzComMode
sts UCSR0A,temp0
ret
char_size5:
ldi temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|0<<UCSZ01|0<<UCSZ00|0<<UCPOL0) ; UCSRC1 or UBRRH0,USBS=0 stoppbits1,
sts UCSR0C,temp0
ldi temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02) ;enable RX u TX <=5bit(UCSZ2=0)
sts UCSR0B,temp0 ;
ret
char_size6:
ldi temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|0<<UCSZ01|1<<UCSZ00|0<<UCPOL0) ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
sts UCSR0C,temp0
ldi temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02) ;enable RX u TX <=6bit(UCSZ2=0)
sts UCSR0B,temp0
ret
char_size7:
ldi temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|0<<UCSZ00|0<<UCPOL0) ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
sts UCSR0C,temp0
ldi temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02) ;enable RX u TX <=7bit(UCSZ2=0)
sts UCSR0B,temp0 ;
ret
char_size8:
ldi temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|1<<UCSZ00|0<<UCPOL0) ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
sts UCSR0C,temp0
ldi temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02) ;enable RX u TX <=7bit(UCSZ2=0)
sts UCSR0B,temp0
ret
char_size9:
ldi temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|1<<UCSZ00|0<<UCPOL0) ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
sts UCSR0C,temp0
ldi temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|1<<UCSZ02) ;enable RX u TX <=9bit(UCSZ2=1)
sts UCSR0B,temp0
ret
;************************uart_deinit********************************
usart_all_aus:
clr temp0
sts UCSR0B,temp0
sts UCSR0C,temp0
sts UBRR0L,temp0
sts UBRR0H,temp0
ret
usart_ofln: ;wenn unterprogramme nicht
clr temp0 ;gestört werden dürfen
sts UCSR0B,temp0 ;nur usart offline
ret
;**********************daten_senden*********************************
INT_USART_RX:
;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
sts UDR0,temp1 ; Put LSB data (r17) into buffer, tranceived data
reti
;(polling)
data_transmit:
lds temp0,UCSR0A
sbrs temp0,UDRE0 ;**
rjmp data_transmit ;**
sts UDR0,temp1 ; Put LSB data (r17) into buffer, tranceived data
ret
;**********************daten_empfangen **********************
INT_USART_TX:
lds temp1,UDR0 ; 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 empfangen die dann an UDR>>>temp1 weitergegeben werden
reti
;(polling)
data_received:
lds temp0,UCSR0A
sbrs temp0,RXC0 ;**
rjmp data_received ;**
lds temp1,UDR0 ; 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
AtMega328_RS_Txt_out.asm
Code:
;**************Zeichen AUSGABE PC**************************************
werbe_rs:
ldi ZH,high(rs_out0*2)
ldi ZL,low(rs_out0*2)
rcall txt_out_rs
;rcall txt_out_rs_debug
rcall enter_rs232
ret
Sonar1_rs:
ldi ZH,high(rs_out1*2)
ldi ZL,low(rs_out1*2)
rcall txt_out_rs
;rcall txt_out_rs_debug
;rcall enter_rs232
ret
millimeter_rs:
ldi ZH,high(rs_out2*2)
ldi ZL,low(rs_out2*2)
rcall txt_out_rs
;rcall txt_out_rs_debug
rcall enter_rs232
rcall enter_rs232
ret
microsekunden_rs:
ldi ZH,high(rs_out3*2)
ldi ZL,low(rs_out3*2)
rcall txt_out_rs
;rcall txt_out_rs_debug
rcall enter_rs232
ret
;************************Zahleausgabe*******************************
HCSR04_micros_out_uart:
rcall Sonar1_rs
lds mathergll,Sonar1l ;alles in die Mathregs laden
lds mathergl,Sonar1h
clr mathergh
clr matherghh
rcall zahl_rs_load_out
rcall microsekunden_rs
ret
HCSR04_mm_out_uart:
rcall Sonar1_rs
rcall zahl_rs_load_out_xy ;variable Ausgabe
rcall millimeter_rs
ret
;************************direktwandlung*wort*in*ASCII***************
rs_out0: .db "Ultraschall hc-sr04 V0.1",$ff
rs_out1: .db "Distanz: ",$ff
rs_out2: .db "mm",$ff
rs_out3: .db "us",$ff
HC_SR04_2.asm
Code:
;********************HC-SR04 Ultraschallsensor*******************
.equ HCSR04_ddr = DDRD
.equ HCSR04_pin = PIND
.equ HCSR04_port= PORTD
.equ Echo = 3
.equ Trigger = 4
.equ CTC_T0 = 7 ; benötigt um 1µs zu erzeugen
.equ T1_max_h = $75 ;high der 30000µs
.equ T1_max_l = $30 ;low der 30000 µs
.equ V_US_20 = 3430 ;dm/s 343 bezogen auf 20°C! Mit Temperatursensor kann hier eingegriffen werden
;************************Init************************************
init_HCSR04:
sbi HCSR04_ddr,Trigger ;Triggerpin als Ausgang setzen
cbi HCSR04_ddr,ECHO
cbi HCSR04_port,ECHO ;Echopin = INT1 als Eingang
rcall INIT_EXT_INT01 ;Int1 = Echo und Aktivierung von T0 auf st. Flanke
rcall mode2_T0_init ;Auflösung 1µs im CTC ohne INT von OCR0A/B, Toggle OCR0B=PD5, Teiler 1 mit CTC_T0
rcall mode0_T1_init ;Teiler auf ext. Eingang PD5, OCR1A = T1_max
ret
;**********************Messung starten***************************
HCSR04_Start:
clr temp1
out TCNT0,temp1
sts TCNT1h,temp1
sts TCNT1l,temp1
rcall HCSR04_Trigger ;Trigger starten
;HCSR04 beginnt nach 450µs mit dem setzen des Echos auf High
;deshalb INT1 auf steigende Flanke
HCSR04_wait:
nop
nop
nop
nop
sbis HCSR04_pin,Echo ;warten bis EchoPin H ist
rjmp HCSR04_wait ;sonst Sprung
HCSR04_wait2:
nop
nop
nop
nop
sbic HCSR04_pin,Echo
rjmp HCSR04_wait2 ;warten bis Echo zurück kommt H-L
rcall prescaler_T0_off ;
rcall prescaler_T1_off ;beide Timer stoppen
lds temp1,TCNT1L
lds temp0,TCNT1H ;Zeit in µs auslesen = doppelter Weg
lsr temp0
ror temp1 ;einmal halbieren
sts sonar1h,temp0
sts sonar1l,temp1 ;Rohzeit in µs speichern = einfacher Weg
ret
HCSR04_Trigger:
sbi HCSR04_port,Trigger
rcall wait10us
rcall wait10us
cbi HCSR04_port,Trigger
ret
;***********************Berechnung der Entfernung anhand ************************
;***********************der Geschwindigkeit und der gem. Zeit ************************
Zeit_zu_Entfernung: ;Geschwindigkeit Schall * Zeit = Entfernung Bsp.: 343m/s * 15001µs = 5145343µm
ldi temp3,high (V_US_20)
ldi temp2,low (V_US_20) ;feste oder errechnete Schgallgeschwindigkeit laden
lds temp1,sonar1h
lds temp0,sonar1l ; Zeit in µs laden
mov math1h,temp3
mov math1l,temp2
mov math2h,temp1
mov math2l,temp0
rcall hmul_2_16bit ; Berechnung durchführen Erg in Mathergll:hh
ret
Lesezeichen