//首先定时器根据时钟的输出信号每隔一段时间对计数单元进行加1 //当计数单元加1到设定提醒时间就进行中断申请,使程序跳转到中断函数中执行 //1.工作模式寄存器TMOD,不可位寻址 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 //配置上述的每隔一段时间进行加1计数操作 TL0 = 0x66; //设置定时初值 TH0 = 0xFC; //设置定时初值 //2.控制寄存器TCON,可位寻址,可以单独赋值 TF0 = 0;//清除TF0.标志,TF0 = 1时溢出,可以不配置,硬件即可自动配置 TR0 = 1; //定时器0开始计时 //3.中断 //3.1中断允许控制寄存器IE EA = 1;//CPU的总中断允许控制位,EA = 1,CPU开放中断 ET0 = 1;//定时器0中断允许控制寄存器 //3.2中断优先级控制寄存器IP,针对普通的89c52 //stc89c52有四个优先级选择,还需配置寄存器IPH PT0 = 0;//设置中断优先级一.对于几点对于51单片机代码的建议 1.模块化代码 2.熟练运用软件STC-ISP 二.定时器时钟代码(LCD显示) 1.main函数:
#include2.配置定时器函数(解析)#include "Delay.h" #incldue "LCD1602.h" #include "Timer0.h" //unsigned char Sec = 0;//秒 //unsigned char Min = 0;//分 //unsigned char Hour = 0;//时 //unsigned char Day = 0;//天 //验证代码能不能进位 unsigned char Sec = 50; unsigned char Min = 59; unsigned char Hour = 23; unsigned int Day = 363; void LCD_Init(); void LCD_ShowString(unsigned char Line,unsigned char Column,char *String); void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length); void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char); void main() { //初始化 LCD_Init(); Timer0_Init(); //lcd显示 //LCD_ShowString(1,1,"Clock:"); LCD_ShowString(1,1,"Hour:Min:Sec"); LCD_ShowString(1,14,"Day"); while(1) { LCD_ShowNum(2,7,Sec,2); LCD_ShowChar(2,6,':'); LCD_ShowNum(2,4,Min,2); LCD_ShowChar(2,3,':'); LCD_ShowNum(2,1,Hour,2); LCD_ShowNum(2,14,Day,3); } } void Timer0_Rountine() interrupt 1 { static unsigned int T0count; //局部变量,static子函数结束后依然保留占据空间 //每次运行中断都重新赋初值保证不溢出和计数间隔 //重新赋初值 TL0 = 0x66; //设置定时初值,由stc生成 TH0 = 0xFC; //设置定时初值 T0count++;//计数 if(T0count>=1000)//1000*1ms = 1s { T0count = 0; Sec++; if(Sec>=60) { Sec = 0; Min++; if(Min>=60) { Min = 0; Hour++; if(Hour>=24) { Hour = 0; Day++; } } } } }
#include3.定时器配置代码(具体见第三第四概念总结)void Timer0_Init() { //TMOD不可位寻址,所以其必须八位直接赋值 //如果同时使用定时器0和定时器1的时候,会刷新中断配置 //TMOD = 0x01; //模式1,就是M1 = 0,M0 = 1,即0000 0001 //0-65535,每隔1us计数+1,所以需要设置初始值 //16位定时器最大时间间隔 = 2^16 = 65.536ms //TMOD = TMOD&0xF0;//与同1才为1,其余均为0,所以低4位清零,高4位保持不变 //TMOD = TMOD|0x01; //只要有1就是1,同0才为0.所以除了最后一位均不变,最后一位置1 //这样就是高4位依然不变,改变的只是低4位,即定时器0 //TF0 = 0;//TF是溢出标志,表明没有溢出 //TR0 = 1;//定时器0的运行控制位 //设置每次计数时间 //TH0使用8位,TL0使用8位, //虽然我们合在一起成了16位定时器,但是我们写的时候得分开写 //TH0 = 64535/256;//(65535-1000)/256,1000us等于1ms, //TL0 = 64535%256;//为刚好1ms//定时器设置,每隔1ms发起一次中断 //比如64535离计数器溢出差值是1000,所以计时时间是1ms //比如65535/256 = 255,刚好是1111 1111,高八位 //65535%256 = 0,刚好是0000 0000,低八位 //对于以上的/与%有1us的延迟,为什么 //TL0 = 64535%256,计算出来是0x17,stc配置出来时0x18,相差1us //因为65535并没有溢出,离计数器溢出差值应该是1001us TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x66; //设置定时初值 TH0 = 0xFC; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 //中断 EA = 1;//CPU的总中断允许控制位,EA = 1,CPU开放中断 ET0 = 1;//定时器0中断允许控制寄存器 PT0 = 0;//设置中断优先级 }
89c51单片机内部有两个16位的定时/计数器,即定时器T0和定时器T1,单片机的定时功能其实就是通过计数来实现的,当单片机每一个机器周期产生一个脉冲时,计数器就加一。
一个16位的定时器,它所能计数的范围是0~65535,如果单片机采用的是12M的晶振,那么定时器单次最长的时间为65535*((1/12)*12),因为一个一个机器周期等于12个振荡周期,那么定时器加一所用的时间是1/12M*12是1us,也就是一个12MHz晶振的51单片机单次最长时间约为65ms.
即普通的51单片机所能配置中断的最长时间是65ms,正常情况下,0-65535,每隔1us计数+1,所以需要配置定时初值。
定时器模式可见下图:
具体代码由stc-isp生成:
//首先定时器根据时钟的输出信号每隔一段时间对计数单元进行加1 //当计数单元加1到设定提醒时间就进行中断申请,使程序跳转到中断函数中执行 //1.工作模式寄存器TMOD TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x66; //设置定时初值 TH0 = 0xFC; //设置定时初值 //2.控制寄存器TCON TF0 = 0;//清除TF0.标志,TF0 = 1时溢出,可以不配置,硬件即可自动配置 TR0 = 1; //定时器0开始计时 //3.中断 //3.1中断允许控制寄存器IE EA = 1;//CPU的总中断允许控制位,EA = 1,CPU开放中断 ET0 = 1;//定时器0中断允许控制寄存器 //3.2中断优先级控制寄存器IP,针对普通的89c52 //stc89c52有四个优先级选择,还需配置寄存器IPH PT0 = 0;//设置中断优先级三.中断
- 什么是中断:
5.中断结构 6.中断请求标志位 7.中断触发 8.中断寄存器 9.中断允许寄存器 10.中断优先级控制寄存器 11.中断优先级 四.定时器 1.定时器/计数器0/1
89c51单片机内部有两个16位的定时/计数器,即定时器T0和定时器T1,单片机的定时功能其实就是通过计数来实现的,当单片机每一个机器周期产生一个脉冲时,计数器就加一。
如,一个16位的定时器,它所能计数的范围是0~65535,如果单片机采用的是12M的晶振,那么定时器单次最长的时间为65535*((1/12)*12),因为一个一个机器周期等于12个振荡周期,那么定时器加一所用的时间是1/12M*12是1us,也就是一个12MHz晶振的51单片机单次最长时间约为65ms.
2.定时器工作模式 3.定时器/计数器工作模式寄存器TMOD当GATE = 1开门,定时器开启与关闭由外部与内部一起控制,对于定时器1来说,GATE = 1,当INT1引脚为高且TR1 = 1时才开启定时器。
当C/T位为1时工作在定时器模式,当M1与M0取值不同代表不同的计数模式,当M1 = 0,M0=1是16位定时器,最多可以存放2^16=65536个计数值,51单片机每计数一个值的时间是一个机器周期,也就是12个时钟周期,T = 12t = 12*(1/12000000)= 1us,所以可以知道最大的计数时间为65.536ms.
M1=1,M0=0时,是一个8位具有重载初值功能的定时器,自动重载初值就是在计数器里面的值计满后,单片机会产生一个溢出中断,自动将计数值清0,因此每次在中断服务程中都需要进行重新赋计数值,而这种模式就省去了重新幅值这一步,由单片机自动进行赋值。



