历史上的今天
今天是:2024年12月24日(星期二)
2021年12月24日 | 51单片机系列——定时器T0、T1怎么用
2021-12-24 来源:eefocus
实例一:方波发生器

源码如下:
main.c
#include sbit Square=P1^5; //设置方波输出引脚P1^5 void main(void){ TMOD=0x02; //配置TMOD:定时器,工作方式2(自动重装初值) TH0=0x06; //方式2,预装值 TL0=0x06; //方式2,计数器 IE=0x82; //配置IE:中断允许/*也可以位操作,写成EA=1,ET0=1*/ TR0=1; //配置TCON:位操作,T0的中断标志位 while(1); //死循环,等待中断 } //这里没有其他中断服务程序,因此没有配置IP中断优先级 void time0_int(void) interrupt 1{ //定时器中断服务程序 Square=!Square; } 结构图如下: 上面是一个很简单的例子,但由此我们可以归纳出定时器的使用方法和步骤: 1、初始化定时器 (1)配置TMOD,TMOD的作用如下 (2)设定THx、TLx的值。需要注意的是除了在工作方式2外。其他的工作方式下,这两个值要在定时器的中断服务函数中重新装入。 (3)设置IP,即中断优先级(不需要的话就不用设置的) (4)开中断:总中断允许和定时器T0/T1的中断允许 (5)打开定时器的中断标志位TRx(直接位操作即可) 这样就完成了定时器的初始化,接下来写一下中断服务程序即可 下面再讲两个实例: 实例二:PWM调直流电机速度 仿真图:图中K1是加速键,K2是减速键 代码如下: //控制直流电机转速 #include #define uint unsigned int sbit Power=P1^0; //启停控制,Power=0电源断开,Power=1电源接通 sbit JiaSu=P1^1; //加速键 sbit JianSu=P1^2; //减速键 unsigned char PWMH; //高电平保持时间(以定时器定时时间的倍数计算) unsigned char PWM; //PWM的整个周期(也已定时器定时时间的倍数计算) unsigned char Counter; //定时器定时时间计数器 void INTT0() interrupt 1{ //每溢出一次来判断一次 Counter++; //计数值加1 if((Counter!=PWMH)&&(Counter==PWM)){//不在PWMH高电平时间,并且一个PWM的周期也到了 Counter=1; //计数值复位 Power=1; //开电源进入下一个PWM的周期,拉高电平 }else if(Counter==PWMH){ //高电平时间结束了,拉低电平关电源不供电 Power=0; } } void main(void){ PWMH=0x04; //设一个高电平的保持时间4/15(暂时定为2倍定时时间) Counter=0x01; //定时时间计数值,设初值为1 PWM=0x15; //一个脉冲周期,暂定15倍定时时间 TMOD=0x02; //定时器0在模式2下工作 TL0=256-200; TH0=256-200;//200us产生一次溢出,即200us为一个定时时间 ET0=1; //开定时器0中断使能 EA=1; //开总中断使能 TR0=1; //开始计时,定时器的中断标志位 while(1){ if(JiaSu==0){ PWMH++; //扫描按键K1 ,加速 while(!JiaSu); //这个很重要,判断开关是否断开 } if(JianSu==0){ PWMH--; //扫描按键K2 ,减速 while(!JianSu); //这个很重要,判断开关是否断开 } } } 这个自己运行一下仿真就知道啦!!! 实例三:PWM控制LED模仿呼吸灯(这个是我从普中上搬下来的,勿喷啦) 代码如下: #include #define uint unsigned int #define uchar unsigned char sbit PWM=P2^1; //定义使用的IO口 bit DIR; //用于改变方向的,1:PWM高电平延长;0:PWM高电平减短 uint count,value,timer1; //count:起到计数(一个缓冲的作用,延时一段时间在让value与timer1比较) timer1:整个PWM的周期 value:起到一个PWM波高低点交替点的作用,与timer1比较:timer1 void Time1Init(){ TMOD|=0x10; //选择定时器1模式,工作方式1,仅用TR1打开启动 TH1=0xFF; TL1=0xFF; //1us ET1=1; //打开定时器1中断允许 EA=1; //开总中断 TR1=1; //打开定时器 } void main(){ Time1Init(); //定时器1初始化 while(1){ if(count>100){ count=0; if(DIR==1){ value++; } if(DIR==0){ value--; } } if(value==1000){ DIR=0; } if(value==0){ DIR=1; } if(timer1>1000) {//PWM周期为1000*1us timer1=0; } if(timer1 }else{ PWM=0; } } } void Time1(void) interrupt 3 { TH1=0xFF; TL1=0xFF; //1us,重装初值 timer1++; count++; } 运行一下,就能看出仿真结果,但我觉得这个仿真的结果不是很好,还不如看一下它示波器的变化。 






史海拾趣
|
罗德与施瓦茨 2009年射频微波测量仪器应用 有奖征文竞赛启事 一等奖1 名;奖励价值6000元的奖品 二等奖 3 名;奖励价值4000元的奖品 三等奖若干名:奖励价值1000元的奖品 为了推动射频微波测试与测量技术的发展,适应客户的测试应用需 ...… 查看全部问答> |
|
随着社会的发展,人们对于居住环境的安全、方便、舒适提出了越来越高的要求,希望回到家即可得到100%的休息与享受,尽可能的减少每天所进行的无用功,而出外时如有非法进入、火灾、液化气泄漏等情况,可自动通知户主并报警。因此,智能家居在这种 ...… 查看全部问答> |
|
evc操作sql server CE时,如何捕捉到错误信息? evc操作sql server CE时,如何捕捉到错误信息? 在VC操作sql server 2000时,我们可以通过: try { ... ... } catch( _com_error &e ) { ... ... } 得到出错的原因,在调试时非常方便,但是evc操作sql server CE时我该如何处理呢?谢谢大 ...… 查看全部问答> |
|
Wince 是否支持大页nand flash?文件格式是dosfs吗? Wince是否支持大页nand flash?文件格式是dosfs吗? Wince支持的Nand的大页模式和小页模式是同一个文件系统吗?… 查看全部问答> |
|
STM8L的LCD控制器怎么使用啊?是不是非要LSE时钟才行啊? 我不想用LSE时钟,我看到手册上说LCD控制器可以使用RTCCLK/2当做时钟输入;也可以直接使用SYSCLK,只需要开启外设时钟的LCD就行。但是我写的程序,COM和SEG咋动都不动一下呢?用示波器看,动都没动,郁闷;下面是几行代码: void LCD_INIT(vo ...… 查看全部问答> |
|
TxMessage.DLC最多是8字节,我一次要发24个。分三次发,发送程序如下TestStatus CAN_Polling(void){ u32 i = 0; u8 m=0; //每次发送的字节数 u8 n=0; ...… 查看全部问答> |




