Study Notes | Timer | STC Interrupt | Timer Time Calculation | STC32G Microcontroller Video Development Tutorial (Brother Chong) | Episode 11: The Function and Significance of Timer

1. The function and significance of timer

What is a timer: A piece of code for a timer-and-non-online
class:

while(1)

{
    TimeCount++;
    delay_ms(1);
}

TimeCount++ and then a delay of 1 millisecond, every time it runs 1ms, the variable will increase by one.
How many milliseconds the system has been running.
The actual code used is as follows:

while(1)
{
    TimeCount++;
    delay_ms(1);
    if (KEY1 == 0)
		{
			delay_ms(10);
			if (KEY1 == 0)
			{
				while(KEY1 == 0);
            }
        }
}

When judging whether the button is pressed or not, we wait for the button to be released, and there is a while loop.
If you don't let go, you will always die in this line. Therefore, during the time period of pressing, TimeCount++ is not being executed, and the variable will not move.
So when a while function like this is executed in a continuous loop, is there a way to make this variable automatically increase by one every 1ms and not be affected by the while loop? Introducing: the concept of
interruption.
If an interruption does not occur, it will continue to execute. Main program (main function). However, if an interrupt occurs, the interrupt processing function will first be processed
. After processing, it will return from the interrupt and continue to execute the main program (a personal task that was not completed before).
Insert image description here

timer interrupt

The interrupt generated after a certain time is scheduled, that is, the timer interrupt.
Main program: You are endorsing a book
Interruption: Mom asks you to see if the soup in the pot is dry after five minutes, an example of a timer interruption.

Timer is a general term for timers and counters.

1) When set as a timer, hardware timing can be realized, or the program can complete an operation at a fixed time;
2) When set as a counter, pulses can be counted;
3) It can replace long delays and improve the operation of the CPU. Efficiency and processing speed, able to respond to an event in a timely manner.

2. STC32G MCU timer usage principle

T0 implements 1ms interrupt
. Original manual:
Insert image description here

定时器/计数器(24位定时器,8位预分频14+16位自动重装载)
STC32G系列单片机内部设置了5个24位定时器/计数器(8位预分频+16位计数)。5个16位定时器T0、T1、T2、T3和T4都具有计数方式和定时方式两种工作方式。对定时器/计数器TO和T1,用它们在特殊功能寄存器TMOD中相对应的控制位CT来选择TO或T1为定时器还是计数器。对定时器/计数器T2,用特殊功能寄存器AUXR中的控制位T2_C/T来选择T2为定时器还是计数器。对定时器/计数器T3,用特殊功能寄存器T4T3M中的控制位T3_C/T来选择T3为定时器还是计数器。对定时器/计数器
T4,用特殊功能寄存器T4T3M中的控制位T4_C/T来选择T4为定时器还是计数器。定时器/计数器的核心部件是一个加法计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统
时钟,则为定时方式,此时定时器/计数器每12个时钟或者每1个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚,则为计数方式,每来一个脉冲加1。
当定时器/计数器TO、T1及T2工作在定时模式时,特殊功能寄存器AUXR中的TOx12、T1x12和T2x12分别决定是系统时钟/12还是系统时钟/1(不分频〉后让TO、T1和T2进行计数。当定时器/计数器T3和T4工作在定时模式时,特殊功能寄存器T4T3M中的T3x12和T4x12分别决定是系统时钟/12还是系统时钟/1(不分频〉后让T3和T4进行计数。当定时器/计数器工作在计数模式时,对外部脉冲计数不分频。
定时器/计数器0有4种工作模式:模式0(16位自动重装载模式)﹐模式1(16位不可重装载模式),模式2(8位自动重装模式),模式3(不可屏蔽中断的16位自动重装载模式)。定时器/计数器1除模式3外,其他工作模式与定时器/计数器О相同。T1在模式3时无效,停止计数。定时器T2的工作模式固定为16位自动重装载模式。T2可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。定时器3、定时器4与定时器T2一样,它们的工作模式固定为16位自动重装载模式。T3/T4可以当定时器使用,也可以当串口的波特率发生器和可编程时钟输出。

2.1 First set the function to timer/counter (essentially they are adding counters)

The STC32G series microcontroller is equipped with five 24-bit timers/counters (8-bit prescaler + 16-bit counting). The five 16-bit timers T0, T1, T2, T3 and T4 all have two working modes: counting mode and timing mode. For timers/counters TO and T1, use their corresponding control bits CT in the special function register TMOD to select whether TO or T1 is a timer or a counter. For timer/counter T2, use the control bit T2_C/T in the special function register AUXR to select whether T2 is a timer or a counter. For timer/counter T3, use the control bit T3_C/T in the special function register T4T3M to select whether T3 is a timer or a counter. For timer/counter T4, use the control bit T4_C/T in the special function register T4T3M to select whether T4 is a timer or a counter. The core component of the timer/counter is an adding counter, which essentially counts pulses. Only the source of the counting pulses is different: if the counting pulses come from the system clock, it is the timing mode. At this time, the timer/counter gets a counting pulse every 12 clocks or every 1 clock, and the counting value increases by 1; if the counting pulses come from the external driver of the microcontroller, pin, it is a counting mode, adding 1 for each pulse.
This lesson mainly uses T0, that is, timer 0, to implement the function. This T is an abbreviation for timing.
Take the timer 0/1 mode register (TMOD) as an example:
T0 C/T: Controls timer 0 to be used as a timer or counter. If cleared to 0, it will be used as a timer (counting the internal system clock). If set to 1, it will be used as a timer.
Counter (counts external pulses on pin TO/P3.4).
Insert image description here

2.2. In timer mode, set no frequency division or frequency division by 12:

Insert image description here

When the timers/counters TO, T1 and T2 work in the timing mode, TOx12, T1x12 and T2x12 in the special function register AUXR respectively determine whether the system clock/12 or the system clock/1 (without frequency division), then let TO, T1 and T2 counts. When timers/counters T3 and T4 work in timing mode, T3x12 and T4x12 in the special function register T4T3M respectively determine whether the system clock/12 or the system clock/1 (no frequency division) is used to allow T3 and T4 to count. When the timer/counter works in counting mode, the external pulse count is not divided.
Timing mode, at this time, the timer/counter gets a count pulse every 12 clocks or every 1 clock, and the count value is increased by 1; the count difference is 12 times.
Take a look at the auxiliary register (AUXR)
Insert image description here
Insert image description here

Use the control bit T2_C/T in the special function register AUXR to select whether T2 is a timer or a counter.
The default highest bit is 0:
Insert image description here

So the default frequency is divided by 12.

Tips: choose no frequency division or 12 frequency division

Look at the specific timing time. If the timing time is enough, then use 12 frequency divider. If there is no frequency division, the equivalent timing time will be shorter, but the accuracy will be better.

2.3, the working mode of the timer

Insert image description here

16-bit auto-reload mode: The count can count from 0 to 65535, 16-bit is 65535, 2^16-1=65535.
When the scheduled time is up, the system will reinstall the scheduled time you wrote into it. There is no automatic reload mode, you need to manually set the timing time yourself.
8-bit auto-reload: counts from 0 to 255, which is its maximum value.
16-bit auto-reload for non-maskable interrupts: the same as mode 0, non-maskable interrupts, the highest interrupt priority, higher than all other interrupts. level, and cannot be turned off. It can be used as the system tick timer of the operating system or the system monitoring timer.
Once this interrupt is enabled, it has the highest priority, and no other interrupts can interrupt it. Later, there are serial port interrupts, external interrupts, etc.
Today I mainly do the setting and testing of the 16-bit automatic reload mode.
Insert image description here

2.4 TCON register setting

TF0 and TR0
TF0:T0 overflow interrupt flag, you must manually write 1 to it, if you don’t write 1, you can’t open it, that is, you can’t count. After T0 is allowed to count, it starts counting by 1 from the initial value. When an overflow occurs, the hardware sets TFO to "1" and requests an
interrupt to the CPU. It will be cleared by the hardware until the CPU responds to the interrupt (it can also be cleared by the query software). cleared to 0).
TR0: The operation control bit of timer T0. This bit is set and cleared by software, of course it doesn't matter if it is not cleared to 0. When GATE (TMOD.3)=0, TRO=1 allows TO to start
counting, and TRO=0 disables TO counting. When GATE(TMOD.3)=1, TRO=1 and INTO input is high level, TO counting is allowed, and TO counting is prohibited when TRO=0.

2.5 Interrupt enable register (interrupt enable bit)

Insert image description here
Insert image description here

Looking back at our previous lesson, we want P60 to output a low level. We can write it like this:
Method 1: P60 = 0;
Method 2: P6 = 0XFE; //Of course it is best to write P6 &= 0XFE;
Insert image description here

For example, if we want to set ET0 equal to 1: we can directly write ET0 equal to 1 (this is more convenient and will not affect other bits)
or we can write IE=0X02

3. Simple application of timer

Insert image description here
When c/T=0, the multiplexer is connected to the frequency division output of the system clock, TO0 counts the internal system clock, and TO works in timing mode. When
C/T=1, the multi-way switch is connected to the external pulse input P3.4/T0, that is, TO works in the counting mode.
Timer 0 of the STC microcontroller has two counting rates: one is the 12T mode, which adds 1 every 12 clocks, the same as the traditional 8051 microcontroller; the other is the 1T mode, which adds 1 every clock, and the speed is the same as that of the traditional 8051 microcontroller. 12 times. The rate of TO is determined by TOx12 in the special function register AUXR. If TOx12=0, TO works in 12T mode; if TOx12=1, T0 works in 1T mode. Timer 0 has two hidden registers RL_THO and RL_TLO
. RL_THO shares the same address with THO, and RL_TLO shares the same address with TLO. When TRO=0, that is, the timer/counter О is disabled, the content written to TLO will be written to RL_TLO at the same time, and the content written to THO will also be written to RL_THO at the same time. When TRO=1, that is, the timer/counter О is allowed to work, the content written to TLO is not actually written to the current register TLO0, but to the hidden register RL_TLO. The content written to THO is actually written. Instead of writing into the current register TH0, write into the hidden register RL_THO, which can cleverly implement a 16-bit reload timer. When reading the content of THO and TLO, the content read is the content of THO and TLO, not the content of RL_THO and RL_TLO.
When timer О works in mode 0 (TMOD[1:0][M1.MO]=00B), the overflow of [THO, TLO] not only sets TFO, but also automatically reloads the contents of [RL_THO, RL_TLO] Enter [THO,TLO].
When TOCLKO/INT_CLKO.0=1, the P3.5/T1 pin is configured as the clock output TOCLKO of timer 0. The output clock frequency is TO overflow rate/2.
If C/T=0, the timer/counter TO counts the internal system clock, then:
The output clock frequency when TO works in 1T mode (AUXR.7/TOx12=1) = (SYsclk) (TMOPS+1) (65536-[RL_THO, RL_TLO]) 2To works in 12T mode (AUXR.7/TOx12=0 ) when the output clock frequency is -(SYsck)(TMOPS+1)/12/(65536-[RL_THO,RL_TLO])2 If C/T=1, the timer/counter TO is for external pulse input (P3.4/ TO) counting, then:
output clock frequency = (To_Pin_CLK)/(65536-[RL_THO,RL_TLO])/2
according to manual 14.5 Sample program
14.5.1 Timer 0 (mode 0-16-bit automatic reload), used for timing

TMOD = 0x00;//模式0,16位自动重载模式
TL0=0x66;//65536-11.0592M/12/1000
TH0 = 0xfe;
TR0= 1;//启动定时器
ET0= 1;//使能定时器中断
EA=1;

TMOD = 0x00 According to the manual, execution settings:
1. 16-bit auto-reload mode;
2. T0_C/T: Control timer 0 to be used as a timer or counter. Clear 0 to use it as a timer (for the internal system clock) Counting)
3. TO_GATE: Control timer 0. When GATE=0 (TMOD.3), if TRO=1, the timer counts.

Timing:

Related formulas:
Insert image description here

TL0 = 0x66;//65536-11.0592M/12/1000
TH0 = 0xfc;
0XFC66 corresponds to 64614, 65536-64614=922,922 12 (0+1)/(11.0592*1000000)=0.0010004340277778s
About 1ms.

The goal of this section: T0 implements an interrupt of 1 millisecond

Use the code from the previous lesson as a template, compile and run, and you will find a small bug. Every time you press the key, the digital tube will flash.
You can use a timer to fix this flashing problem.
First open the stc manual, section 14.5 routine:
Insert image description here

Right-click to jump to the definition of sys_init(), and you can see that the previous definitions of TMOD already exist.
Directly see our most important TMOD, the general initialization code is placed before EA.
The time given in the manual is 11.0592MHZ, which needs to be changed to 24MHZ:
Insert image description here

According to the aforementioned formula: 24000000*0.001/12/(0+1)=2000, change to programmer mode: 65536-2000=0XF830, then: TL0 = 0X30; //Calculate the 1ms timing time TH0 = 0XF8
under the 24MB clock
;
Insert image description here

Turn on the timer and enable timer interrupts.

STC interrupt list

Insert image description here
Insert image description here
Insert image description here
Add a timer interrupt function. The function name is written according to the regulations and can be customized, but the keyword interrupt cannot be missing, indicating the interrupt number:
void TM0_Isr() interrupt 1 //Timer 0 corresponds to the interrupt number 1, automatically find the interrupt number, and go implement.
Migrate the required functions to the interrupt. Here you only need to add the digital tube refresh function SEG_Fre() to it, disable the delay statement in SEG_Fre(), and add the digital tube refresh code:

void TM0_Isr() interrupt 1 //1ms进来执行一次,无需其他延时,重复赋值
{
	SEG_Fre();		//数码管刷新1ms执行一次

	if( RUN_State==1 ) //开始运行后,每隔1ms加1,需要移进来
		{
			TimCount++; //每ms加1,按键操作均不影响数码管刷新
			Show_Tab[4] = TimCount/10000%10;
			Show_Tab[5] = TimCount/1000%10+10;
			Show_Tab[6] = TimCount/100%10;
			Show_Tab[7] = TimCount/10%10;		//取10位
		}
}

Compile and download, and found a bug. When the button is pressed and not released, there is a problem with the digital tube display. There must be a problem with the button function. Find the button part code: delete the refresh code of the button part. This part is refreshed by the interrupt function every time
. ms is executed automatically without repeated refresh.
Run it again, the digital tube does not flicker, and the experiment is successful.

4. How to quickly use the timer

STC-ISP has a dedicated timer time calculation tab:
Insert image description here

After entering the parameters, produce C code:

void Timer0_Isr(void) interrupt 1
{
}

void Timer0_Init(void)		//1000微秒@24.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x30;				//设置定时初始值
	TH0 = 0xF8;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
}

Put the initialization function Timer0_Init() before the main program, and modify the interrupt name to be consistent:

The less frequent the interruption, the better! !

Summarize

1. Understand timers and timer interrupts
2. Learn to analyze when to use timers
3. Familiar with tools and be able to use timers quickly

Homework:

1. The homework for Lesson 10 is to make a simple clock, and then change the clock into a timer driver.
2. On the basis of the above, a button is added. Press once to pause time, press once to continue running, and press once again to pause!

Guess you like

Origin blog.csdn.net/Medlar_CN/article/details/132712561