在STC15W4K56S4单片机GPIO口配置的基础上学会单片机的可编程定时/计数器的使用,实现LED灯的闪烁控制,LED灯闪烁间隔为0.2秒。
知识引入
1.单片机定时方法
(1)软件定时
让CPU循环执行一段程序,通过选择指令和安排循环次数以实现软件定时。软件定时完全占用CPU,增加了CPU开销,降低了CPU工作效率,因此软件的定时时间不宜过长。仅适用于CPU较空闲的程序中使用。
(2)硬件定时
硬件定时的特点是定时功能全部由硬件电路(例如,采用555时基电路)完成,不占用CPU时间,但需要改变电路的参数调节定时时间,在使用上不够方便,同时会增加硬件成本。
(3)可编程定时器定时
可编程定时器的定时值及定时范围很容易通过软件来确定和修改。下文任务实现中所应用到的STC15W4k56S4单片机内部有5个16位的定时/计数器(T0、T1、T2、T3、T4),通过对系统时钟或外部输入信号进行计数控制,可以方便地用于定时控制,或用于分频器和用于事件记录。
2.相关寄存器设置
对定时器/计时器T0和T1,用他们在特殊功能寄存器TMOD中对应的控制位 C/T 来选择T0或者T1为定时器还是计数器,对于定时器/计时器T2,用特殊功能寄存器AUXR中的控制位T2_C/T来选择T2为定时器还是计数器,对于定时器/计时器T3,用特殊功能寄存器T4T3M中控制位T3_C/T来选择T3为定时器还是计数器,对于定时器/计时器T4,用特殊功能寄存器T4T3M中控制位T4_C/T来选择T3为定时器还是计数器。
定时器/计数器的核心部件是一个加法计数器,其本质是对脉冲进行计数,只是计数脉冲来源不同。如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每1个时钟得到一个计数脉冲,计数值加1定时器/计数器的核心部件是一个加法计数器,其本质是对脉冲进行计数。只是计数脉冲来源不同:如果计数脉冲来自系统时钟,则为定时方式,此时定时器/计数器每12个时钟或者每1个时钟得到一个计数脉冲,计数值加1;如果计数脉冲来自单片机外部引脚(T0为P3.4,T1为P3.5,T2为P3.1,T3为P0.7,T4为P0.5),则为计数方式,每来一个脉冲加1。
符号 | 描述 | 地址 | 位地址及其符号 MSB LSB |
复位值 |
TCON | 定时器控制寄存器 | 88H | EA | ELVD | EADC | ES | ET1 | EX1 | ET0 | EX0 | 0000 0000B |
TMOD | 工作方式寄存器 | 89H | GATE | C/T| M1 | M0 | GATE | C/T | M1 | M0 | 0000 0000B |
TL0 | 定时器0低位 | 8AH | 0000 0000B | |
TL1 | 定时器1低位 | 8BH | 0000 0000B | |
TH0 | 定时器0高位 | 8CH | 0000 0000B | |
TH1 | 定时器1高位 | 8DH | 0000 0000B | |
IE | 中断允许控制 | A8H | EA | ELVD | EADC | ES | ET1 | EX1 | ET0 | EX0 | 0000 0000B |
IP | 中断优先级控制 | B8H | PPCA | PLVD | PADC | PS | PT1 | PX1 | PT0 | PX0 | 0000 0000B |
T2H | 定时器2高8位寄存器 | D6H | 0000 0000B | |
T2L | 定时器2低8位寄存器 | D7H | 0000 0000B | |
AUXR | 辅助寄存器 | 8EH | T0x12|T1x12|UART_M0x6|T2R|T2_C/T|T2x12 |EXTRAM|S1ST2 |
0000 0001B |
INT_CLKO AUXR2 |
外部中断允许和时钟输出寄存器 | 8FH | -|EX4|EX3|EX2|MCKO_S2|T2CLKO|T1CLKO|T0CLKO | x000 0000B |
T4T3M | T3和T4的控制寄存器 | D1H | T4R|T4_C/T|T4x12|T4CKLO|T3R|T3_C/T|T3x12|T3CLKO | 0000 0000B |
T4H | 定时器4高8位寄存器 | D2H | 0000 0000B | |
T4L | 定时器4低8位寄存器 | D3H | 0000 0000B | |
T3H | 定时器3高8位寄存器 | D4H | 0000 0000B | |
T3L | 定时器3低8位寄存器 | D5H | 0000 0000B | |
IE2 | 中断只能寄存器 | AFH | - | ET4 | ET3 | ES4 | ES3 | ET2 | ESPI | ES2 | x000 0000B |
符号 | 描述 | 地址 | 位地址及其符号 MSB LSB |
复位值 |
TMOD | 工作方式寄存器 | 89H | GATE | C/T| M1 | M0 | GATE | C/T | M1 | M0 | 0000 0000B |
TCON | 定时器控制寄存器 | 88H | EA | ELVD | EADC | ES | ET1 | EX1 | ET0 | EX0 | 0000 0000B |
AUXR | 辅助寄存器 | 8EH | T0x12|T1x12|UART_M0x6|T2R|T2_C/T|T2x12 |EXTRAM|S1ST2 |
0000 0001B |
M1 M0 | 工作方式 | 功能说明 |
0 0 | 方式0 | 自动重装初始值的16位定时器/计数器(推荐) |
0 1 | 方式1 | 16位定时器/计数器 |
1 0 | 方式2 | 自动重装初始值的8位定时/计数器 |
1 1 | 方式3 | 定时器0:分成两个8位定时器/计数器;定时器1:停止计数 |
//功能:实现LED灯时间间隔0.2秒闪烁,每1ms进一次中断 #include #include #define uchar unsigned char #define uint unsigned int #define FOSC 11059200 //时钟11.0592MHz #define T1MS (65536-FOSC/12/1000) //12T模式,1ms进一次中断 //进一次中断的初值 sbit LED= P2^2; //定义LED的引脚位置 uint count=0; //定义全局变量,不用赋值,默认为0 void Delay500ms() //晶振11.0592MHz 延迟0.5S { unsigned char i, j, k; _nop_(); _nop_(); i = 22; j = 3; k = 227; do { do { while (--k); } while (--j); } while (--i); } void init() { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = T1MS; //设置定时初值 TH0 = T1MS>>8; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //使定时器0工作 ET0 = 1; //开启定时器0中断开关 EA = 1; //开启中断总开关 } void main () { init(); P2M1 &= ~(3<<2); P2M0 |= (3<<2); while (1); } Void LED0( ) interrupt 1 //定时器0中断服务程序 { count++; if(count==200) { LED=!LED; //每进入一次中断程序,count加1 count=0; } } |