weird timer0 timer1 interaction

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello:

I am unsing the mega48 & have been using timer 1 to generate PWM signals on oc1a & oc1b with no trouble at all (fast PWm mode 9)

I needed another PWM so I decided to use timer 0 (OCOA), also in fast pwm mode3...however when I set it up it seems that my PWM's from timer 1 no longer function!!

ldi temp, $83
sts tccr0a, temp
ldi temp, $01 ;fast mode 3
sts tccr0b, temp

ldi temp, $A2 ;init pwm pot1/2 settings
sts tccr1a, temp
ldi temp, $09 ;fast 9 bit pwm mode 6
sts tccr1b, temp
ldi temp, $83

The timer OCR's are set elsewhere to control the pulse widths. When I delete the setting of tccr0a/b then timer 1 pwm works, otherwise it stops!!! What's going on??!!

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have tracked it down a bit more (no pun intended). If writing to TCCR0A is disabled, timer 1 continues to generate a nice PWM. Somehow writing to TCCR0A is shutting off the timer 1 function??!!\

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First, did you remember to set OC1A, OC1B and OC0A as outputs? You might want to set the Output Compare Registers (OCR0A, OCR1A and OCR1B) values before enabling their timer. Are any interrupts enabled?

; Timer0 WGM mode 3, fast PWM, 8 bit (0xFF TOP)

sbi DDRD, DDD6 ; set pin 10 (OC0A/PCINT22/AIN0/PD6) as an output

ldi temp, 0x83 ; use your real “initial” value here
sts OCR0A, temp		; Timer/Counter0 Output Compare Register A

ldi temp, (1 << COM0A1) | (0 << COM0A0) | (0 << COM0B1) | (0 << COM0B0) | (1 << WGM01) | (1 << WGM00) ; 0x83
sts TCCR0A, temp		; Timer/Counter0 Control Register A

ldi temp, (0 << FOC0A) | (0 << FOC0B) | (0 << WGM02) | (0 << CS02) | (0 << CS01) | (1 << CS00) ; 0x01
sts TCCR0B, temp		; Timer/Counter0 Control Register B

; Timer1 WGM mode 6, fast PWM, 9 bit (0x1FF TOP)

sbi DDRB, DDB1 ; set pin 13 (OC1A/PCINT1/PB1) as an output
sbi DDRB, DDB2 ; set pin 14 (OC1B/PCINT2/SS/PB2)as an output

ldi temp, 0x01 ; use your real “initial” value here
sts OCR1AH, temp		; Timer/Counter1 High Output Compare Register A
ldi temp, 0x90 ; use your real “initial” value here
sts OCR1AL, temp		; Timer/Counter1 Low Output Compare Register A
ldi temp, 0x01 ; use your real “initial” value here
sts OCR1BH, temp		; Timer/Counter1 High Output Compare Register B
ldi temp, 0x80 ; use your real “initial” value here
sts OCR1BL, temp		; Timer/Counter1 Low Output Compare Register B

ldi temp, (1 << COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10) ; 0xA2
sts TCCR1A, temp		; Timer/Counter1 Control Register A

ldi temp, (0 << ICNC1) | (0 << ICES1) | (0 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10) ; 0x09
sts TCCR1B, temp		; Timer/Counter1 Control Register B
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
sts tccr0a, temp
...
sts tccr0b, temp 

These should be OUT, not STS. Effect is that you're walking on PORTB and DDRB.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the help the--code provided didn't work for timer0, then I saw the post about using OUT instead of STS--- I changed it & now all works fine!!! Apoaarently you can use STS for timer1, but timer 0 must use the OUT command.

Thanks again,

Hoyt

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mckenney, thanks for noticing my mistake. Another DUH for me. Normally I use an AVR assembler 2 macro that kruse came up with and I never have to think about it anymore. At least the problem was solved.

OutReg tccr0a, temp 
... 
OutReg tccr0b, temp
; usage: InReg reg, addr
.macro InReg
    .if @1 < 0x40
        in @0, @1
    .elif @1 >= 0x60
        lds @0,@1
    .else
       .error "InReg: Invalid I/O register address"
    .endif
.endmacro

; usage: OutReg addr, reg
.macro OutReg
    .if @0 < 0x40
        out @0, @1
    .elif @0 >= 0x60
        sts @0,@1
    .else
       .error "OutReg: Invalid I/O register address"
    .endif
.endmacro