starting and stopping timer 0?

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

Alright I'm pretty new to MCU's but I'm working on my first project. Anyways, in my project I need a clock that can count for 15 minutes, now I've got a book and I've already figured out all the necessary things such as prescale factor and other variables needed to count for 15 minutes. That is not the problem though. I'm planning on using timer 0.

My problem is that I am not sure how to start and stop the timer. I don't want the timer ISR always running, so what line of code do I use to start and stop it?

Referencing my book it says that:

TIMSK=0x01;					

unmasks the interupt

and

#asm("sei")

activates interrupts.

So if I want in a certain place within the loop the timer to start do I unmask it using TIMSK on that certain line (I assume #asm("sei") would still be in the main function)? And how do I stop and reset it also?

Probably gonna be using a small avr like the ATTINY2313.

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

You can stop timer with clearing prescale bits.
Say prescale = 1024.

#define START_TIMER0 TCCR0B |= (1<<CS0)|(1<<CS2)
#define STOP_TIMER0  TCCR0B &= 0B11111000
#define CLEAR_TIMER0 TCNT0 = 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why dont you just stop and start the timer rather than playing around with interrupts?

TCCR0 = 0x00; //stops the timer
TCCR0 = 0x??; //start timer with prescale etc?

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

Kartman wrote:
Why dont you just stop and start the timer rather than playing around with interrupts?

TCCR0 = 0x00; //stops the timer
TCCR0 = 0x??; //start timer with prescale etc?

Thanks, that's what I was wondering. Does it reset the timer too (I know the count cycles are very quick but do they go back to 0)?

Also in my book for setting up timer 0 it had this code:

//TTCR0 = 0x?? 					
//TCNT0 = 0x00;
//OCR0 = 0x00;

TIMSK=0x01;					
#asm("sei")

So I realize now the first line not only sets prescale but also activates the timer and the other 2 at the very bottom allow the timer to trigger interrupts upon overflow. But what about TCNT0 and OCR0? What are these for and are they needed? I tried reading about it in the ATTINY 2313 manual but didn't understand it.

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

Throw away your book and read the datasheet instead.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

Lol yeah I have been reading the datasheet but I this book is a C programming for avr reference, the datasheets talks in terms of registers and assembly code but not in what specific code I need to enter to make it work. I know basic assembly but have not desire to program in it. Anyways, here's the project I'm working on.

I'm wanting to create a device that controls the power to something based on a timer. Basically the device will sit between whatever you want to power and the outlet, and it will have a 15 minute timer activated by an on/reset button. After 15 minutes it will give an audible warning and then go into a 5 minute countdown and then after that shut off the power to whatever you plugged into it (using a relay). To stop it from powering off the user must push the reset button sometime within the 20 minutes, it's a safety type device to ensure you don't leave something on unattended. I have typed out what I think is the code with the timer interrupts and everything, but I'm having trouble getting it to compile based on the timer stuff. Here is my code:

#include 
#include 

int cycle_count = 0; 	// Counts up to 1 second
int second_count = 0; 	// Counts number of seconds
int secondary = 0;		// Indicates if in 5 minute countdown

									// Timer/Counter 0 ISR

ISR(TIMER0_OVF_vect) 
{
	TCNT0 = 6; 						// Set reload number to 6 which means timer ISR
									// counts up to 256 - 6 = 250 per ISR
	
	++cycle_count;
	
	
	if (cycle_count == 2500)		// Increment second count per 2500 overflow cycles
	{
		cycle_count = 0;
		++second_count;
	
	}
}

int main (void)
{
	DDRA = 0x1F;					// Set 5 inputs on LSB and rest as outputs
	
	PORTA = 0x04;					// Pull all and I/O low (active high) and let led Pin A2 be high for
									// red off status indicator LED								

	
	TIMSK = 0x01;						// Unmask and enable interupts
	#asm("sei")		
	
	while(1)
	{
		if (PINA | 0x20)			// If pin 5 of port A is high (ON/RESET button) start timer
		{
			second_count = 0;		// Reset second_count back to zero
			secondary = 0;			// Deactivate secondary (5 min countdown) status
			TCCR0 = 0x03;			// Activate and prescale to sysck/64
			
			PORTA = PORTA | 0x11; 	// Turn relay and green status LED on
			
		}
		
		while ((second_count == 900) & (second_count <= 902))	// After 15 minutes (900 seconds ) has elapsed
		{							
			
			if (PINA | 0x20)					// Reset if triggered
			{
			second_count = 0;		
			secondary = 0;
			TCCR0 = 0x03;
			
			PORTA = PORTA | 0x11; 	
			}
			
			
			PORTA = PORTA | 0x0A; 				// Set pin 1 (buzzer) and pin 3 high (yellow warning LED)
												// while leaving others alone indicating 5 minute warning
			if (second_count > 901)
			{
				PORTA = PORTA ^ 0x02;			// Silence pin 2 buzzer by bit masking 
			}
			
			secondary = 1;						// Set secondary mode as active
			second_count = 0;					// and reset second_count for countdown mode
					
		}
		
		while ((second_count >= 300) & (secondary == 1))
			{
				PORTA = PORTA | 0x02;
				
				if (second_count >=305)
				{
					PORTA = 0x04; 				// Silence pin 2 buzzer, and turn all other pins off
												// except for red LED
												
					TCCR0 = 0x00; 				// Stop timer
					second_count = 0;			// Reset second_count back to 0 for next run
				}
			}
	
	}
}

I'm getting the following errors:

Quote:

sss.c:35:3: error: invalid preprocessing directive #asm
sss.c: In function 'main':
sss.c:43: error: 'TCCR0' undeclared (first use in this function)
sss.c:43: error: (Each undeclared identifier is reported only once
sss.c:43: error: for each function it appears in.)
make.exe: *** [sss.o] Error 1

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

Quote:
sss.c:35:3: error: invalid preprocessing directive #asm
Because you are giving it code intended for a different compiler. For avr-gcc just use sei().
Quote:
sss.c:43: error: 'TCCR0' undeclared (first use in this function)
Likely because you are compiling for a different AVR than the code is written for.

Regards,
Steve A.

The Board helps those that help themselves.

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

You're doin' more than what you're ready for, since you don't know how to start / stop a timer. Build up in your understanding of the timer systems. After throwing away that book, STUDY the timer tutorials in that forum. Start with abcminiusers ( his is about the most extensive ). Take it a section at a time and use an led so you can visually check your understanding. Write the code in the section and GET IT, or at least begin to. Got a scope ( USE it , if you do ) ?

In your T0_ISR(), tcnt0 only goes to 255, NOT 256. ANY cnter goes to ( 2^N ) - 1.

It's scary that for your 1st MCU pjt. you're building a circuit that controls an AC device, but don't understand enough about getting it to compile ( questions your programming experience ) or really get the timers ( KEY hardware for this design ). I hope there are no gaps in your analog knowledge.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
After throwing away that book, STUDY the timer tutorials in that forum.

Lol the book was actually recommended in this thread:
https://www.avrfreaks.net/index.p...

"Embedded C Programming and the Atmel AVR
by Richard H. Barnett, Sarah A. Cox, Larry D. O'Cull"

I'll read some more of the tutorials here though, it just seems like lot I found on websites other than this one seem to be about nothing but very basics, basic I/O operations, basic loops and conditional statements. I had a C++ class my first year as an ECE (student) I'm a senior now (but really a second semester junior curriculum wise). I also had a microcomputer class this last semester but we used the HCS12 Motorola processors programming in assembly. It was a lab and class so I did get some practice but when we talked about interrupts, timers, input capture, pwm, etc. we did not actually do any labs on those subjects. I seem to understand the basic concept of how timer 0 functions(at least I think) but I am having trouble implementing it cause I am still learning AVR C. But I guess I'll do what you said first and go back and read some more tutorials on this forum.

What's the next best topic to start with after I/O operations, conditional statements and bit masking?

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

Since you've done those, you're on A right track going with timers. You can tie all those subjects into using timers. Get timer0 to flash an led at some see-able rate using CTC mode, then using PWM. Get an led to just turn on by using a timer0 ISR(), then toggle it in the ISR(). After that, you have a good base to go on to whatever other subsystem interests YOU most. Personally, I'd go for getting an LCD working for debugging future pjts when you need it.

The Motorola MCUs have regs. called PERIOD and DUTY. Look at the t2313 timer1 table that has mode0 - mode15.
TOP => PERIOD reg. and an OCR1x reg. => DUTY reg. ( if OCR1A is TOP, you lose it as a duty reg. ) . When you can think about timer functions and code works as you image it, you really got / gettin' it.

Good tool to CONFIRM, not replace, your understanding:
http://www.b9.com/elect/avr/kavr...

I skimmed that book at a library... and put it right back on the shelf ( the PIC version's MUCH better ). Get this dude's book:
smileymicros.com and you'll be doin' something ( he has a free chapter download and it's GOOD ! "C programming for ..." )

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

TAlking abt timer0, anyone knows how to use timer0 as counter? i did my coding by copy paste from websites examples but yet didn't work. my application is to start the timer0 when i transmit signal n stop the timer upon receiving signal. den using the bits from my timer0 results i can calculate the bits to get the time taken for the signal to travel from transmitter to receiver.

here are my code:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 		//INCLUDE PWM TIMER

unsigned int timeL,timeH;

int channel_one , channel_two;   
char hundreds[11]={'0','1','2','3','4','5','6','7','8','9','T'};
char tens[10]={'0','1','2','3','4','5','6','7','8','9'};
char no[10]={'0','1','2','3','4','5','6','7','8','9'};
void ADC_SEND(void);
void InterruptHandlerLow(void);			// Low priority interrupt service routine

#pragma code InterruptVectorLow = 0x018	// Low priority interrupt vector
void InterruptVectorLow(void) 
{
  	_asm
 	goto	InterruptHandlerLow			// Jump to interrupt routine
  	_endasm
}


#pragma code									
#pragma interruptlow InterruptHandlerLow


void InterruptHandlerLow() 			// Low Priority Interrupt Routine
{		
	

	if(PORTCbits.RC4==1)			//IF SIGNAL RECEIVED,
	T0CONbits.TMR0ON=0;				//STOP COUNTER
	timeL = TMR0L; // Save lower byte to variable 
	timeH = TMR0H; // Save lower byte to variable 

	
	ADCON0 = 0b00000001;			// Select AN0 for conversion ; A/D enabled
	ConvertADC();					// starts A/D conversion
	while (BusyADC());				// wait for conversion to finish
	channel_one = ReadADC(); 		// read the result of the A/D conversion for AN1
	CloseADC();						// disable the A/D converter

	ADCON0 = 0b00000101;			// Select AN1 for conversion				
	ConvertADC();					// Start A/D conversion
	while (BusyADC());				// wait for conversion to finish
	channel_two = ReadADC();   		// read the result of the A/D conversion for AN2
	CloseADC();						// disable the A/D converter
   

	while (BusyUSART());	       	// ensure the serial port is not busy
    WriteUSART('s');
    while (BusyUSART());
	WriteUSART(hundreds[(channel_one/100)]);
    while (BusyUSART());
	WriteUSART(tens[(channel_one%100)/10]);
	while (BusyUSART());
	WriteUSART(no[(channel_one%100)%10]);
	
	while (BusyUSART());
	WriteUSART(hundreds[(channel_two/100)]);
     while (BusyUSART());
	WriteUSART(tens[(channel_two%100)/10]);
	while (BusyUSART());
	WriteUSART(no[(channel_two%100)%10]);
}



									//////////////////	
//----------------------------------// Main Program //-----------------------------------------------
									//////////////////									
void main()
{	
	TRISA = 0b11111111;				    // sets Port A as input - for analog input
	TRISB = 0b00000000;					// sets Port B as output - for digital output ?
	TRISC	= 0b10011000;				//RC7(R-X) as input & RC6(TX) as output 
	//TRISC = 0x10111111;				// sets Port C bit 6 (TX) as output and the rest as input
	INTCON 	= 0b11100000;				// Enables all Interrupt, Peripheral Interrupt and TMR0
 	//configure and activate the internal oscillator
	OSCCON = 0b01110000;        	 	//select internal 8Mhz frequency
	OSCTUNE = 0b01000000;				// PLL Mode enable, Total Internal Oscillation = 32MHz 
	

	//TIMER0 SETTINGS
	OpenTimer0 (TIMER_INT_ON &			// On Timer0 Interrupt
			   T0_16BIT &				// 16-bits Mode
			   T0_SOURCE_EXT &			// External Clock Source
			   T0_PS_1_8);				// Set Prescaler to 1:8
	
	//RS232 SETTINGS
	OpenUSART(USART_TX_INT_OFF &		// Transmitter Interrupt Off
			USART_RX_INT_OFF &			// Receiver Interrupt Off
			USART_ASYNCH_MODE &			// Set USART to Asynchronous Mode
			USART_EIGHT_BIT &			// 8-bits Data
			USART_CONT_RX &				// Continuous Reception
			USART_BRGH_HIGH,103);		// High Speed Rate and Baud Rate = 19200 {(32000000/19200*16)} - 1


	//THIS IS THE SETTING FOR THE PULSE WIDTH MODULATION
	//THIS IS IN PIN 13
	OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);	//OPEN PWM. PRESCALAR IS 1:1
	OpenPWM1(0xc7);	//REFER TO A FOR CALCULATION									
	SetDCPWM1(400);	//REFER TO B FOR CALCULATION

   	RCONbits.IPEN		= 1;			// Enable Priority Level
   	INTCON2bits.TMR0IP	= 0;  			// Set Timer0 Interrupt with Low Priority
   	INTCONbits.GIEH 	= 1;			// Enable Interrupts with Low Priority
  	INTCONbits.GIEL		= 1;			// Enable Global Interrupt

	
 
	//// open A/D module ////--------------------------------------------------------------------------
		 
	ADCON1 = 0b00001100;				// configure AN0, AN1 and AN2 as analog channels
	ADCON2 = 0b10010010;				// A/D result right justified; 12 TAD ; FOSC/32;ACQ=4TAD

	if(PORTCbits.RC2==1)		//IF SIGNAL IS TRANSMITTED,
	T0CONbits.TMR0ON=1;			//START COUNTER FROM 0 BITS
	TMR0L=0b00000000;
	TMR0H=0b00000000;  		
	while(1);
}

u will notice that there are other function, do ignore that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
here are my code: 

#include  

Looks suspicious to me. :roll:

Also PLEASE DO NOT use sms language but your best English and learn to use the CODE button when posting code.

Attachment(s): 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Shalam,

That code is for a Microchip PIC microcontroller. This is the AVRFreaks Forum. We discuss Atmel microcontrollers here.

Try here:

http://www.microchip.com/forums/

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

You say:

Quote:
TAlking abt timer0, anyone knows how to use timer0 as counter?

But then you say the actual use is:
Quote:
i can calculate the bits to get the time taken
Which is explicitly using the timer as a timer, not a counter.

Regards,
Steve A.

The Board helps those that help themselves.

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

#include
#include
#include
#include
#include
//INCLUDE PWM TIMER

unsigned int timeL,timeH;

void high_isr(void); // Low priority interrupt service routine
#pragma code high_vector=0x08 // High priority interrupt vector

void high_vector(void)
{
_asm goto high_isr _endasm //JUMP TO INTERRUPT ROUTINE
}

#pragma code //RETURN TO DEFAULT CODE SECTION
#pragma interrupt high_isr

void high_isr(void) // high Priority Interrupt Routine
{
PORTBbits.RB2=!PORTBbits.RB2;
T0CONbits.TMR0ON=0; //STOP COUNTER
timeL = TMR0L; // Save lower byte to variable
timeH = TMR0H; // Save higher byte to variable
INTCONbits.INT0IF = 0; //The INT0 external interrupt CLEARED.
}

void main()
{
TRISA = 0b11111111; // sets Port A as input - for analog input
TRISB = 0b00000011; // sets Port B as output - for digital output ?
TRISC = 0b10011000; //RC7(R-X) as input & RC6(TX) as output

//configure and activate the internal oscillator
OSCCON = 0b01110000; //select internal 8Mhz frequency
OSCTUNE = 0b01000000; // PLL Mode enable, Total Internal Oscillation = 32MHz

//TIMER0 SETTINGS
OpenTimer0 (TIMER_INT_ON & // On Timer0 Interrupt
T0_16BIT & // 16-bits Mode
T0_SOURCE_EXT & // External Clock Source
T0_PS_1_8); // Set Prescaler to 1:8

//TIMER0 START BITS @ 0
TMR0L=0b00000000; //TIMER0 STARTING BITS AT 0
TMR0H=0b00000000; //TIMER0 STARTING BITS AT 0

//THIS IS THE SETTING FOR THE PULSE WIDTH MODULATION
//THIS IS IN PIN 13
//OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1); //OPEN PWM. PRESCALAR IS 1:1
OpenPWM1(0xc7); //REFER TO A FOR CALCULATION
SetDCPWM1(400); //REFER TO B FOR CALCULATION

T0CONbits.TMR0ON=1; //START COUNTER FROM 0 BITS

//INTERRUPT SETTINGS
INTCON=0b00010000; //DISABLE GLOBAL & ENABLE EXT INTERRUPT,Disables the RB port change interrupt,
//Enables the INT0 external interrupt, Disables the TMR0 overflow interrupt,
INTCON2=0b01000000; //External Interrupt on rising edge
RCONbits.IPEN=1; //Enable priority levels on interrupts
INTCONbits.GIEH=1; //Global Interrupt Enable

while(1);
}

i doing a project on measuring time taken for ultrasonic transmitter to reach receiver. using timer0 to count. everything is set as required. i addd code to toggle 1 led to indicate in go to interrupt. but when i c watch window, the value of timer remain at start bits ie 0. y...

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

What are you takimg about?? Which part don't you undertand? You are on a Atmel AVR board and you are asking for help with code for a MICROCHIP PIC chip!

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Shalam, Wrong forum:

Microchip Technology Inc.

Go here: http://www.microchip.com/forums/

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

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

Quote:

Shalam, Wrong forum:

Microchip Technology Inc.

Go here: http://www.microchip.com/forums/


Agree - don't see any point taking this further.

Topic locked