Generating exactly 1 second interrupt in Atmega16 without external Crystal

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

Dear all, 

 

I want my program to call a specific function every one second and I don't want to use `delay_ms()`. I set internal 8 MHz oscillator as the source of clock. I think I must use timer interrupts, but I don't have any idea if is it possible to generate exactly 1 second delays or not. 

May I ask you to help me handle it. The origin problem is to calculate average of a sine input signal for one second and send that average to the computer using USART protocol. because of this I don't want to use `delay_ms()` function. I want to calculate the average in my program `while()` loop and then every 1 second the interrupt send the result to COM port and also to my 2*16 LCD.

 

Thanks in advance.

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

It is common to ask the next question:  What is "exactly one second"?  The short answer is that there is no such thing; even the international standard clocks are averaged...

 

If your question is "I want to do something once a second, to the accuracy of my AVR clock source" that is a much more reasonable question.  See the datasheet specifications for the internal oscillator.  The accuracy may be +/- a few percent.  If you care to calibrate it with a more accurate time base, then you should be able to get to less than 1%.  See the datasheet also, for changes in the internal clock frequency with changes in supply voltage and temperature.

 

In all of my AVR applications, I set up a timer to create a "tick" that is then used for all internal timing.  My most common value is 10ms.  So every 10ms a "tick" is generated.  These are then added to whatever soft timers are needed in the application.  In your case, you may want to count up or count down until you get 100 of these 10ms ticks, and when satisfied then you do your "every one second" activities and reset the counter mechanism.

 

https://www.avrfreaks.net/forum/u...

That is an extensive thread that is very pertinent to the above.  It goes into the "exact" question, but the OP for that thread was also trying to make one second with a timer so it will be a very good starting point.

 

 

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: Tue. Jun 16, 2015 - 03:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From experience, the internal oscillator will provide pretty accurate, yet slightly inaccurate timing, I used it for a clock (actual time telling clock), and it was off by about a minute after 24 hours

Anyhow, you can use the 16 bit timer (Timer1) in ctc mode, it'll give you an interrupt and reset every time it reaches the value in OCR1A/B.

This tool is neat for calculating what value you need to put in OCR1:
http://eleccelerator.com/avr-tim...

Just input your clock freq., prescaler value and input 1 sec in real time, then press the real time button and it'll give you the value you need, in the "Total Timer Ticks" field.
If the value isn't a whole number, try to change the prescaler, the timer doesn't accept decimal points.

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

When talking of timing accuracy think of parts-per-million and what you would think was acceptable.

 

50ppm is the equivalent of 4.32 seconds per day

500ppm is the equivalent of 43.2 seconds per day

5000ppm is the equivalent of 432 seconds = 7.2 minutes per day

50000ppm is the equivalent of 72 minutes per day

100000ppm is the equivalent of 144 minutes (2.4 hours) per day.

 

The internal RC of a mega 16 has a potential error of 10% which is 100000ppm. So it could be off by more than 2 hours per day.

 

A 32.768kHz watch crystal costs about $0.05..$0.10

 

You do the maths ;-)

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

I set the internal 8 MHz oscillator as the clock source, and wrote the below ISR for my program:

 

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
char v_avg[16];

// Reinitialize Timer1 value
TCNT1H=0x85EE >> 8;
TCNT1L=0x85EE & 0xff;

++j;
if (j==32250)
{
    sprintf(v_avg,"%d",i);
    lcd_clear();
    lcd_gotoxy(0,0);
    puts(v_avg);
    i++;
    j=0;
}


}

 

I except the above ISR to print my counter value (i.e value of i) on the LCD every 1 second. But I see nothing on the LCD. Is there anything wrong with my program?

 

--------------------------------------------------------

 

This is whole the program so far:

 

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 6/16/2015
Author  : 
Company : 
Comments: 


Chip type               : ATmega16A
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*******************************************************/

#include <mega16a.h>

#include <delay.h>

// Alphanumeric LCD functions
#include <alcd.h>

// Declare your global variables here

// Standard Input/Output functions
#include <stdio.h>

 int i=0;
 int j=0;



// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
char v_avg[16];

// Reinitialize Timer1 value
TCNT1H=0x85EE >> 8;
TCNT1L=0x85EE & 0xff;

++j;
if (j==32250)
{
    sprintf(v_avg,"%d",i);
    lcd_clear();
    lcd_gotoxy(0,0);
    puts(v_avg);
    i++;
    j=0;
}


}

// Voltage Reference: AREF pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}

void main(void)
{
OSCCAL = 0xAD;
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31.250 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 s
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x85;
TCNT1L=0xEE;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 19200
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x19;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: ADC Stopped
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 8
lcd_init(8);

// Global enable interrupts
#asm("sei")

while (1)
      {

      }
}

 

Last Edited: Tue. Jun 16, 2015 - 03:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As I want to send data to my computer using USART, with a baud rate of 19200 bit per second, I think using a 32.768 KHz is not applicable. I mean I wonder if it not possible to generate 19200 baudrate using 32.768 KHz crystal. Am I right?

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

Where to start...

 

"nothing on the LCD"?  How about putting out "hello world" after startup, to ensure that your LCD is working?

lcd_init (8);

lcd_putsf ("Hello");
lcd_gotoxy (1,1);
lcd_putsf (" world!");

Did you check the return value from the lcd_init()?  Character LCDs are very slow to start up.  I suggest a delay of at least 100ms at AVR startup before attempting character LCD operations.

 

Try to find examples of CTC mode for timer operations.  There is no need to be manipulating TCNT in the ISR.

 

Almost always, you do not want to do extensive operations inside an ISR.  Set a volatile flag variable to indicate that the event occurred.  In the main loop, check the flag.  When set, clear the flag for the next "tick", and then do your operations.

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

You do realize that with the code you posted you will only get a compare match on j every 32250 seconds -- nearly 100 hours.  About every half week...

 

(Your Wizard-generated code makes an interrupt every one second. 

 

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31.250 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 s
// Timer1 Overflow Interrupt: On

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

I'm not sure why this is a separate thread from your Thread on averaging a signal?

 

You did not answer any of my questions in your other Thread.

What is the frequency of the signal? etc., etc.

 

You could certainly do as you suggest, have a 1 per second interrupt and read out some value.

 

I think a more traditional approach would be to have a Timer/Counter in CTC mode, and take an ADC sample every 1 mSec, (for example).

Then, on the 1000th sample you update a variable holding the second's data, and a flag marking new data.

In your Main Loop you watch for the flag.

When it is set you know you have a new 1 second's worth of data, and you display it on your LCD and send it out the USART.

You also reset the flag.

 

The timing work is done by the Timer/Counter which generates the ISR to trigger obtaining the ADC samples.

 

There isn't a need for a 1 / second interrupt.

 

JC

 

 

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

You are right. Its a good idea. I'll change my following approach to your approach. I don't have any idea how much is the input signal frequency. 

 

I change the above program to the following one. The program works fine for LCD. I mean I can see a counter on the LCD but I receive nothing on the serial port!

 

/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Automatic Program Generator
© Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 6/16/2015
Author  : 
Company : 
Comments: 


Chip type               : ATmega16A
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*******************************************************/

#include <mega16a.h>

#include <delay.h>

// Alphanumeric LCD functions
#include <alcd.h>

// Declare your global variables here

// Standard Input/Output functions
#include <stdio.h>

int flag=0;
// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
TCNT1H=0x85EE >> 8;
TCNT1L=0x85EE & 0xff;

flag =1;
}

// Voltage Reference: AREF pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}

void main(void)
{
int i=0;
char v_avg[16];
OSCCAL = 0xAD;
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31.250 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1 s
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x85;
TCNT1L=0xEE;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
MCUCSR=(0<<ISC2);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 19200
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x19;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: ADC Stopped
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 8
lcd_init(8);

// Global enable interrupts
#asm("sei")

while (1)
      { 
      if(flag)
        {    
        lcd_clear();
        lcd_gotoxy(0,0);
        sprintf(v_avg,"%d",i);
        lcd_puts(v_avg);
        printf("1"); 
        ++i; 
        flag=0;
        }
      }
}

 

When I mask the above program on my micro, the value on the LCD increase by 1, each second but in the computer I have nothing as below:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Note that I tried different tools on the host. but nothing changed. I always receive nothing.

 

Last Edited: Tue. Jun 16, 2015 - 06:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Nothing"?  You used a 'scope or logic analyzer or similar, on PD1 of your Mega16, and see "nothing"?

 

You said that you set the internal 8MHz as your clock source.  Have you proven that?  How close is your clock to exactly 8MHz?  (Once you are a few percent off, then you will not get successful serial communications.)  What do you have connected to PD1 of your Mega16?

 

Where did you get the 0xad that you are loading into OSCCAL?  Have you made a loop, using all values of OSCCAL and then printing teach value to the serial port, and see which appear on your terminal emulator.

 

 

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

Well. First thing you need to be sure you're doing is writing to your com port, so skip all the timer and interrupt stuff and just make the program write "Heavens to Murgatroid" or somesuch out. Once you get that working, then you can start playing with your timer.

 

Tip: There's a mode of the timer where it will generate an interrupt and restart itself. Use that.

 

Edit: *Where there was a will*

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

Last Edited: Wed. Jun 17, 2015 - 01:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at a small GPS module, it provides an accurate Pulse Per Second signal.

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

Thank you all my friends. I checked my circuit again and again and finally I found that I forgot to use MAX232 IC in my circuit and the COM port pins was connected to the MCU pins directly! I so sorry for wasting your time.  :(

 

After adding a MAX232 to the circuit it works fine using the internal 8MHz oscillator. 

 

The final version of my program has some problems still. I posted the final code so far in this topic :  https://www.avrfreaks.net/forum/a...

 

dear theusch :

Where did you get the 0xad that you are loading into OSCCAL? 

I am using ProgISP to communicate with my program. This tool has compatibility to show calibration values as below:

 

 

Last Edited: Thu. Jun 18, 2015 - 03:16 PM