-         

Ergebnis 1 bis 4 von 4

Thema: Kummer mit CTC (mode 4)

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935

    Kummer mit CTC (mode 4)

    Anzeige

    liebe assembler gemeinde,
    seit tagen plage ich mich mit meinem atmega8 (1MHz takt) und folgendem problem herum:
    der CTC Timer soll ein 33kHz rechteck an PB1 erzeugen, gleichzeitig sollen in der hauptschleife im 1s takt PB0, PD7 und PD5, PD6 abwechselnd geschalten werden.
    beides funktioniert für sich genommen ganz prima, aber alles zusammen will partout nicht klappen.

    Code:
    .NOLIST                
    .INCLUDE <m8def.inc>  
    .LIST                    
    .CSEG                    
    
    RESET:
    rjmp init     
    rjmp DUMMY    
    rjmp DUMMY      
    rjmp DUMMY 
    rjmp DUMMY      
    rjmp DUMMY     
    rjmp MYINT 
    rjmp init    
    rjmp MYINT 
    
    .ORG INT_VECTORS_SIZE 
    
    init: 
    ldi R16,HIGH(RAMEND) 
    out SPH,R16 
    ldi R16,LOW(RAMEND) 
    out SPL,R16 
    
    ; CTC klarmachen
    ldi r17,0;
    ldi r16,(1<<WGM12)|(1<<CS10)
    out TCCR1A,r17 
    out TCCR1B,r16
    
      ; port b und d als ausgang
      LDI r24,255       
      OUT DDRB,r24 
      LDI r24,255
      OUT DDRD,r24
    
    ; interrupt
    ldi r16,(1<<OCIE1A)|TIMSK;
    out TIMSK,r16 
    
    ; zaehler laden
    ldi r16,0 
    out OCR1AH,r16 
    ldi r16,255 ;29 (mit 29 sind es ca 33kHz, mit 255 ca 3,8kHz)
    out OCR1AL,r16 
    
    ; PB1 ist anfangs HIGH
    ldi r18,2 
    out portb,r18 
    
    sei  ; Interrupts aktivieren
    
    ; hauptschleife
    loop: 
    ldi r24,32
    out portd,r24
    
    ;  delay loop, 1Hz
              ldi  r17,$09
    WGLOOP0:  ldi  r18,$BC
    WGLOOP1:  ldi  r19,$C4
    WGLOOP2:  dec  r19
              brne WGLOOP2
              dec  r18
              brne WGLOOP1
              dec  r17
              brne WGLOOP0
              nop
    
    ldi r24,192
    out portd,r24; PD5+6 auf HIGH
    
    ;  delay loop, 1Hz
              ldi  r17,$09
    WGLOOP3:  ldi  r18,$BC
    WGLOOP4:  ldi  r19,$C4
    WGLOOP5:  dec  r19
              brne WGLOOP5
              dec  r18
              brne WGLOOP4
              dec  r17
              brne WGLOOP3
              nop
    
    ; immer wiederholen 
    rjmp loop
    
    ; isr, klappt nicht mit meinen pushes..
    MYINT: 
    ;push r16
    ;push r17
    ;push r18
    ;push r19
    ;ldi r20,SREG
    ;push r20
    ;push r23
    ;push r24
    
    ; toggle funktion:
    ; "wenn portb=0 ist, wird portb=2"
    ; "wenn portb=2 ist, wird portb=0"
    
    ldi r20,0
    ldi r21,portb
    cp r21,r20
    breq setport
    out portb,r20
    rjmp intend
    
    setport:
    ldi r21,2 
    ;ldi r22,portb
    ;or r21,r22
    out portb,r21
    
    intend: ; auch diese pops taugen nicht
    ;pop r24
    ;pop r23
    ;pop r20
    ;out SREG,r20
    ;pop r19
    ;pop r18
    ;pop r17
    ;pop r16
    
    reti
    
    DUMMY:
    reti
    vielleicht ist der atmel mit 1MHz auch zu langsam für das, was ich erreichen will? dann würde ich ein 16MHz quarz dranbasteln. aber auch mit erheblich niedrigerer CTC frequenz geht es nicht.

    ausserdem komme ich mit push und pop nicht zurecht. im code sind diese befehle auskommentiert, da ansonsten gar keine 33kHz zustande kommen. aber eigentlich ist es doch ein LIFO, also warum sollte das nicht gehen?

    entschuldigt die vielleicht dummen fragen, ich bin noch kein ASM experte, und habe mich bemüht, es alleine (mit datenblatt und forum-suche) zu schaffen. nur langsam verzweifle ich.

    bin dankbar für jede hilfe!

    eure katze

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569

    Re: Kummer mit CTC (mode 4)

    Oha ...
    1. Die push & pop Dinger müssen sein. Ohne die bringst du dein Programm total durcheinnder.
    2. heisst es: in r20, SREG und nicht ldi r20, SREG
    3. Hast du bei den Werten für das OCR1A Register einen Denkfehler drin. Da du bei einem Überlauf des Timers einen Pin togglest, musst du schon mit der doppelten Frequenz rechnen. daher wären 33 kHz = 14 für das OCR1A Register.
    4. In den verfügbaren 15 Takten kann deine ISR aber niemals abgearbeitet werden.


    Lösungsmöglichkeiten:
    1. den Takt erhöhen. Damit ergibt sich natürlich auch ein anderer Wert für das OCR1A
    2. oder dem µC das togglen komplett überlassen. d.H. COM1A0 im TCCR1A setzen und die ISR komlett wegfallen lassen (siehe Datenblatt Seite 97)


    Im übrigen haste hier schonmal einen sortierten Code für die 2te Version.

    Code:
    	.NOLIST               
    	.INCLUDE <m8def.inc> 
    	.LIST                   
    
    
    	; MCU Takt für diverse Berechnungen festlegen
    	.equ		tosc		= 1000000		 
    
    	; Ausgabefreq festlegen
    	.equ		fout		= 33000
    	
    	; Timer 1 Ladewert
    	.equ		ladewert 	= (tosc / (2 * fout)) - 1
    
    	.CSEG                   
    	.org 0
    
    
    	; Interupt Vektoren
    	rjmp 	init 				; Reset Handler
    	reti 						; IRQ0 Handler
    	reti 						; IRQ1 Handler
    	reti 						; Timer2 Compare Handler
    	reti 						; Timer2 Overflow Handler
    	reti 						; Timer1 Capture Handler
    	reti 						; Timer1 CompareA Handler
    	reti 						; Timer1 CompareB Handler
    	reti 						; Timer1 Overflow Handler
    	reti 						; Timer0 Overflow Handler
    	reti 						; SPI Transfer Complete Handler
    	reti 						; USART RX Complete Handler
    	reti 						; UDR Empty Handler
    	reti 						; USART TX Complete Handler
    	reti 						; ADC Conversion Complete Handler
    	reti 						; EEPROM Ready Handler
    	reti 						; Analog Comparator Handler
    	reti 						; Two-wire Serial Interface Handler
    	reti 						; Store Program Memory Ready Handler
    
    
    
    init:						
    	ldi 	r16,	high(RAMEND); Stackpointer initialisieren
    	out 	SPH,	R16
    	ldi 	r16,	low(RAMEND)
    	out 	SPL,	R16
    
    	ldi 	r24,	255			       
    	out 	DDRB,	r24			; Port B als Ausgang
    	out 	DDRD,	r24			; Port D auch
    	out		PORTC,	r24			; Pullups von Port C aktivieren 
    								; (-> damit hat dieser einen definierten Pegel 
    								; und nicht osziliert sinnfrei rum)
    
    
    
    
    	ldi 	r17,	(1<<COM1A0)	; Timer 1 konfigurieren (Mode 4 -> CTC)
    	ldi 	r16,	(1<<WGM12)|(1<<CS10)
    	out 	TCCR1A,	r17
    	out 	TCCR1B,	r16
    
    	ldi 	r16,	high(ladewert)
    	out 	OCR1AH,r16
    	ldi 	r16,	low(ladewert)
    	out 	OCR1AL,r16
    
    
    ;	in		r16,	TIMSK		; Diese auskommentierten Zeilen sind hier unnötig, 
    ;	ori	 	r16,	(1<<OCIE1A)	; ich habe sie nur drinne gelasen um zu zeigen, 
    ;	out 	TIMSK,	r16			; wie ich es machen würde
    
    	sei  						; Interrupts aktivieren
    
    
    loop:							; hauptschleife
    	ldi 	r24,	32
    	out 	PORTD,	r24
    
    	ldi		r17,	0x09		; delay loop, 1Hz
    WGLOOP0:  
    	ldi		r18,	0xBC
    WGLOOP1:
    	ldi		r19,	0xC4
    WGLOOP2:
    	dec		r19
    	brne	WGLOOP2
    	dec		r18
    	brne	WGLOOP1
    	dec		r17
    	brne	WGLOOP0
    	nop
    
    	ldi		r24,	192
    	out		portd,	r24			; PD5+6 auf HIGH
    
    	ldi		r17,	0x09		; delay loop, 1Hz
    WGLOOP3:
    	ldi		r18,	0xBC
    WGLOOP4:
    	ldi		r19,	0xC4
    WGLOOP5:
    	dec		r19
    	brne WGLOOP5
    	dec		r18
    	brne	WGLOOP4
    	dec		r17
    	brne	WGLOOP3
    	nop
    
    	rjmp 	loop

    Ich hoffe dir damit geholfen zu haben.

    Grüße,
    da Hanni.

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    danke! ja, ich denke das hilft mir um einiges weiter. danke auch für den code, das ist sehr freundlich von dir, dass du dir die mühe gemacht hast
    ich werde das dann gleich einmal testen. ich dachte mir fast, dass der toggle interrupt unnötig ist, aber ich habe es nicht anders hinbekommen.

    nochmal danke und gruesse von der katz

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Gern geschehen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •