Take AVR mega16 as an example, it has three registers, timer0, timer1 and timer2, T0 and T2 are 8-bit timers, T1 is a 16-bit register, T2 is an asynchronous timer, and all three timers can be used to generate PWM.
Let's take timer T0 as an example to briefly introduce the operation of the timer. T0 has three registers that can be accessed by the CPU, TCCR0, TCNT0, and OCR0. Let's take a look at a timer initialization program generated by ICC.
CODE:
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1KHz
// actual value: 1.000KHz (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
}
[Copy to clipboard]
TCCR0 is a control register used to control the working mode details of the timer;
TCNT0 is the T/C register, and its value is increased or decreased by one in each working cycle of the timer to realize the timing operation. The CPU can read and write TCNT0 at any time.
OCR0: Output compare register, it contains an 8-bit data, which is continuously compared with the counter value TCNT0. The match event can be used to generate an output compare interrupt, or to generate a waveform on the OC0 pin.
Here is the simplest mode. TCNT keeps adding one, reaches the maximum value 0xFF and then clears to enter the next count, in the above program.
TCCR0=0x00; turn off the clock source of T0 and the timer stops working.
TCNT0 = 0x83; Set the initial value of the T/C register and let the timer start timing or counting from TCNT0 at 0x83.
OCR0 = 0x7D; Set the value of the compare match register, which is not used in this program.
TCCR0 = 0x02; Select the clock source, which is the clock divided by 8. After setting, the timer starts working.
After initialization, the timer starts working. TCNT0 increases by one at each timer clock. When TCNT0 is equal to the value of OCR0, OCF0 in the T/C interrupt flag register - TIFR is set. If OCIE0 in TIMSK is 1 (that is, T0 compare match interrupt is allowed) and global interrupts are allowed, the compare match interrupt will run. In the interrupt program, TCNT0 and OCR0 can be operated to adjust the timer.
TCNT0 continues to increase by one. When it reaches 0xFF, TOV0 in the T/C interrupt flag register - TIFR is set. If TOIE0 in TIMSK is 1 (that is, T0 overflow interrupt is allowed) and global interrupts are allowed, the overflow interrupt will run. TCNT0 and 0CR0 can be operated in the interrupt program to adjust the timer.
The timer-related registers include SREG and TIMSK. Bit 1 of the former controls the global mid-segment enable, and bit 1 (OCIE0) and bit 0 (TOIE0) of the latter respectively control the compare match interrupt and overflow compare match interrupt enable.
In the actual process, the operation of timer-related registers is very flexible. The value of TCNT0 can be modified in the overflow interrupt, and the value of OCR0 can also be modified in the interrupt. In the following experiments, we will talk about how to use timer 1 to modify OCR1A to achieve 1S precise timing.
The master can only lead you to the door, but the practice depends on yourself. This is the basic principle of the timer. If you want to know more about the timer, please read the data manual.
Timing formula: Time=PRE*(MAX-TCNT0+1) /F_cpu unit S, where PRE is the frequency division number, which is 8 in this example, MAX is the maximum value 255, TCNT0 is the value at the time of initialization, which is 0x83 (decimal 131) in this example, and T_cpu is the system clock frequency, which is 1000000 in this example.
In this example, the timing time is: Time=8*(255-131+1)/1000000=0.001 S, which is 1ms, 1Khz. It can be seen that if the crystal oscillator is selected as 8M, the timing time becomes 0.000125S, that is, the larger the crystal oscillator, the shorter the timing time, and the larger the pre-scaling frequency, the longer the timing.
If you select 1ms during setup, you will get the following result, which is the same as 1Khz above.
CODE:
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1mSec
// actual value: 1.000mSec (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
}
//ICC-AVR application builder : 2007-6-9 0:33:58
// Target : M16
// Crystal: 1.0000Mhz
// Purpose: Demonstrate the working principle of timer
// Author: Gu Xin
// AVR and virtual instrument [url]http://www.avrvi.com[/url]
#include
#include
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x03; //PA0 PA1 output
PORTB = 0x00;
DDRB = 0xFF; //PB output
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1KHz
// actual value: 1.000KHz (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
}
//Compare match interrupt
#pragma interrupt_handler timer0_comp_isr:20
void timer0_comp_isr(void)
{
//compare occured TCNT0=OCR0
if(OCR0==0x7D) //Adjust 0x7D
{
OCR0=0x7F;
}
else
{
OCR0=0x7D;
}
PORTA ^= 0x01; //PA0 inverted
}
//Overflow interrupt
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x83; //reload counter value
PORTA ^= 0x01; //PA0 inverted
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x03; //timer interrupt sources enable timer zero match and overflow interrupt
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
init_devices();
PORTA=0x00;
while(1)
{
PORTB = TCNT0; //TCNT0 can be read at any time
}
}
Previous article:Mega128 serial communication program
Next article:AVR Timer Usage Example
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- TMS320C66x study notes universal parallel port interrupt service program example
- How many years can a laptop battery last?
- How to Use a Network Analyzer for Cable Testing
- Network port problem
- Looking for an audio spectrum chip
- [N32L43x Review] OPAMP internal operational amplifier usage
- Oscilloscope measurement of automobile CAN-BUS bus signal and waveform analysis
- Xun uses Yocto file system to develop QT file system for i.MX6ULL Terminator
- Msp430F5438A interrupt
- 10 ways to dissipate heat from PCB!