Code:
.include "m328Pdef.inc"
/* Mikrokontroller.net; Persönliche Änderung auf 20MHz */
.equ F_CPU = 20000000 ; Frequenz
.equ BAUD = 9600 ; Baudrate
; Berechnungen
.equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
.equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif
.org 0x0000
jmp RESET ; Reset Handler
reti nop ; IRQ0 Handler
reti nop ; IRQ1 Handler
reti nop; PCINT0 Handler
reti nop; PCINT1 Handler
reti nop ; PCINT2 Handler
reti nop ; Watchdog Timer Handler
reti nop ; Timer2 Compare A Handler
reti nop ; Timer2 Compare B Handler
reti nop ; Timer2 Overflow Handler
jmp TIM1_CAP ; Timer1 Capture Handler
reti nop ; Timer1 Compare A Handler
reti nop ; Timer1 Compare B Handler
reti nop ; Timer1 Overflow Handler
jmp TIM0_COM ; Timer0 Compare A Handler
reti nop ; Timer0 Compare B Handler
reti nop ; Timer0 Overflow Handler
reti nop ; SPI Transfer Complete Handler
reti nop ; USART, RX Complete Handler
reti nop ; USART, UDR Empty Handler
reti nop ; USART, TX Complete Handler
.def temp = r16
.def value = r17
.def status = r18
.def timer0 = r20
.def timer1_low = r21
.def timer1_high = r22
/* BEGINN DES HAUPTPROGRAMMES*/
Reset:
ldi temp, HIGH(RAMEND) ; Stackpointer
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, 0x11110011 ; Die Interrupt sollen als Eingang bleiben
out DDRD, temp
ldi temp, 0xFF ; PORTB wird als Ausgang gesetzt
out DDRB, temp
ldi temp, 0x00
out PORTD, temp ; Alle Pins auf 0 setzen (Die beiden Eingänge bekommen keinen Pull-Up)
rcall UART_Reset
rcall Timer0_Reset
rcall Timer1_Reset
sei
Loop:
;sbic PORTD, 6
;jmp Result_Output
jmp Loop
isUDRclear:
ldi temp, UCSR0A
sbrs temp, 6 ; Überprüfe ob das UDR Register LEER ist
rjmp isUDRclear ; Wenn nicht bleibt in einer Schleife bis es so ist.
sts UDR0, value
ret
Result_Output:
mov value, timer1_low ; Timerwert auf den USART geben
rcall isUDRclear
mov value, timer1_high ; Timerwert auf den USART geben
rcall isUDRclear
rcall sync_0
jmp Loop
/* ISR ROUTINE */
TIM0_COM:
/*Die Pegel auf LOW setzen brauch nicht implementiert werden,
da das von der HArdware gemacht wird*/
inc timer0
cpi timer0, 0x64 ; Damit wird der High Timer auf 10ms festgelegt.
breq Sound_On
cpi timer0, 0x01
breq Sound_Off
reti
TIM1_CAP:
ldi timer1_low, TCNT1L
ldi timer1_high, TCNT1H
reti
Sound_On:
ldi temp, (1<<PD6)
out PORTD, temp
ldi timer0, 0x00 ; setze Timer zurück
reti
Sound_Off:
sbis PORTD, 6
reti
ldi temp, (0<<PD6)
out PORTD, temp
ldi timer0, 0x00
reti
/* RESETS FUNCTION*/
UART_Reset:
ldi temp, HIGH(UBRR_VAL)
sts UBRR0H, temp
ldi temp, LOW(UBRR_VAL)
sts UBRR0L, temp
ldi temp, ( (1<<UMSEL00) | (1<<UCSZ01) | (1<<UCSZ00) ) ; synchron mit 8 Bit.
sts UCSR0C, temp
ldi temp, (1<<TXEN0)
sts UCSR0B, temp
ret
Timer0_Reset:
ldi temp, ( (1<<COM0A1) | (0<<COM0A0) | (0<<WGM02) | (1<<WGM01) | (0<<WGM00) ) ; der Ausgang wird immer beim Oberflow
out TCCR0A, temp ; immer auf LOW gesetzt
ldi temp, 0xFA ; 250 Schritte entsprechen genau 100us FA
out OCR0A, temp
ldi temp, (1<<OCIE0A) ; aktiviere Compare-Overflow Interrupt
sts TIMSK0, temp
ldi temp, (0<<CS02|1<<CS01|0<<CS00) ; setze Vorteiler auf 8
out TCCR0B, temp
ret
Timer1_Reset:
ldi temp, (1<<ICES1)
sts TIMSK1, temp
ret
sync_0:
ldi r25,0x03
sync_1:
ldi r26,0x03
sync_loop:
dec r26
brne sync_loop
dec r25
brne sync_1
ret
Lesezeichen