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.