Getting Timer 0 to work

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

Hi All,

Some (many) of you were kind enough to help last November with some newbie questions.

I'm now trying to get 4 servos to run at once, and can't get timer0 to work.

So I thought I would go to first principles and try something really simple.  It's not working, so I have attached it.

 

There's a Delay routine, a debugging print routine, plus "main".  I've looked at the C code expansion to assembler to try to compare it with what's in the data sheet.

Things look okay to me.  Comment indicates where it gets stuck. 

The code originally came from Mazidi, Mazidi and Naimi's book "The AVR Microcontroller And Embedded Systems Using Assembly and C".

 

Thanks for any guidance you can give.

--John

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "avr/io.h"
#include "USART.h"

void T0Delay ();
void printDecWord ();

int main () {
	DDRB = 0xFF;
	initUSART();

	T0Delay();
	for (;;) {
		printString ("main\n\r");
		PORTB = 0x55;
		T0Delay ();
		PORTB = 0xAA;
	}
}

void T0Delay () {
	TCNT0 = 0x20; // _SFR_IO8(0x26) : assembly code just says 0x26
	TCCR0A = 0x01;
	printString ("waiting\n\r");
	while ((TIFR0 & 0x1) == 0) { // stuck in this loop forever
		printDecWord (TIFR0);
	}
	printString ("done\n\r");
	TCCR0A = 0;  // _SFR_IO8(0x24) assembly code just says 0x26
	TIFR0 = 0x1; // _SFR_IO8(0x15) assembly code just says 0x26
}

void printDecWord(uint16_t word) {
    if (word >= 10000)
        transmitByte('0' + (word / 10000));                 /* Ten-thousands */
    if (word >= 1000)
        transmitByte('0' + ((word / 1000) % 10));               /* Thousands */
    if (word >= 100)
        transmitByte('0' + ((word / 100) % 10));                 /* Hundreds */
    if (word >= 10)
        transmitByte('0' + ((word / 10) % 10));                      /* Tens */
    transmitByte('0' + (word % 10));                             /* Ones */
}


To save others following the link the above is bb.c

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

Perhaps you should tell us which AVR model is involved.  And perhaps show a build-log snippet, that shows that you are indeed building for that model.  Tell toolchain and version.

 

Do the printString()'s come through?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

clawson wrote:
assembly code just says ...

 

???  Perhaps show a .LSS fragment for the T0delay routine.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Okay, good questions.

The printStrings come through.

 

Compiling on Linux for 328p as below:

The compile:

avr-gcc -Os -g -std=gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums  -ffunction-sections -fdata-sections  -DF_CPU=1000000UL   -DBAUD=9600UL -I. -I../../AVR-Programming-Library -mmcu=atmega328p -c -o bb.o bb.c
avr-gcc -Wl,-Map,bb.map  -Wl,--gc-sections  -mmcu=atmega328p bb.o ../../AVR-Programming-Library/USART.o  -o bb.elf
avr-objcopy -j .text -j .data -O ihex bb.elf bb.hex
avrdude -c avrisp -p atmega328p -b 19200 -P /dev/ttyACM0  -U flash:w:bb.hex

 

Part of the lst file for the T0Delay routine:

 

00000132 <T0Delay>:
 132:   80 e2           ldi r24, 0x20   ; 32
 134:   86 bd           out 0x26, r24   ; 38
 136:   81 e0           ldi r24, 0x01   ; 1
 138:   84 bd           out 0x24, r24   ; 36
 13a:   80 e0           ldi r24, 0x00   ; 0
 13c:   91 e0           ldi r25, 0x01   ; 1
 13e:   0e 94 d9 00     call    0x1b2   ; 0x1b2 <printString>
 142:   a8 99           sbic    0x15, 0 ; 21
 144:   05 c0           rjmp    .+10        ; 0x150 <T0Delay+0x1e>
 146:   85 b3           in  r24, 0x15   ; 21
 148:   90 e0           ldi r25, 0x00   ; 0
 14a:   0e 94 4b 00     call    0x96    ; 0x96 <printDecWord>
 14e:   f9 cf           rjmp    .-14        ; 0x142 <T0Delay+0x10>
 150:   8a e0           ldi r24, 0x0A   ; 10
 152:   91 e0           ldi r25, 0x01   ; 1
 154:   0e 94 d9 00     call    0x1b2   ; 0x1b2 <printString>
 158:   14 bc           out 0x24, r1    ; 36
 15a:   81 e0           ldi r24, 0x01   ; 1
 15c:   85 bb           out 0x15, r24   ; 21
 15e:   08 95           ret

 

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

Now we know Mega328 target, right?

 

And now we can look at the characteristics of timer0 on that model.  As with most/many AVR8 models, timers are controled with the CSnm bit in the B register.  You have not set that up, so the timer is "stopped"/not running.

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Wed. Jan 3, 2018 - 04:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've selected PWM Phase Correct, is that what you wanted?

 

You haven't selected a clock source, TCCR0B (0x25) CS02:0 so module isn't running. 

 

NOTE: Didn't see previous post before I sent mine.

Last Edited: Wed. Jan 3, 2018 - 04:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This looks good.  Thank you.   I'll check it out after I get back from dinner.

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

Decided to check in the morning so I wouldn't be up all night if it didn't work for me.  But it did...many thanks.

--John