A Counter with precise delay in Atmega 2560

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

Hello...My task is to initialize the Timer 1 in Normal mode with initial count value of 0 and a frequency division factor of 256 and to display on the first row and first column of LCD, the number of times, the Timer has overflowed and on 5th such overflow, stop the timer and indicate this by turning ON buzzer for 2 seconds.

#define F_CPU 14745600
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd.h"		// user-defined header file - it is included in project folder

volatile unsigned int counter=0; // A global variable to act as a counter
 
 void buzzer_on (void)
{
	unsigned char port_restore = 0;
	port_restore = PINC;
	port_restore = port_restore | 0x08;
	PORTC = port_restore;
}

void buzzer_off (void)
{
  // PORTC=;      // Set PC3 to "0", making sure that other port pin values are unaffected.
   unsigned char port_restore = 0;
 port_restore = PINC;
 port_restore = port_restore & 0xF7;
 PORTC = port_restore;
}


void lcd_port_config (void)
{
		DDRC =	DDRC | 0xF7;	//all the LCD pin's direction set as output
		PORTC=	PORTC & 0x80; 	// all the LCD pins are set to logic 0 except PORTC 7
}

void timer1_init(void)
{
	TCCR1A = 0x00;	 // Timer 1 mode selection (Use Normal mode)
	TCCR1B = 0x00;  //Timer 1 mode selection
	TCNT1H = 0x1F; 	 //Counter higher 8 bit value
	TCNT1L = 0x01; 	 //Counter lower 8 bit value
	TCCR1B=  0x04;	 //start Timer by selecting prescalar factor 256 (avoid overwriting mode selection bits)

}


ISR(TIMER1_OVF_vect)
{
	//TIMER1 has overflowed
	if(counter<=5)
	{
	counter=counter+1;   // increment counter variable every time, the overflow occurs.
	}
	TCNT1H =0x1F;	//reload counter high value
	TCNT1L =0x01;	//reload counter low value
	
}


void interrupt_init()
{
	cli();    //Clears the global interrupts
	
	TIMSK1 = 0x01;  //TIMER 1 overflow interrupt enable
	
	sei();   //Enables the global interrupts
}

void indicate_and_buzz(void)
{
	//int column=1;
	//for(int i=1;i<=5;i++)
	while(1)
	{
		lcd_numeric_value(1,1,counter,3);
	}

	buzzer_on();
	_delay_ms(2000);
	buzzer_off();
}

//Please do not make any changes in the main function
int main (void)
{
	lcd_port_config();
	lcd_init();
	interrupt_init();
//	lcd_init();    // function is defined in the header file "lcd.h"
	timer1_init();
	indicate_and_buzz();
}

  

 

 

Last Edited: Sat. Feb 10, 2018 - 08:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

help me with this

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

Pushing for a response 7 minutes after first posting isn't going to win you any friends.  If you tell us when you have to hand in your homework we will give you a response.

 

David

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

 

Don't you need to wait until the value of counter changes before you display it, or does

lcd_numeric_value(1,1,counter,3);

do that for you? 

 

Jim

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

Pushing for a response 7 minutes

 

...and posting in the wrong forum doesn't help either. I'll move the thread.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

@Raving Lunatic...yes i have to wait until the counter changes its value..so where can I write lcd_numeric_value() function so that the lcd will display the value of counter starting from 1?

Last Edited: Sat. Feb 10, 2018 - 01:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Since when does "Level" mean "name"?

 

And since when did the word "please" get dropped from requests for help?

 

Ross McKenzie ValuSoft Melbourne Australia

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

Make sure any variables shared by irq & non-irq  code are declared  as volatile (ex, your counter variable). 

 

you are not monitoring/checking the counter overflow anywhere at all...so nothing has any idea if 5 have occurred & it is then time to sound the alarm.

 

It will set everything up , then  do something to the display 5 times and buzz, regardless of whether the timer did anything at all.
 

When in the dark remember-the future looks brighter than ever.

Last Edited: Sat. Feb 10, 2018 - 03:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

how about simply:

 

PORTC |= (1<<PC3)  //set pin

PORTC &= ~(1<<PC3) //clear pin

When in the dark remember-the future looks brighter than ever.

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

Here, I have Edited my code. I have checked the overflow value but i have no idea how to stop timer or how to get out from while loop. Here i have got number displaying from 0 to 6. but buzzeon() and buzzeroff() is not executed.  

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

I hope you didn't edit the code in your original post....

i have no idea how to stop timer or how to get out from while loop

You initialised the timer so do the opposite and you have a while condition which is checking the value of 1 and it will always be 1 so change the condition to something that you can change.

 

When is your assignment due in?

 

David 

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

How about (generically, not exact code):

 

the loop:

 

display present count

if count equals 5

     [stop timer &

     sound buzzer]

 

since the timer is stopped, the count will stay halted forever

There are many other arrangements possible...this example, the loop keeps going , "doing nothing"

 

 

Note, this rewrites the display at a very high speed (the loop), which is inefficient or may cause flickering (depending on the lcd code)....ideally you only write to the display when there is a new number...but start simple

 

When in the dark remember-the future looks brighter than ever.

Last Edited: Sat. Feb 10, 2018 - 03:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while(1)
	{
		lcd_numeric_value(1,1,counter,3);
	}

i tried this code, but iam getting an error undefined reference to 'lcd_numeric_value'. how to solve it if any one knows pls help us

ranju

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

while(counter<=2)

 

{

 

lcd_print(1,1,counter,5);

 

}

 

with lcd_print funtion i have cleared my error.

ranju

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

my task is to initialize Timer 1 in Normal mode with a frequency division factor of 64. Using Timer 1, display a stopwatch with time starting from 00000 to 20000 (0 s to 20 s, time displayed in milliseconds). Display time in milliseconds up to five digits.

iam not getting the counter value increment. pls help me with this code.

 

 

#define F_CPU 14745600

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include "lcd.h" // user-defined header file - it is included in project folder

 

 

 

volatile unsigned int counter=0; // A global variable to act as a counter

 

 

 

 

void lcd_port_config (void)

 

{

 

DDRC = DDRC | 0xF7; //all the LCD pin's direction set as output

 

PORTC= PORTC & 0x80; // all the LCD pins are set to logic 0 except PORTC 7

 

}

 

void timer1_init(void)

 

{

 

TCCR1A = 0x00; // Timer 1 mode selection (Use Normal mode)

 

TCCR1B = 0x00;  //Timer 1 mode selection

 

TCNT1H = 0x1F; //Counter higher 8 bit value

 

TCNT1L = 0x01; //Counter lower 8 bit value

 

TCCR1B=  0x03; //start Timer by selecting prescalar factor 256 (avoid overwriting mode selection bits)

 

}

 

 

 

ISR(TIMER1_OVF_vect)

 

{

 

if(counter<=20)

{

counter=counter+1;   // increment counter variable every time, the overflow occurs.

}   

TCNT1H =0x1F; //reload counter high value

 

TCNT1L =0x01; //reload counter low value

 

}

 

void interrupt_init()

 

{

 

cli();    //Clears the global interrupts

 

TIMSK1 = 0x01;  //TIMER 1 overflow interrupt enable

 

sei();   //Enables the global interrupts

 

}

 

 

 

void time_calc(int counter)

 

{

for(int j=0;j<=20;j++)

{

       lcd_print(1,1,counter,5);

      

_delay_ms(1000);

}

 

}

 

 

 

//Please do not make any changes in the main function

 

int main (void)

 

{

 

lcd_port_config();

 

interrupt_init();

 

lcd_init();                 //function is defined in the header file lcd.h

 

timer1_init();

 

time_calc(counter);

 

}

ranju

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

Are you in the same class as poojapatel? Why are you hijacking his thread?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

we are not in the same class, we just tried that code to solve the query.

ranju

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

pls help me with this code.

I am wondering

 

is there

 

 

 

 

a really

 

 

 

 

good  

 

 

 

 

reason  that  you

 

 

 

 

 

put way too

 

 

much

 

 

spacing in your

 

 

 

 

 

 

code

 

 

that it

is impossible

 

 

 

 

 

 

 

to see  on

 

 

the

 

 

 

 

screen

 

at one

time

 

 

and understand

 

 

 

 

 

what

 

 

you have

 

 

 

 

 

 

written

 

When in the dark remember-the future looks brighter than ever.

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

I condensed

#define F_CPU 14745600
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd.h" // user-defined header file - it is included in project folder

volatile unsigned int counter=0; // Global variable

void lcd_port_config (void){
	DDRC = DDRC | 0xF7; //all LCD pin's set as output
	PORTC= PORTC & 0x80; //all LCD pins are set to logic 0 except PORTC 7
}

void timer1_init(void){
	TCCR1A = 0x00; // Timer 1 mode selection (Use Normal mode)
	TCCR1B = 0x00;  //Timer 1 mode selection
	TCNT1H = 0x1F; //Counter higher 8 bit value
	TCNT1L = 0x01; //Counter lower 8 bit value
	TCCR1B=  0x03; //start Timer, prescalar factor 256 (avoid overwriting mode selection bits)
}


ISR(TIMER1_OVF_vect){
	if(counter<=20)
		{counter=counter+1;}   // increment counter every overflow 
	TCNT1H =0x1F; //reload counter high value
	TCNT1L =0x01; //reload counter low value
}

void interrupt_init(){
	cli();    //Clears the global interrupts
	TIMSK1 = 0x01;  //TIMER 1 overflow interrupt enable
	sei();   //Enables the global interrupts
}

void time_calc(int counter){
	for(int j=0;j<=20;j++){
   	    lcd_print(1,1,counter,5);
	   _delay_ms(1000);}
}

//Please do not make any changes in the main function
int main (void){     
	lcd_port_config();
	interrupt_init();
	lcd_init();   //function is defined in the header file lcd.h
	timer1_init();
	time_calc(counter);
}

 

When in the dark remember-the future looks brighter than ever.

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

my doubt is how to calculate the total time elapsed from the above code

ranju

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

Do you want your timing defined by the IRQ or   _delay_ms(1000);....pick one or the other

When in the dark remember-the future looks brighter than ever.

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

yes i tried, but it is not working.

ranju