Atmega8 with rtc crystal - Page 1
Forum section: electronics / general

author: ramin110
author_rank: Contributor
timestamp: January 16, 2016, 06:14:03 pm
content: hi everyoneI want to build a precise timer with atmega8 microcontroller and external 32.768khrz watch crystal. I set all fuse correctly for external crystal and etc. everything works fine but my timer has a offset of -1 second in each 9 seconds. what is my problem?please helphfuse = 0xc9lfuse = 0xe9code:#ifndef F_CPU#define F_CPU 32768UL#endif#include <util/delay.h>#include <avr/io.h>#include <inttypes.h>#include <stdlib.h>#include <string.h>//This function is used to initialize the USART//at a given UBRR valuevoid USARTInit(uint16_t ubrr_value){//Set Baud rateUBRRL = ubrr_value;UBRRH = (ubrr_value>>;/*Set Frame Format>> Asynchronous mode>> No Parity>> 1 StopBit>> char size 8*/UCSRC=(1<<URSEL)|(3<<UCSZ0);//Enable The receiver and transmitterUCSRB=(1<<RXEN)|(1<<TXEN);}//This fuction writes the given "data" to//the USART which then transmit it via TX linevoid USARTWriteChar(char data){//Wait untill the transmitter is readywhile(!(UCSRA & (1<<UDRE))){//Do nothing}//Now write the data to USART bufferUDR=data;}unsigned int count = 0;int main(void){DDRB = (1<<PB0);//for Baud rate = 300bps*/USARTInit(6);while(1){//LED On//PORTB = (1<<PB0);//_delay_ms(1000);//LED Off//PORTB = (0<<PB0);count++;char str;itoa(count, str, 10);for(unsigned int i = 0; i < strlen(str); i++)USARTWriteChar(str);USARTWriteChar(0b1101);_delay_ms(1000);}}

author: Simon
author_rank: Unknown
timestamp: January 16, 2016, 06:17:38 pm
content: Have you measured the crystal signal ? if there is a 10% error you should spot it easily. otherwise it's something in your code.

author: wraper
author_rank: Unknown
timestamp: January 16, 2016, 06:23:08 pm
content: Wait, are you making the timer with a delay function?

author: ramin110
author_rank: Contributor
timestamp: January 16, 2016, 07:15:28 pm
content: I am beginner in microcontroller and I think i can't use delay? right, i just changed the code and using avr timer. it's working. i think kindaint main(void){DDRB = (1<<PB0);//for Baud rate = 300bps*/USARTInit(6);OCR1A = 31;TCCR1B |= (1 << WGM12);// Mode 4, CTC on OCR1ATIMSK |= (1 << OCIE1A);//Set interrupt on compare matchTCCR1B |= (1 << CS12) | (1 << CS10);// set prescaler to 1024 and start the timersei();// enable interruptswhile(1){//LED On//PORTB = (1<<PB0);//_delay_ms(1000);//LED Off//PORTB = (0<<PB0);// count++;// char str;// itoa(micros(), str, 10);// for(unsigned int i = 0; i < strlen(str); i++)// USARTWriteChar(str);// USARTWriteChar(0b1101);//_delay_ms(10);}}ISR (TIMER1_COMPA_vect){count++;char str;itoa(count, str, 10);for(unsigned int i = 0; i < strlen(str); i++)USARTWriteChar(str);USARTWriteChar(0b1101);}

author: Simon
author_rank: Unknown
timestamp: January 16, 2016, 07:17:18 pm
content: The problem with delays is that you can't do anything else with the processor because it's locked into the time delay.If you use an interupt on a timer it means you can do something for the 99.9999995 of the time and then act when the interupt fires.

author: wraper
author_rank: Unknown
timestamp: January 16, 2016, 07:54:59 pm
content: Quote from: Simon on January 16, 2016, 07:17:18 pmAlso delay function is not accurate at all. All it does is burning CPU cycles without doing anything useful to get approximate delay. On top of that, doing something between delays (Sending data to USART), distracts the timing even more. Remember that your clock frequency is very low, so anything you do will take a hell a lot of cycles. Also slow clock by itself makes delay function less accurate rather than with higher clock.

author: Simon
author_rank: Unknown
timestamp: January 16, 2016, 07:58:38 pm
content: If you need higher processing speed then maybe the best thing is to use the clock chip to drive just the counter if your chip suports it so that the main CPU core can run at 1-20MHz. Or if not you can use a logic gate to make a crystal oscilator with the clock crystal and use it's output to drive an interupt enabled pin. I did this to make a pulse generator to drive an old mechanical clock, more because I could not make my uC work with the crystal but it immediately occured to me that I could harness the power of the uC to do anything else as well as the timer function.

author: ramin110
author_rank: Contributor
timestamp: January 16, 2016, 08:00:16 pm
content: thanks a lot people for useful information and your time.