Timer0 im Mode2 (CTC) will in Bascom nicht so wie ich ...

dino03

Aktives Mitglied
27. Okt. 2008
6.760
20
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo,

ich stricke nun schon ne Zeit an diesem Timer0 rum. Er soll im Mode2 (CTC-Mode) alle 20µs einen Interrupt auslösen. Ist ja auch kein Thema (theoretisch) ...
- Prescaler 8
- OCR0 auf 39
- Timer/Counter0 Compare Match Interrupt

Irgendwie macht Bascom aber immer was anderes oder ich finde nicht die richtigen Befehle. Grad keine Lust das komplett in Assembler zu machen :p

Code:
' ===== TIMER 0 =====
'
' ===== Timer Initialisieren ==================================================
Config Timer0 = Timer , Prescale = 8                        ' Timer1 liefert die Basiszeit (20us)
On Oc0 Tim0_isr
'
'===== Timer/Counter Control Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TCCR0
'    FOC0  WGM00 COM01 COM00 WGM01 CS02  CS01  CS00
'      W    R/W   R/W   R/W   R/W   R/W   R/W   R/W
'           ---   ---------   ---   ---------------
'              \        ||   /                 |||
'                \      00 Normal Port Oper.   000 No Clock (Stopped)
'                  \      /                    001 Clk no Prescaling
'                    \  /                      010 Clk/8
'                     ||                       011 Clk/64
'                   0 00 Normal                100 Clk/256
'                   1 01 PWM, Phase Correct    101 Clk/1024
'                   2 10 CTC                   110 Ext T0, Clock on falling edge.
'                   3 11 Fast PWM              111 Ext T0, Clock on rising edge.
'
' In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to
' manipulate the counter resolution. In CTC mode the counter is cleared to zero when
' the counter value (TCNT0) matches the OCR0. The OCR0 defines the top value for the
' counter, hence also its resolution.
' An interrupt can be generated each time the counter value reaches the TOP value by
' using the OCF0 Flag.
'
' Mode2, Prescaler /8, NormalPortOperation
'         FWCC WSSS
Tccr0 = &B0100_0010


'===== Timer/Counter Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- TCNT0
'    -----------TCNT0[7:0]----------
'    R/W R/W R/W R/W R/W R/W R/W R/W


'===== Output Compare Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- OCR0
'    -----------OCR0[7:0]-----------
'    R/W R/W R/W R/W R/W R/W R/W R/W
Ocr0 = 100

'===== Timer/Counter Interrupt Mask Register =====
'Bit --7-- --6-- --5--- --4--- --3--- --2-- --1-- --0-- TIMSK
'    OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
'     R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
'
'OCIEx: Timer/Counter Output Compare Match Interrupt Enable
'TOIEx: Timer/Counter Overflow Interrupt Enable
Enable Compare0


'===== Timer/Counter Interrupt Flag Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TIFR
'    OCF2  TOV2  ICF1  OCF1A OCF1B TOV1  OCF0  TOV0
'     R/W   R/W   R/W   R/W   R/W   R/W   R/W   R/W

' 200Hz PWM * 8Bit = 51,2kHz
' 1 / 51,2kHz = 19,5us
' Compare
' Prescaler   Compare
'      8      39
'     64      4

Enable Timer0                                               ' Timer starten
Enable Interrupts

...
...
...

' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist der Zaehler fuer die Frequenzmessung
Tim0_isr:
  Incr Rampe                                                ' Ueberlauf vom 16Bit-Timer bearbeiten

  ' ### Index ISR ###
  $asm
  sbi portb,0
  sbi portb,1
  $end Asm
  ' #################

  If Pwm_w < 1 Then Goto Dim_aus

  If Pwm_w < Rampe Then Goto Dim_aus

  ' WEISS
  $asm
  sbi portA,3
  sbi portA,4
  Sbi portA,5
  $end Asm
  Goto Dim_ende

Dim_aus:
  ' Nicht WEISS
  $asm
  Cbi portA,3
  Cbi portA,4
  Cbi portA,5
  $end Asm

Dim_ende:

  ' ### Ende ISR ###
  $asm
  Cbi portb,0
  Cbi portb,1
  $end Asm
  ' #################

Return

Ich hab einige Ausgangspins als Indikatoren für interne Laufzeiten verwendet und mit dem LA8 nachgemessen. Irgendwie stellt Bascom immer die selbe Laufzeit ein. Egal ob ich nun das OCR0 ändere oder den Prescaler.

Hat schonmal einer mit dem Timer0 nen CTC-Mode gemacht? In den Büchern von Kühnel, Hoffmann, Walter hab ich auch nichts brauchbares gefunden. Hier im Forum bis jetzt auch noch nicht. Weiter hab ich noch nicht gesucht.

Ich werd jetzt erstmal Schluß machen und was abbeißen ... evtl sieht es morgen schon anders aus ;)

Gruß
Dino
 
Hallo Dino,
für CTC musst du noch clear_timer angeben:
Config Timer0 = Ctc , Clear_timer = 1 , Prescale = 8 'du kannst hier =CTC schreiben, musst du aber nicht.
 
Hi Rolf,

besten Dank :D Irgendwie ist Bascom an der Stelle selbst mit der Befehlsreferenz nicht grade aussagekräftig.

Ich hab es jetzt mal angepaßt ...

Der ganze Rotz bereinigt aus dem Editor wie beim letzten Test ...
Code:
' #############################################################################
' ##### Magierstab v2 mit Mega32 ##############################################
' #############################################################################
' (c) 27.06.2010 by Dino
' BASCOM 2.0.7.5
'
'

' Prozessor ATmega32
$regfile = "m32def.dat"
' 16MHz Quarztakt (Baudraten-Quarz)
$crystal = 16000000

$hwstack = 32
$swstack = 32
$framesize = 32

' ATMEL AVR ATmega32
' 32kByte Flash (16kx16)
' 1kByte EEPROM
' 32 Register + 2kByte RAM
'
'                                            ATmega32
'                                 +-------------------------------+
'               PWM rt1 ----------| 1 PB0(XCK/T0)     (ADC0)PA0 40|---------- PWM bl1
'               PWM rt2 ----------| 2 PB1(T1)         (ADC1)PA1 39|---------- PWM bl2
'               PWM gn1 ----------| 3 PB2(INT2/AIN0)  (ADC2)PA2 38|---------- PWM bl3
'               PWM gn2 ----------| 4 PB3(OC0/AIN1)   (ADC3)PA3 37|---------- PWM ws1
'                Enable ----------| 5 PB4(SS)         (ADC4)PA4 36|---------- PWM ws2
'        Taster1 --- (ISP) MOSI --| 6 PB5(MOSI)       (ADC5)PA5 35|---------- PWM ws3
'        Taster2 --- (ISP) MISO --| 7 PB6(MISO)       (ADC6)PA6 34|
'        Taster3 ---- (ISP) SCK --| 8 PB7(SCK)        (ADC7)PA7 33|---------- Akkuspannung
'   Reset-Taster -- (ISP) RESET --| 9 RESET                AREF 32|--(*)
'                          +Vcc --|10 VCC                   GND 31|-- GND
'                           GND --|11 GND                  AVCC 30|-- +Vcc (gesiebt)
'                          XTAL --|12 XTAL2          (TOSC2)PC7 29|
'                          XTAL --|13 XTAL1          (TOSC1)PC6 28|
'              MAX232 ||----------|14 PD0(RXD)         (TDI)PC5 27|
'              Debug  ||----------|15 PD1(TXD)         (TDO)PC4 26|
'           INT0-Taster ----------|16 PD2(INT0)        (TMS)PC3 25|
'           INT1-Taster ----------|17 PD3(INT1)        (TCK)PC2 24|
'                                 |18 PD4(OC1B)        (SDA)PC1 23|----------|| 2x LM75 (Akku + Treiber/LEDs)
'                                 |19 PD5(OC1A)        (SCL)PC0 22|----------|| PCF8574 für LCD Servicedisplay
'                                 |20 PD6(ICP1)        (OC2)PD7 21|
'                                 +-------------------------------+
'        (*) 100nF nach GND


' ----- FUSES -----
'
' * SUT1 und SUT0 (Zustand=11): Start-up Time 65ms nach Reset,
'   Einstellung für Quarzoszillator und langsam ansteigende
'   Betriebsspannung (Tabelle 5 des Datenblattes)
' * CKSEL3-CKSEL0 (Zustand=1111): Quarzoszillator im Bereich 3-8MHz
'   (Tabelle 4 des Datenblattes)
' * CKOPT (Zustand=1): schneller Quarzoszillator (Tabelle 4 des Datenblattes)
' * BODEN (Zustand=0): Brown-out einschalten
' * BODLEVEL (Zustand=1): Brown-out Schwelle auf 2,7V setzen
'
'  Unter Beachtung der invertierten Logik der Fuse-Bits sollte man
'  also die Fuses so setzen wie im folgenden Bild:
'
' ( )7 ( )6 [ ]BootLock12 [ ]BootLock11 [ ]BootLock02 [ ]BootLock01 [ ]Lock2 [ ]Lock1
'
' [ ]OCDEN [ ]JTAGEN (X)SPIEN [ ]CKOPT  [ ]EESAVE [X]BOOTSZ1 [X]BOOTSZ0 [ ]BOOTRST
'
' [ ]BODLEVEL [X]BODEN [ ]SUT1 [ ]SUT0 [ ]CKSEL3 [ ]CKSEL2 [ ]CKSEL1 [ ]CKSEL0
'  ______________________
' |                      |
' | [X] Bit=0  [ ] Bit=1 | ( ) -> Nicht anwaehlbar  [ ] -> Anwaehlbar
' | progr.     unprogr.  |
' |______________________|





' #############################################################################
' ##### DEFINITION DER VARIABLEN ##############################################
' #############################################################################
'
Dim R As Byte
R = 0
Dim G As Byte
G = 0
Dim B As Byte
B = 0
Dim W As Byte
W = 0


Dim Rampe As Byte
Rampe = 0

Dim Pwm_r As Byte
Pwm_r = 0
Dim Pwm_g As Byte
Pwm_g = 0
Dim Pwm_b As Byte
Pwm_b = 0
Dim Pwm_w As Byte
Pwm_w = 0


' #############################################################################
' ##### DEFINITION DER PORTS ##################################################
' #############################################################################
'
' =============================================================================
' ===== PortA (digital) =======================================================
' =============================================================================
' PA0 ---->-- blau1
' PA1 ---->-- blau2
' PA2 ---->-- blau3
' PA3 ---->-- weiss1
' PA4 ---->-- weiss2
' PA5 ---->-- weiss3
' PA6 ---->--
' PA7 ---->-- VBat-ADC
'
' A=7= I=6= I=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' VBat ---- ws3  ws2  ws1  bl3  bl2  bl1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddra = &B0011_1111
Porta = &B0000_0000



' =============================================================================
' ===== PortB =================================================================
' =============================================================================
' PB0 ---->-- rot1
' PB1 ---->-- rot2
' PB2 ---->-- gruen1
' PB3 ---->-- gruen2
' PB4 ---->-- PWM-Enable
' PB5 ---->-- Taster1 (MOSI)
' PB6 ---->-- Taster2 (MISO)
' PB7 ---->-- Taster3 (SCK)
'
' I=7= I=6= I=5= O=4= O=3= O=2= O=1= O=0=  => 11110111 => DDRB
' SCK  MISO MOSI PWME gn2  gn1  rt2  rt1   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrb = &B0001_1111
Portb = &B1110_0000



' =============================================================================
' ===== PortC (digital) =======================================================
' =============================================================================
' PC0 ---->-- SCL
' PC1 --<->-- SDA
' PC2 ---->--
' PC3 ---->--
' PC4 ---->--
' PC5 ---->--
' PC6 ---->--
' PC7 ---->--
'
' I=7= I=6= I=5= I=4= I=3= I=2= I=1= I=0=  => 11110111 => DDRB
' ---- ---- ---- ---- ---- ---- SDA  SCL   => 00001000 => PORTB (init)
'   |    |    |    |    |    |    |    |
'
Ddrc = &B0000_0000
Portc = &B1111_1111



' =============================================================================
' ===== PortD =================================================================
' =============================================================================
' PD0 --<---- RxD | UART1
' PD1 ---->-- TxD | TTL-Pegel
' PD2 --<---- INT0
' PD3 --<---- INT1
' PD4 --<----
' PD5 --<----
' PD6 --<----
' PD7 --<----
'
' I=7= I=6= I=5= I=4= O=3= I=2= O=1= I=0=  => 00001001 => DDRD
'  T4   T3   T2   T1  TxD1 RxD1 TxD  RxD   => 11110110 => PORTD (init)
'   |    |    |    |    |    |    |    |
'
Ddrd = &B0000_0010
Portd = &B1111_1111




' ===== TIMER 0 =====
'
' ===== Timer Initialisieren ==================================================
Config Timer0 = Ctc , Prescale = 8 , Clear Timer = 1        ' Timer1 liefert die Basiszeit (20us)
On Oc0 Tim0_isr
'
'===== Timer/Counter Control Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TCCR0
'    FOC0  WGM00 COM01 COM00 WGM01 CS02  CS01  CS00
'      W    R/W   R/W   R/W   R/W   R/W   R/W   R/W
'           ---   ---------   ---   ---------------
'              \        ||   /                 |||
'                \      00 Normal Port Oper.   000 No Clock (Stopped)
'                  \      /                    001 Clk no Prescaling
'                    \  /                      010 Clk/8
'                     ||                       011 Clk/64
'                   0 00 Normal                100 Clk/256
'                   1 01 PWM, Phase Correct    101 Clk/1024
'                   2 10 CTC                   110 Ext T0, Clock on falling edge.
'                   3 11 Fast PWM              111 Ext T0, Clock on rising edge.
'
' In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to
' manipulate the counter resolution. In CTC mode the counter is cleared to zero when
' the counter value (TCNT0) matches the OCR0. The OCR0 defines the top value for the
' counter, hence also its resolution.
' An interrupt can be generated each time the counter value reaches the TOP value by
' using the OCF0 Flag.
'
' Mode2, Prescaler /8, NormalPortOperation
'         FWCC WSSS
Tccr0 = &B0100_0010


'===== Timer/Counter Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- TCNT0
'    -----------TCNT0[7:0]----------
'    R/W R/W R/W R/W R/W R/W R/W R/W


'===== Output Compare Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- OCR0
'    -----------OCR0[7:0]-----------
'    R/W R/W R/W R/W R/W R/W R/W R/W
Ocr0 = 39

'===== Timer/Counter Interrupt Mask Register =====
'Bit --7-- --6-- --5--- --4--- --3--- --2-- --1-- --0-- TIMSK
'    OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
'     R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
'
'OCIEx: Timer/Counter Output Compare Match Interrupt Enable
'TOIEx: Timer/Counter Overflow Interrupt Enable
Enable Compare0


'===== Timer/Counter Interrupt Flag Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TIFR
'    OCF2  TOV2  ICF1  OCF1A OCF1B TOV1  OCF0  TOV0
'     R/W   R/W   R/W   R/W   R/W   R/W   R/W   R/W

' 200Hz PWM * 8Bit = 51,2kHz
' 1 / 51,2kHz = 19,5us
' Compare
' Prescaler   Compare
'      8      39
'     64      4

Enable Timer0                                               ' Timer starten
Enable Interrupts


Dim Loopcount As Word
Loopcount = 0

' #############################################################################
' ##### Hauptschleife Start ###################################################
' #############################################################################
Do



If Loopcount > 3000 Then
  ' ### Index Dimm ###      Anschalten fuer LA8
  $asm
  sbi portb,2
  sbi portb,3
  $end Asm
  ' #################

  If Pinc.7 = 0 Then                                        ' Taste gedrueckt
    If Pwm_w < 255 Then                                     ' wenn Ende nicht erreich dann hochdimmen
      Incr Pwm_w
    End If
  Else                                                      ' Taste nicht gedrueckt
    If Pwm_w > 0 Then                                       ' wenn Null nicht erreich dann runterdimmen
      Decr Pwm_w
    End If
  End If

  Loopcount = 0
  ' ### Ende Dimm ###      Ausschalten fuer LA8
  $asm
  Cbi portb,2
  Cbi portb,3
  $end Asm
  ' #################
End If


Incr Loopcount

Loop
' #############################################################################
' ##### Hauptschleife Ende ####################################################
' #############################################################################







' ================================================
' ===== ISR fuer Timer0 Overflow =================
' ================================================
' Timer0 ist der Impulsgeber fuer den PWM-Rampenzaehler
Tim0_isr:
  ' ### Index ISR ###    Anschalten fuer LA8
  $asm
  sbi portb,0
  sbi portb,1
  $end Asm
  ' #################

  Incr Rampe                                                ' Ueberlauf vom 8Bit-Timer bearbeiten

  If Pwm_w < 1 Then Goto Dim_aus                            ' Bei PWM=0 Ausgang abschalten

  If Pwm_w < Rampe Then Goto Dim_aus                        ' Bei PWM kleiner Rampe also Ausgang abschalten

  ' PWM-Wert ist gleich oder groesser Rampe also Ausgang anschalten
  ' WEISS
  $asm
  sbi portA,3
  sbi portA,4
  Sbi portA,5
  $end Asm
  Goto Dim_ende                                             ' zum Ende um den Ausgang anzulassen

Dim_aus:                                                    ' Ab hier den Ausgang abschalten
  ' Nicht WEISS
  $asm
  Cbi portA,3
  Cbi portA,4
  Cbi portA,5
  $end Asm

Dim_ende:

  ' ### Ende ISR ###     Ausschalten fuer LA8
  $asm
  Cbi portb,0
  Cbi portb,1
  $end Asm
  ' #################
Return


' #############################################################################

End

Leider ist trotz fest eingegebener Werte im OCR0-Register der Ablauf der ISR-Routine immer noch viel zu langsam und vor allem unregelmäßig :(

Dimmen tut er ja ...
SoftPWM_01.png
man sieht in der vierten Zeile den Ausgang hoch und wieder runterdimmen. Es ist nur sehr flackerig wegen dem Timer0

Die ISR wird sehr unregelmäßig aufgerufen. Am Anfang der ISR wird "rot" auf Vcc geschaltet und am Ende der ISR wieder auf GND
SoftPWM_02_ISR.png
der kleine Abstand liegt bei 37µs. Die ISR dauert 2,5µs (in ASM optimierungsfähig). Nur den langen Abstand kann ich mir nicht erklären. 216µs bis zum nächsten Interrupt :confused:

Dadurch geht die PWM-Frequenz auf 30Hz runter und die LED flackert auch noch irgendwie.
SoftPWM_03_PWM-freq.png
Alles sehr komisch.

Na mal sehen ... morgen ist auch noch ein Tag und notfalls mach ich es doch alles in Assembler :p

EDIT: Ich hab jetzt sogar mit Unterstrich (Clear_Timer=1) geschrieben. Nutzt auch nix. Er kümmert sich nicht um meine Änderungen.

Gruß
Dino
 
Nochmal der letzte Stand von heute ...

Ich hab jetzt die Register selber beschrieben und Bascom außen vor gelassen. Es geht trotzdem nicht. Wurschtelt Bascom evtl irgendwie im Timer0 rum ?
Code:
' ===== TIMER 0 =====
'
' ===== Timer Initialisieren ==================================================
'Config Timer0 = Ctc , Prescale = 8 , Clear_timer = 1        ' Timer1 liefert die Basiszeit (20us)
[B]On Oc0 Tim0_isr[/B]
'
'===== Timer/Counter Control Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TCCR0
'    FOC0  WGM00 COM01 COM00 WGM01 CS02  CS01  CS00
'      W    R/W   R/W   R/W   R/W   R/W   R/W   R/W
'           ---   ---------   ---   ---------------
'              \        ||   /                 |||
'                \      [B]00 Normal Port Oper.[/B]   000 No Clock (Stopped)
'                  \      /                    001 Clk no Prescaling
'                    \  /                      [B]010 Clk/8[/B]
'                     ||                       011 Clk/64
'                   0 00 Normal                100 Clk/256
'                   1 01 PWM, Phase Correct    101 Clk/1024
'                   [B]2 10 CTC[/B]                   110 Ext T0, Clock on falling edge.
'                   3 11 Fast PWM              111 Ext T0, Clock on rising edge.
'
' In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to
' manipulate the counter resolution. In CTC mode the counter is cleared to zero when
' the counter value (TCNT0) matches the OCR0. The OCR0 defines the top value for the
' counter, hence also its resolution.
' An interrupt can be generated each time the counter value reaches the TOP value by
' using the OCF0 Flag.
'
' Mode2, Prescaler /8, NormalPortOperation
'         FWCC WSSS
[B]Tccr0 = &B0100_0010[/B]


'===== Timer/Counter Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- TCNT0
'    -----------TCNT0[7:0]----------
'    R/W R/W R/W R/W R/W R/W R/W R/W


'===== Output Compare Register =====
'Bit -7- -6- -5- -4- -3- -2- -1- -0- OCR0
'    -----------OCR0[7:0]-----------
'    R/W R/W R/W R/W R/W R/W R/W R/W
[B]Ocr0 = 39[/B]

'===== Timer/Counter Interrupt Mask Register =====
'Bit --7-- --6-- --5--- --4--- --3--- --2-- --1-- --0-- TIMSK
'    OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
'     R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
'
'OCIEx: Timer/Counter Output Compare Match Interrupt Enable
'TOIEx: Timer/Counter Overflow Interrupt Enable
'Enable Compare0
[B]Timsk = &B0000_0010[/B]

'===== Timer/Counter Interrupt Flag Register =====
'Bit --7-- --6-- --5-- --4-- --3-- --2-- --1-- --0-- TIFR
'    OCF2  TOV2  ICF1  OCF1A OCF1B TOV1  OCF0  TOV0
'     R/W   R/W   R/W   R/W   R/W   R/W   R/W   R/W

' 200Hz PWM * 8Bit = 51,2kHz
' 1 / 51,2kHz = 19,5us
' Compare
' Prescaler   Compare
'      8      39
'     64      4

' Enable Timer0                                               ' Timer starten
[B]Enable Interrupts[/B]

Für heute reichts mir jetzt ...

Noch ne letzte Info: Wenn ich den Prescaler auf 011 stelle (/64) dann passiert auch was. Also so ganz falsch kann ich nicht liegen. Irgendwie paßt es aber trotzdem nicht. Ich hab jetzt auch gesehen das die Dauer des Dimm-Bereichs sich von 1,5µs auf 10,5µs verlängert wenn genau dort der Interrupt zuschlägt.

Gruß
Dino
 
Du hast WGM=01 (phasenkorrekten PWM bis 0xFF) statt WGM=10 (CTC bis OCR0)...

Edit: was Bascom da vorher und/oder danach sonst noch so treibt, kann ich auf dem Tablet jetz nicht nachvollziehen/simulieren/reassemblieren, aber mit "TCCR0=0b01000010" legst DU den WGM auf 01 (um)...
 
Hi,

Du hast WGM=01 (phasenkorrekten PWM bis 0xFF) statt WGM=10 (CTC bis OCR0)...
Sch...e :p stimmt. Welcher Idiot bei Atmel hat das höherwertige Bit nach rechts gepackt? (auch wenn noch zwei andere dazwischen sind). Man sollte das Datenblatt doch etwas genauer lesen :rolleyes:

Danke :cool: das wars ... ich hab jetzt mit meiner eigenen Registereinstellung ein sauberes Dimming der LEDs :D

Gruß
Dino
 
... ich hab jetzt mit meiner eigenen Registereinstellung ein sauberes Dimming der LEDs :D
Hast du doch mit Bascom auch, wenn du deine direkte Registereinstellung weglässt.
Die ISR wird mit 50KHz aufgerufen und erzeugt eine 195Hz PWM.
Ich sehe da kein Problem.
 
Hallo,

Hast du doch mit Bascom auch, wenn du deine direkte Registereinstellung weglässt.
Die ISR wird mit 50KHz aufgerufen und erzeugt eine 195Hz PWM.
Ich sehe da kein Problem.
also ich habe nochmal einiges getestet. Es geht nicht. Mit Bascom kann ich irgendwie beim Timer0 keinen Compare-Interrupt auslösen. Im Buch von Klaus Kühnel habe ich dazu auch eine Textstelle gefunden (Seite 155):
Da beim Timer0 nur der Overflow Interrupt zur Verfügung steht, muss Timer0 mit einem Wert von 256-195 geladen werden, um nach 195 Takten einen Overflow Interrupt zu erzeugen.
Laut dem Datenblatt des Mega32 hat er aber auch einen Compare-Match Interrupt ...
Interrupt-Vekoren
11 - $014 - TIMER0 COMP - Timer/Counter0 Compare Match
12 - $016 - TIMER0 - OVF - Timer/Counter0 Overflow
und ...
The Output Compare Register contains an 8-bit value that is continuously compared with the
counter value (TCNT0). A match can be used to generate an output compare interrupt, or to
generate a waveform output on the OC0 pin.
und auch Seite 73 : CTC-Mode
In Clear Timer on Compare or CTC mode (WGM01:0 = 2), the OCR0 Register is used to manip-ulate the counter resolution. In CTC mode the counter is cleared to zero when the counter value
(TCNT0) matches the OCR0.
The OCR0 defines the top value for the counter, hence also its
resolution. This mode allows greater control of the compare match output frequency. It also sim-plifies the operation of counting external events
Man muß also auch beim Timer0 nicht dauernd in der ISR den Timerwert neu schreiben und mit dem Ovf-Int arbeiten sondern man kann statt dessen auch mit dem CompareMatch arbeiten und läßt alles von der Hardware erledigen.

In Bascom ...
Syntax
CONFIG TIMER0 = COUNTER , EDGE=RISING/FALLING , CLEAR TIMER = 1|0
CONFIG TIMER0 = TIMER , PRESCALE= 1|8|64|256|1024
bei "ON interrupt label [NOSAVE]" steht auch nichts über einen OC0. Ich kann den Interruptvektor allerdings einstellen und er wird auch bei eigener Timerkonfiguration verwendet.

Wenn ich das über Bascom einstellen lasse, dann ruft er die ISR für CompareMatch nicht auf. Erst wenn ich die Register selber beschreibe ruft er die ISR auf. Bascom scheint also den Timer0 für den CTC-Mode mit Compare0-Interrupt nicht sauber zu initialisieren. So wie es aussieht wird beim Timer0 immer nur der Ovf0-Interrupt aktiviert.

Ich werde also bei meinen direkten Registereinstellungen bleiben. Da muß ich dann auch nicht raten sondern ich weiß was drin steht.

Gruß
Dino
 
Ich verstehe nicht, warum ihr da dauernd auf angeblichen Schwächen von Bascom rumhackt.
Einen Timer im CTC-Modus zu betreiben geht einfach so:
Code:
$regfile = "m16def.DAT"
$crystal = 16000000
$framesize = 40
$hwstack = 32
$swstack = 20

Config Portd.5 = Output
Config Portb.3 = Output

Config Timer0 = Ctc , Prescale = 64 , Clear_timer = 1 , Compare = Toggle             'PortB.3 toggelt zur Kontrolle ebenfalls
On Compare0 Timer0_isr
Enable Compare0
Enable Interrupts

Do
   Ocr0 = 24
   Wait 3
   Ocr0 = 249
   Wait 3
Loop
End

Timer0_isr:
   Toggle Portd.5                                           'toggled mit 500 Hz
Return

Wenn das im Buch von Klaus Kühnel nicht steht, dann hat er es nicht gewusst oder es nicht für wichtig gehalten.
Keine Ahnung. Ich verwende jedenfalls nur den CTC Modus, Timer vorladen halte ich für ein permanente Fehlerquelle.
Aber das muss jeder selber wissen.
Und wenn du lieber mit ASM arbeitest, ist das ja auch kein Problem. Aber es ist nicht der Fehler von Bascom.
In deinen bisherigen Programmen war es jedenfalls immer dein Fehler. Sorry.
 
Hi Rolf,

Ich verstehe nicht, warum ihr da dauernd auf angeblichen Schwächen von Bascom rumhackt.
Einen Timer im CTC-Modus zu betreiben geht einfach so:
Code:
Config Timer0 = Ctc , Prescale = 64 , Clear_timer = 1 , Compare = Toggle             'PortB.3 toggelt zur Kontrolle ebenfalls
On Compare0 Timer0_isr
[B][COLOR="#FF0000"]Enable Compare0[/COLOR][/B]
Enable Interrupts

Do
   Ocr0 = 24
   Wait 3
   Ocr0 = 249
   Wait 3
Loop
End

Timer0_isr:
   Toggle Portd.5                                           'toggled mit 500 Hz
Return
an der Stelle war der Fehler. Jetzt läufts auch mit Bascom. :) Hast gewonnen ;) Da stand bei mir noch Timer0. Irgendwie war ich der Meinung das man damit den Timer startet (Takt einschalten). Wenn man die Beispiele aus dem Buch interpretiert, dann hätte man drauf kommen können. :p Man sollte nicht mehrere Sachen gleichzeitig machen sonder sich auf eine Sache konzentrieren ...

Besten Dank nochmal.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)