Hier ist der Quell-Code für meine Schwierigkeit
;
************************************************************************
*
; Timer 1 Test
; Datum: 30.09.2008
; Letzte Änderung: 21.10.2008
; Hagen Großmann
;
************************************************************************
*
/***********************************************************************
***
Einstellung für AVRstudio
Main: ATmega48
ISP mode
Program:
Fuses: BODLEVEL brown-out detection disable
SUT_CKSEL Ext. Full-swing Crystal; Start-up time PWRDWN/RESET: 16K
CK/14 CK + 4.1 ms
LockBits:no memory lock feattures enable (lockbit 0xff) Mod1
************************************************************************
***/
;***********************************************************************
***
; Anschlußbelegung für ATmega48
;
;
;oder weil USART nicht 8 bit synchron ohne Start und Stopbit übertragen
kann:
;Port B:
; 0 -> DE Daten
; 1 -> /RE Daten/Takt
; 2 -> DE Takt und /SS
; 3 -> MOSI
; 4 -> MISO
; 5 -> CLK
; 6 -> XTAL
; 7 -> XTAL
; Port C:
; 0 -> frei
; 1 -> frei
; 2 -> frei
; 3 -> frei
; 4 -> frei
; 5 -> frei
; 6 -> Reset
;
;
; Port D:
; 0 -> RxD -> Dout
; 1 -> TxD -> Din
; 2 -> /CS -> ext.ADC0 Spannungseingänge 0-7
; 3 -> /CS -> ext.ADC1 Stromeingänge 0-7
; 4 -> CLK
; 5 -> LED onBoard+ext.
; 6 -> frei
; 7 -> frei
;***********************************************************************
*********
;
; Konfigurations- und Sicherheitsbits
; an in Ponyprog(programmiert, bei Atmel -> 0)
WDTON,SUT0,CKSEL2,CKSEL1,CKSEL0
.include "m48def.inc"
.def Empf =r9
.def Send =r10
.def ADC_high =r11
.def ADC_low =r12
.def Lese_Zeiger =r13
.def Zeitgeber1 =r14
.def Kanal_Zeiger =r15
.def Temp1 =r16
.def Temp2 =r17
.def Temp3 =r18
.def Temp4 =r19
.def ZP_b =r20 ;byte-Zähler für RS485-Schnittstelle
.def ZP_p =r21 ;Paketzähler für RS485-Schnittstelle
.def status =r22
.def PIND_filter =r23
.def Z_l =r24
.def Z_h =r25
;**********************************************************************
;Aufteilung vom RAM
.equ lesen=SRAM_START ; Rechner liest vom Modul
.equ schreiben=lesen+32 ; Rechner schreib auf Modul
.equ sendesequenz=schreiben+32 ; 3Byte für Befehlsfolge an ADCs
.equ pininterupt=sendesequenz+3 ;
.equ schleifendurchlauf1=pininterupt+1 ;
;**********************************************************************
;*************** Macro Definition *************************************
.MACRO LED_ON
sbi PORTD, 5
.ENDMACRO
.MACRO LED_OFF
cbi PORTD, 5
.ENDMACRO
.MACRO LED_toggle
in Temp1, PORTD
ldi Temp2, 0x20
eor Temp1, Temp2
out PORTD,Temp1
.ENDMACRO
;************** Macro Definition Ende *********************************
.cseg
;***********************************************************************
****
;Interuptverteiler ab Adresse 0
.org $0000
; AVR mega168 vectors starten bei Addresse 0
; und haben lange absolute Sprünge
rjmp reset ;reset-Sprung
rjmp ext_int0 ;nicht benutzt
rjmp ext_int1 ;nicht benutzt
rjmp PCINT_0 ;nicht benutzt
rjmp PCINT_1 ;nicht benutzt
rjmp PCINT_2 ;nicht benutzt
rjmp WDT ;nicht benutzt
rjmp TIM2_compA ;nicht benutzt
rjmp TIM2_compB ;nicht benutzt
rjmp TIM2_ovf ;nicht benutzt
rjmp TIM1_capt ;Zeitmessung zwischen 2 Flanken an B0
rjmp TIM1_compA ;nicht benutzt
rjmp TIM1_compB ;nicht benutzt
rjmp TIM1_ovf ;innere Uhr (1ms)
rjmp TIM0_compA ;Kontroll-Leuchtdiode
rjmp TIM0_compB
rjmp TIM0_ovf ;Kontroll-Leuchtdiode
rjmp SPI_int ;Übnertragung zum Hauptrechner
rjmp USART_rxc ;UART Empfang fertig (Befehle)
rjmp USART_dre ;nicht benutzt
rjmp USART_txc ;nicht benutzt
rjmp ADC_int
rjmp EE_rdy ;nicht benutzt
rjmp ANA_comp ;nicht benutzt
rjmp TWI
rjmp SPM_rdy
PCINT_1:
push R0
in R0,SREG
push R0
push Temp2
; ldi Temp4,0x05 ; 5-mal blinken
in Temp1,PINC ; welcher Pin ist low
ldi Temp2,0xFF ; Schiebemaske mit Carry
ldi Temp4,0x00 ; SchleifenZähler für Anzahl Blinken
ori Temp1,0xC0 ; Bit 7 & 6 setzen, weil Port C nut 7 Bit breit
und Bit 6 als Ausgang
; out PORTD,Temp1 ; Kontrollausgabe
clc
rcall welcher_pin
rcall s4
pop Temp2
pop R0
out SREG,R0
pop R0
reti
; ******************************************************************
;Timer1 compare
TIM1_compA:
ldi YH,high(sendesequenz+3)
ldi YL,low(sendesequenz+3)
ldi Temp2, 0x03
mov Lese_Zeiger,Temp2
rcall sendeByte
pop Temp1
pop R0
out SREG,R0
pop R0
reti
USART_rxc:
push R0
in R0,SREG
push R0
pop R0
out SREG,R0
pop R0
reti
USART_dre:
push R0
in R0,SREG
push R0
pop R0
out SREG,R0
pop R0
reti
;USART Sende-Interrupt
USART_txc:
push R0
in R0,SREG
push R0
pop R0
out SREG,R0
pop R0
reti
;-----------------------------------------------------------------------
------------------
;*** Ende Interruptprogramme ***
;***********************************************************************
****************
/***********************************************************************
**
initialisieren
************************************************************************
**/
RESET:
ldi Temp1,high(RAMEND) ;Stabel auf Ende (stapelt abwärts)
out SPH,Temp1
ldi Temp1,low(RAMEND)
out SPL,Temp1
rcall PORTB_konfigurieren
rcall PORTC_konfigurieren
rcall PORTD_konfigurieren
; rcall SPI_konfigurieren
rcall USART_als_SPI_konfigurieren
rcall Sendesequenz_Werte
; rcall USART_konfigurieren
; rcall Timer0_konfigurieren
rcall Timer1_konfigurieren
ldi Temp4,3 ; erstmal 3-mal blinken
; ldi Temp4,1 ; erstmal 1-mal blinken
rcall s4
sbi PIND,PIND2 ; Testzwecke ADC0 aktiv
sei
;
************************************************************************
*
; Hauptprogramm
;
************************************************************************
*
Rhein_Schleife:
nop
rjmp Rhein_Schleife
; ***** ENDE Hauptprogramm
*************************************************
/***********************************************************************
****
Controller konfigurieren
************************************************************************
***/
PORTB_konfigurieren:
ldi Temp1,0b00010010 ;B0 ist DE Daten, kommt bei Kommunikation auf 1
;B1 ist /RE Daten/Takt, kommt normalerweise immer auf 0
;B2 ist DE Takt und /SS,
;kommt normalerweise immer auf 0, wenn Modul Slave ist
;B4 ist MISO (Datenausgang Kommunikation);
out DDRB,Temp1 ;Datenrichtungsregister
ldi Temp1,0b00000000 ;
out PORTB,Temp1
ret
PORTC_konfigurieren:
ldi Temp1, 0x40
ldi Temp2, 0x3F
out DDRC,Temp1 ; Input
out PINC, Temp2 ;
ldi Temp1,0x02 ; PinInterupt Port C eingeschaltet
ldi Temp2,0x3F ; PinInteruptMaske Port C eingeschaltet
sts PCICR,Temp1
sts PCMSK1,Temp2
ret
PORTD_konfigurieren:
ldi Temp1,0b11111110
; ldi Temp1,0x00
out DDRD,Temp1
ldi Temp1,0b11101100
out PORTD,Temp1
ret
SPI_konfigurieren:
ret
USART_als_SPI_konfigurieren:
clr Temp1
sts UBRR0H,Temp1
sts UBRR0L,Temp1
sbi PIND, XCK ; Setting the XCKn port pin as output, enables master
mode.
clr Temp1
ldi Temp1,(1<<UMSEL1 | 1<<UMSEL0 | 0<<UCPHA0 | 0<<UCPOL0)
sts UCSR0C,Temp1 ; MSPIM MasterMode, MSP first out, SPI-Mode 0
clr Temp1
ldi Temp1,(1<<RXCIE0 | 1<<TXCIE0 | 0<<UDRIE0 | 1<<RXEN0 | 1<<TXEN0)
;
sts UCSR0B,Temp1 ; RX Interrupt Enable, USART Data Register Empty
Interrupt Enable, Receiver Enable, Transmitter Enable
clr Temp1
ldi Temp2, 0x13 ; Taktteiler für XCK = 20MHz/40
sts UBRR0H,Temp1
sts UBRR0L,Temp2
ret
Sendesequenz_Werte:
ldi Temp4, 0x07 ; Sequenz für ADC
ldi Temp3, 0xC0 ; Platzhalter für XCK
ldi Temp2, 0x00 ; Platzhalter für XCK
sts sendesequenz+2,Temp4
sts sendesequenz+1,Temp3
sts sendesequenz,Temp2
ret
USART_konfigurieren:
clr Temp1
sts UBRR0H,Temp1
sts UBRR0L,Temp1
ldi Temp1,(1<<RXCIE0 | 1<<TXCIE0| 1<<UDRIE0 | 1<<RXEN0 | 1<<TXEN0)
;
sts UCSR0B,Temp1 ; RX Interrupt Enable, USART Data Register Empty
Interrupt Enable, Receiver Enable, Transmitter Enable
clr Temp1
ldi Temp1,(1<<USBS0 | 1<<UCSZ01 | 1<<UCSZ00)
sts UCSR0C,Temp1 ; MSPIM MasterMode, MSP first out,
ldi Temp1,0x02
ldi Temp2, 0x08 ; Taktteiler für BAUD=2400 bei 20 MHz
; clr Temp1
; ldi Temp2, 0xcf ; Taktteiler für BAUD=2400 bei 8 MHz
sts UBRR0H,Temp1
sts UBRR0L,Temp2
ret
Timer0_konfigurieren:
ret
Timer1_konfigurieren:
ldi Temp1, 0x00 ; normale Port-Operation, Kein Ausgang auf
OC1A/OC1B
sts TCCR1A, Temp1 ; Timer/Counter1 Control Register A
ldi Temp1, 0x09 ; Übereinstimmung mit
VergleichsregisterA,Rücksetzen bei Gleichheit,Taktteiler 1
; ldi Temp1, 0x0D ; Übereinstimmung mit
VergleichsregisterA,Rücksetzen bei Gleichheit,Taktteiler 1024
sts TCCR1B, Temp1 ; Timer/Counter1 Control Register B
ldi Temp1, 0x80 ; Match für Channel A & B
sts TCCR1C, Temp1 ; Timer/Counter1 Control Register C
clr Temp1
sts TCNT1H,Temp1 ; Zählregister löschen
sts TCNT1L,Temp1 ; Zählregister löschen
; ldi Temp1, 0x4E ; Vergleichsregister wird mit Vergelichswert
; ldi Temp2, 0x1F ; 0x4E20 gefüllt entspricht 20k Takte = 0.001sec
ldi Temp1, 0x4C ; Testweise 1024*19531=19999744 Takte
ldi Temp2, 0x4B ; Testweise
sts OCR1AH, Temp1
sts OCR1AL, Temp2
clr Temp1
sts ICR1H,Temp1
sts ICR1L,Temp1
ldi Temp1, 0x27 ; Capture Interrupt ist an,Compare B Match
Interrupt an, Compare A Match Interrupt an, Overflow Interrupt an
sts TIMSK1, Temp1
ret
/***********************************************************************
**
Ende Controller konfigurieren
************************************************************************
**/
/***********************************************************************
**
Unterprogramme
************************************************************************
**/
LED_toggle_Schleife:
LED_toggle
clr Zeitgeber1
clr Temp3
ldi Temp3,(1 << OCF1B | 1 << OCF1A)
out TIFR1, Temp3
ret
Werte_holen:
ret
Kanal_abfragen:
ret
sendeByte:
lds Temp1,UCSR0A
sbis 0x10,UDRE0 ; wenn SendeRegister leer, dann kein Rücksprung
; sbis nimmt keinen "Temp1"-Bezeichner an, nur die reale Adresse von
Temp1 -> Bug
rjmp sendeByte ; Rücksprung, wenn SendeRegister voll
ld Temp1, -Y ; Testzwecke
sts UDR0, Temp1 ; Testzwecke
dec Lese_Zeiger
brne sendeByte
LED_toggle
ret
S4: LED_ON
rcall pause
LED_OFF
rcall pause
dec Temp4
brne S4
ret
pause:
ldi Temp3,30
; ldi Temp3,1
S3:
ldi Temp2,255
; ldi Temp2,1
S2:
ldi Temp1,255
; ldi Temp1,1
S1: dec Temp1
brne S1
dec Temp2
brne S2
dec Temp3
brne S3
ret
welcher_pin:
rol Temp2 ; Rollen links mit Carry -> PinMaske bewegen
inc Temp4 ; Schleifendurchlauf = entsprechender Pin
cpse Temp1,Temp2 ; Pins mit Maske vergleichen und bei Gleichheit
Schleife abbrechen
brne welcher_pin ; bei Ungleichheit neuer Schleifendurchlauf
ret