Hallo Saturas077,
wie sieht denn jetzt das komplette Programm aus und mit welchem Takt wird der µC betrieben. In den letzten posts sehe ich zB. überhaupt keine Initialisierung der Interrupt Vektoren mehr.
Gruß
Searcher
Hallo Saturas077,
wie sieht denn jetzt das komplette Programm aus und mit welchem Takt wird der µC betrieben. In den letzten posts sehe ich zB. überhaupt keine Initialisierung der Interrupt Vektoren mehr.
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
In diesem Code setze ich die Pins Manuell, aber der Pin PD6 sollte eigentlich automatisch nach jedem Compare Interrupt auf 0 gesetzt werden.
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
Wenn der Code funktioniert, wie Du es möchtest, kann man den Fehler nicht suchen. PD6 sollte nach Deinen Settings und Datenblatt wirklich wieder nach jedem Compareinterrupt auf 0 gesetzt werden. Nur, wie wird er auf 1 gesetzt ohne die Sound_on Sound_off?
Abfrage des Pin Zustandes geschieht normalerweise über das PIND Register außer es absichtlich so gewollt. Wenn über die COMA Bits die OC0A Funktion aktiviert ist, empfiehlt sich das besonders, da der Pin dann nicht mehr auf Zuweisungen über das PORTD Register reagiert. (Aussage etwas wackelig, da ich das jetzt nicht ausprobiert habe und meine, das noch im Gedächtnis zu haben.)Code:Sound_Off: sbis PORTD, 6
Geändert von Searcher (05.05.2014 um 12:19 Uhr) Grund: "sbis PORTD,6" in Frage gestellt
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Es sollte nur Sound_On noch vorhanden sein. Sound_Off sollte dementsprechend von der CTC Routine abgenommen werden und zwar in jedem Compare Interrupt
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Deine Aussage finde ich sehr Interessant, da dass das einzige war, was funktioniert hat.
Also, ohne:
Ist der Pegel immer High auf dem Oszi. (In der Simulation in 6.2 ebenfalls)Code:Sound_Off: sbis PORTD, 6 reti ldi temp, (0<<PD6) out PORTD, temp ldi timer0, 0x00 reti
Erst durch den Absatz wird es ein Toggeln. Es spielt keine Rolle wie ich COMxy einstelle.
Zu deiner exakten Frage wie der pegel High wird. Du hast den Übeltäter selbst gepostet:
Ich hoffe wir finden den Fehler, ansonsten muss ich die CTC Funktion erstmal ohne das zurücksetzen akzeptieren.Code:Sound_On: ldi temp, (1<<PD6) out PORTD, temp ldi timer0, 0x00 ; setze Timer zurück reti
Viele Grüße
Ich blick jetzt nich mehr durch
und muß erstmal in mich gehen
![]()
Bin mir ziemlich sicher, daß wenn OC0A aktiviert ist, der PD6 nicht mehr auf Ausgaben ins PORTD.6 reagiert. Allerdings habe ich keinen Mega328p kann das aber später mal mit Mega88A ausprobieren. *Rätsel*
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Also ich habe es nicht geschafft PD6 über PORTD.6 anzusprechen, wenn OC0A über die COM0Ax Bits aktiviert war.
Überhaupt hat nur das Setzen des COM0A0 Bits zum toggeln bei Comparematch Änderungen an PD6 hervorgerufen; eben ein toggeln. Die anderen Bitkombinationen nach Datenblatt haben OC0A entweder konstant auf low oder high gelegt. Keine Ahnung welchen Sinn die beiden anderen Bitkombinationen im CTC Modus haben.
Wie wird DDRD hiermit überhaupt konfiguriert? Es müßte doch "ldi temp , 0xF3" heißen!
Was ist den die Aufgabe des Timer0? Alle 10ms einen Puls (high oder low, wie lang?) auf PD6 generieren?
Eventuell müßte eine andere Lösung als CTC finden.
Gruß
Searcher
Hoffentlich liegt das Ziel auch am Weg
..................................................................Der Wegzu einigen meiner Konstruktionen
Danke für eure mühen. Ich habe es jetzt erstmal manuel gelöst.
Lesezeichen