2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Timers and counters are hardware modules used to measure time intervals or count events. They can be used in many applications, such as generating precise time delays, measuring frequencies, counting external events, etc. The timer of the 51 MCU belongs to the internal resources of the MCU, and its circuit connection and operation are completed inside the MCU. This article will introduce the working principle, configuration method and application of the timer and counter in the 51 MCU in detail.
This chapter will involve knowledge related to interrupts. For details, please refer to:Interrupt system explanation
Note: The timer resources are related to the model of the microcontroller. Different models of microcontrollers may have different numbers and operating methods of timers, but generally speaking, the operating methods of T0 and T1 are common to all 51 microcontrollers.
The timer is like a small alarm clock inside the microcontroller. According to the output signal of the clock, the value of the counting unit increases by one every "one second". When the value of the counting unit increases to the "set alarm reminder time", the counting unit will send an interrupt request to the interrupt system, generate a "ring reminder", and make the program jump to the interrupt service function for execution.
The working principle of timer/counter is based on clock pulse. In timer mode, they use internal clock source to count; in counter mode, they use external pulse source to count. Each timer/counter has a register to store the current count value.
The timing and counting functions are controlled by the control bits of the special function register TMOD.
C
T
Csqrt{T}
CTThe information of each bit of the TMOD register is listed in the following table. It can be seen that the two timers/counters have four operating modes, which are selected by M1 and M0 of TMOD. Modes 0, 1 and 2 of the two timers/counters are the same, while mode 3 is different. The functions of each mode are as follows:
By setting M1 and M0 in the TMOD register, timer/counter 0 and 1 have four different operating modes.
The working mode diagram is as follows:
Mode 1 is identical to Mode 0 except that all 16 bits of TH0 and TL0 are used. In this mode, the 8-bit overflow of TL0 carries to TH0, and the overflow flag TF0 in TCON is set when TH0 overflows.
When GATE=0 (TMOD.3), if TR0=1, the timer counts. When GATE=1, the external input INTO is allowed to control timer 0, so that pulse width measurement can be achieved. TRO is the control bit in the TCON register. The specific function description of each bit of the TCON register can be found in the introduction of the TCON register in the previous section.
Note: The timer of STC89C51RC/RD+ series MCU has two counting rates: one is 12T mode, adding 1 every 12 clocks, which is the same as the traditional 8051 MCU; the other is 6T mode, adding 1 every 6 clocks, which is twice the speed of the traditional 8051 MCU. The T0 rate is set in the STC-ISP programmer when burning the user program.
In this mode, the timer/counter can automatically reload the 8-bit counter. The overflow of TL0 not only sets TF0, but also reloads the contents of TH0 into TL0. (TH0 can be set first, and the contents of TH0 will not change during reloading)
For Timer 0, in this mode, Timer 1 stops counting, which has the same effect as setting TR1 to 0.
For Timer 0, in this mode, TL0 and TH0 of Timer 0 are used as two independent 8-bit counters. The following figure is the logic diagram of Timer 0 in Mode 3. TL0 occupies the control bits of Timer 0: C T Csqrt{T} CT, GATE, TRO, INTO and TFO. THO is limited to the timer function (counter cycle) and occupies TR1 and TF1 of timer 1. At this time, TH0 controls the timer 1 interrupt.
Mode 3 is provided to add an additional 8-bit timer/counter, so that the microcontroller has three timers/counters. Mode 3 is only applicable to timer/counter 0. When timer T1 is in mode 3, it is equivalent to TR1-0 and stops counting, while T0 can be used as two timers.
Note: The STC-ISP programming tool comes with a built-in calculation of the initial value of the timing time. You can copy the code according to the mode you choose.
The LED1 indicator light is controlled to flash at intervals of 1 second through the timer 0 interrupt. The physical connection diagram is as follows: D1 is connected to the P2_0 pin. A 12.000MHz clock is used. The interrupt is triggered every 1 millisecond. The interrupt trigger function is counted. When it reaches 1000, it is one second.
#include <REGX52.H>
sbit LED1 = P2^0;
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
LED1 = !LED1;
}
count++;
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void main()
{
Timer0_Init();
while(1)
{
}
}
In this demonstration, the _crol_left shift and _cror_right shift functions in the INTRINS.H library are used. When the KEY1 button is pressed, the LED water light will switch the direction state and flash. Physical connection: K1 is connected to the P0_0 pin, and the eight LED lights are inserted into the P2 pin.
#include <REGX52.H>
#include <INTRINS.H>
sbit KEY1 = P0^0;
sbit KEY2 = P0^1;
unsigned char LEDMode;
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
if(LEDMode == 0)
P2 = _crol_(P2,1);
if(LEDMode == 1)
P2 = _cror_(P2,1);
}
count++;
}
unsigned char Getkey()
{
unsigned char keyNumber = 0;
if(KEY1 == 0)
{
DelayXms(5);
while(KEY1 == 0);
DelayXms(5);
keyNumber = 1;
}
if(KEY2 == 0)
{
DelayXms(5);
while(KEY2 == 0);
DelayXms(5);
keyNumber = 2;
}
return keyNumber;
}
void main()
{
unsigned char keyNum = 0;
P2 = 0xfe;
Timer0_Init();
while(1)
{
keyNum = Getkey();
if(keyNum)
{
if(keyNum == 1)
{
LEDMode++;
if(LEDMode>=2)
{
LEDMode = 0;
}
}
}
}
}
This demo code uses LCD1602 module as display. I won't explain the LCD1602 module in detail. A special chapter will be provided later. If you need LCD1602 library, you can chat with me. Physical connection: Just plug in the LCD1602 module on the board.
#include <REGX52.H>
#include "LCD1602.h"
unsigned char Sec=55,Min=59,Hour;//秒分时
void DelayXms(unsigned int xms) //@12.000MHz
{
unsigned char data i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
ET0 = 1;//打开T0中断
EA = 1;//打开总中断
TR0 = 1; //定时器0开始计时
}
void External0_ISR(void) interrupt 1
{
static unsigned int count = 0;
TL0 = 0x18; //需要手动复原
TH0 = 0xFC; //需要手动复原
// 中断处理代码
if(count == 1000)
{
count = 0;
Sec++;
if(Sec == 60)
{
Sec = 0;
Min++;
if(Min == 60)
{
Min = 0;
Hour++;
if(Hour == 24)
{
Hour = 0;
}
}
}
}
count++;
}
void main()
{
Timer0_Init();
LCD_Init();
LCD_ShowString(1,1,"Time:");
LCD_ShowString(2,1,"00:00:00");
while(1)
{
LCD_ShowNum(2,1,Hour,2);
LCD_ShowNum(2,4,Min,2);
LCD_ShowNum(2,7,Sec,2);
}
}