enricorossi.org

Enrico Rossi


Test counter0 on atmega16

These programs illustrate the use of time counter 0 on a AtMega 16 MCU, AVR libc and avr-gcc.

In this example we have a 4Mhz external clock connected on an stk500 dev kit. If you use a different clock speed, please fix the FCPU value in the Makefile or in GCC flags.

GIT repository to clone

You can clone from my git repository to download the source code and eventually bugfix and patch.

Feel free to contact me for idea, suggestion or error fix. If you find this page helpfull please drop me a line, thanks.

Test 1

Simple fixed frequency counter.

Connect the PB3 (OC0) pin to a led and then the led will flash. This code simply activate the timer/counter 0 to a prescaled freq of 1024. The counter start count from 0 to 255 (8 bit), when it match the value set into the OCR0 register it will toggle the output pin OC0, reset the counter to 0 then restart counting.

/*
   Copyright (C) 2009 Enrico Rossi

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

   Enrico Rossi <e.rossi@tecnobrain.com>
 */

#include <inttypes.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>

int main (void) {
	uint8_t i;
	
	/* must output the OC0 port PB3 on Mega16*/
	PORTB = 0;
	DDRB = _BV(PB3);

	/* compare match to the top, max slow speed */
	OCR0 = 0xff;

	/* Timer Interrupt Unused */
	
	/* CTC mode with toggle OC0 on compare match */
	/* prescale to 1024 */
	/* start */
	TCCR0 = _BV(WGM01) | _BV(COM00) | _BV(CS02) | _BV(CS00);

	for (;;)
		_delay_ms(500);

	return (0);
}

compile with

avr-gcc -I/usr/avr/include/ -Wall -Wstrict-prototypes -pedantic -mmcu=atmega16 -Os -D F_CPU=4000000UL -o test.elf test_counter1.c -lm
avr-objcopy -j .text -j .data -O ihex test.elf test.hex

and program it on an stk500 with something like

avrdude -c stk500v1 -p atmega16 -P /dev/ttyUSB0 -e -U flash:w:test.hex

Test 2

Accellerating by decreasing the OCR0 value from 255 to 0, this will shorten the time the counter need to toggle the output. Note that we decrease the OCR0 in any time, not when a match occur, thus some missing match may occur sometime (see datasheet).

/*
   Copyright (C) 2009 Enrico Rossi

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

   Enrico Rossi <e.rossi@tecnobrain.com>
 */

#include <inttypes.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>

int main (void) {
	uint8_t i;
	
	/* must output the OC0 port PB3 on Mega16*/
	PORTB = 0;
	DDRB = _BV(PB3);

	/* compare match to the top, max slow speed */
	OCR0 = 0xff;

	/* Timer Interrupt Unused */
	
	/* CTC mode with toggle OC0 on compare match */
	/* prescale to 1024 */
	/* start */
	TCCR0 = _BV(WGM01) | _BV(COM00) | _BV(CS02) | _BV(CS00);

	for (;;)
		for (i=255; i>0; i--) {
			OCR0 = i;
			_delay_ms(200);
		}

	return (0);
}

Compile and install as above.

Acknowledgment