51单片机定时器的原理与使用(二)

发布者:WiseThinker最新更新时间:2018-05-06 来源: eefocus关键字:51单片机  定时器 手机看文章 扫描二维码
随时随地手机看文章

承接上一节51单片机定时器的原理与使用,这节我们继续讲述怎么用定时器做一个电子钟,PWM脉冲和测电阻。先从实验三讲起吧!

实验三、定时器测电阻

测量如下图Rx的电阻并显示在数码管上。


测量思路为:
1、电容C1放电,P2.5与P2.6设置为输入模式,P2.7设置为推挽输出且为输出低电平0。这时候C1通过R1和P2.7放电。
2、切断C1的放电回路,将P2.7设为输入模式。
3、P2.5设为推挽输出,并且输出高电平5V,即P2.5的高电平通过Rk对C1充电。同时打开定时器Tx。
4、MCU不断读P2.7的状态,当P2.7为高,则关闭定时器。同时P2.5恢复输入模式。这个过程中定时器记录了P2.5通过Rk对C1充电直到P2.7为高电平的时间t1。
5、将P2.7设为推挽输出并输出0,即对C1再次放电。放电完成后,将P2.7恢复为输入状态。
6、P2.6设为推挽输出,并且输出高电平5V,即P2.6的高电平通过Rx对C1充电。同时打开定时器Tx。MCU不断读P2.7的状态,当P2.7为高,则关闭定时器。这个过程中定时器记录了P2.6通过Rx对C1充电直到P2.7为高电平的时间t2。
Rk/Rx = t1/t2 即 Rx = t2*Rk/t1
直接上代码:


  1. main.c  

  2. #include "reg51.h"  

  3.   

  4. unsigned int count;  

  5. extern void load_smg();  

  6. extern void res_test();  

  7. extern  void delay(unsigned int x);  

  8.   

  9. void Timer1_Init()  

  10. {  

  11.     TMOD|=0x10;  

  12.     TH1=64614/256;  

  13.     TL1=64614%256;  

  14.     TR1=1;  

  15. }  

  16.   

  17. void Isr_Init()  

  18. {  

  19.     EA=1;  

  20.     ET1=1;  

  21.     ET0=1;  

  22. }  

  23.   

  24. void Timer0_Init()  

  25. {  

  26.     TMOD|=0x01;  

  27.     TH0=0;  

  28.     TL0=0;  

  29.     TR0=0;  

  30. }  

  31.   

  32. void TF1_isr() interrupt 3      //1ms  

  33. {  

  34.     TH1=64614/256;  

  35.     TL1=64614%256;  

  36.     load_smg();  

  37.   

  38. }  

  39. void main()  

  40. {  

  41.     Timer0_Init();  

  42.     Timer1_Init();  

  43.     Isr_Init();  

  44.       

  45.     while(1)  

  46.     {  

  47.        res_test();  

  48.        delay(65000);  

  49.        delay(65000);  

  50.     }  

  51. }  

  52.   

  53. smg.c  

  54.  #include "reg51.h"   

  55.   //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

  56.  code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

  57.  char smgbuf[4]={1,2,3,4}; //从RAM的smgbuf这个地址开始连续存放4个数,并且每个数占一个单元。  

  58.  extern unsigned int count; //外部申明,表示并不在这里申明  

  59.   

  60. void fill_smgbuf() //向LED缓冲区填充数据  

  61. {  

  62.     smgbuf[0]=count/1000;  //千位  

  63.     smgbuf[1]=(count%1000)/100;  //百位  

  64.     smgbuf[2]=((count%1000)%100)/10;   //十位  

  65.     smgbuf[3]=((count%1000)%100)%10;   //个位  

  66. }  

  67.   

  68. void load_smg()   //将数码管显示缓冲区的数据,显示到数码管上  

  69.  {  

  70.     static char i;  

  71.     fill_smgbuf();  

  72.     i++;  

  73.     if(i>=4)  

  74.     {  

  75.         i=0;  

  76.     }  

  77.     P0=0xFF;   //消除上一个循环的影子  

  78.     P2 = ~(1<

  79.     P0 = seg[smgbuf[i]];      

  80.   

  81.  }  

  82. resistor.c  

  83. #include "reg51.h"  

  84. sfr P2M1=0x95; //因为reg51.h里面没有,所以自己定义  

  85. sfr P2M0=0x94;  

  86. float t1, t2;  

  87. float Rk=100; //K  

  88. float Rx;  

  89. extern unsigned int count;  

  90. sbit P2_5=P2^5;  

  91. sbit P2_6=P2^6;  

  92. sbit P2_7=P2^7;  

  93.   

  94.  void delay(unsigned int x)  

  95.  {  

  96.     while(x)     

  97.     {  

  98.         x--;  

  99.     }     

  100.  }  

  101.   

  102. void p25_ppout() //将P2.5配置成推挽输出  

  103. {  

  104.     P2M1&=~(1<<5);  

  105.     P2M0|=(1<<5);  

  106. }  

  107.   

  108. void p25_odin() //将P2.5配置成仅输入高阻  

  109. {  

  110.     P2M1|=(1<<5);  

  111.     P2M0&=~(1<<5);  

  112. }  

  113.   

  114. void p26_ppout() //将P2.6配置成推挽输出  

  115. {  

  116.     P2M1&=~(1<<6);  

  117.     P2M0|=(1<<6);  

  118. }  

  119.   

  120. void p26_odin() //将P2.6配置成仅输入高阻  

  121. {  

  122.     P2M1|=(1<<6);  

  123.     P2M0&=~(1<<6);  

  124. }  

  125.   

  126. void p27_ppout() //将P2.7配置成推挽输出  

  127. {  

  128.     P2M1&=~(1<<7);  

  129.     P2M0|=(1<<7);  

  130. }  

  131.   

  132. void p27_odin() //将P2.7配置成仅输入高阻  

  133. {  

  134.     P2M1|=(1<<7);  

  135.     P2M0&=~(1<<7);  

  136. }  

  137.   

  138. void res_test()  

  139. {  

  140.     p25_odin(); p26_odin(); p27_ppout(); P2_7=0;  //C1放电  

  141.     delay(65000);  

  142.     delay(65000);  

  143.     p27_odin(); //放电完成  

  144.   

  145.     p25_ppout(); P2_5=1;//P2.5通过Rk对电容C1充电  

  146.     TR0=1;      //打开定时器0  

  147.     while(P2_7==0);//等待充电到P2.7口为高电平  

  148.     TR0=0;       //关闭定时器0  

  149.     p25_odin();  

  150.   

  151.     t1=TH0*256+TL0;  

  152.     TH0=0;  

  153.     TL0=0;  

  154.   

  155.     p25_odin(); p26_odin(); p27_ppout();P2_7=0;  //C1放电  

  156.     delay(65000);  

  157.     delay(65000);  

  158.     p27_odin(); //放电完成  

  159.   

  160.     p26_ppout();P2_6=1;  

  161.     TR0=1;      //打开定时器0  

  162.     while(P2_7==0);//等待充电到P2.7口为高电平  

  163.     TR0=0;       //关闭定时器0  

  164.     p26_odin();  

  165.   

  166.     t2=TH0*256+TL0;  

  167.   

  168.     Rx=t2*Rk/t1;  

  169.     count = (unsigned int) Rx;  

  170. }  


实验一、电子钟

main.c文件


  1. #include "reg51.h"  

  2. /*实时时钟 RTC*/  

  3. char RTC[3] = {12,34,56};  

  4. extern void load_smg();  

  5. unsigned int ms1;  

  6.   

  7. void Timer1_Init()  

  8. {  

  9.     TMOD|=0x10;  

  10.     TH1=64614/256;  

  11.     TL1=64614%256;  

  12.     TR1=1;  

  13. }  

  14.   

  15. void Isr_Init()  

  16. {  

  17.     EA=1;  

  18.     ET1=1;  

  19. }  

  20. void Run_clock()  

  21. {  

  22.     RTC[2]++;  

  23.     if(RTC[2]>=60)  

  24.     {  

  25.         RTC[2]=0;  

  26.         RTC[1]++;  

  27.         if(RTC[1]>=60)  

  28.         {  

  29.             RTC[1]=0;  

  30.             RTC[0]++;  

  31.             if(RTC[0]>=24)  

  32.             {  

  33.                 RTC[0]=0;  

  34.                       

  35.             }     

  36.         }  

  37.     }  

  38. }  

  39. void TF1_isr() interrupt 3      //1ms  

  40. {  

  41.     static int ms;  

  42.     TH1=64614/256;  

  43.     TL1=64614%256;  

  44.     ms++;  

  45.     ms1++;  

  46.     if(ms1>=1000)  

  47.     {  

  48.         ms1=0;  

  49.     }  

  50.     if(ms>=1000)   //1 sec  

  51.     {  

  52.         ms=0;  

  53.         Run_clock();      

  54.           

  55.     }  

  56.     load_smg();  

  57.   

  58. }  

  59. void main()  

  60. {  

  61.     Timer1_Init();  

  62.     Isr_Init();  

  63.     while(1)  

  64.     {  

  65.   

  66.     }  

  67. }  

smg.c文件


  1.  #include "reg51.h"   

  2.   //char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

  3.  code char seg[10]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};  

  4.  char smgbuf[4]={1,2,3,4}; //从RAM的smgbuf这个地址开始连续存放4个数,并且每个数占一个单元。  

  5. // extern unsigned int count;   //外部申明,表示并不在这里申明  

  6.  extern char RTC[3];  

  7.  extern void delay(unsigned int x);  

  8.  extern unsigned int ms1;  

  9.   

  10. void fill_smgbuf() //向LED缓冲区填充数据  

  11. {  

  12.     smgbuf[0]=RTC[1]/10;  //分钟十位  

  13.     smgbuf[1]=RTC[1]%10;  //分钟个位  

  14.     smgbuf[2]=RTC[2]/10;   //秒钟十位  

  15.     smgbuf[3]=RTC[2]%10;   //秒钟个位  

  16. }  

  17.   

  18. void load_smg()   //将数码管显示缓冲区的数据,显示到数码管上  

  19.  {  

  20.     static char i;  

  21.     fill_smgbuf();  

  22.   

  23.     for(i=0;i<4;i++)   

  24.     {  

  25.         P0=0xFF;   //消除上一个循环的影子  

  26.         if(ms1<500)  

  27.         {  

  28.            P0 = seg[smgbuf[i]]&0x7F;  

  29.         }  

  30.         else  

  31.         {  

  32.            //P0=0xff;   //整体闪烁  

  33.            P0 = seg[smgbuf[i]];  //实现分钟与秒钟之间的 :闪烁  

  34.         }  

  35.           

  36.         P2 = ~(1<

  37.         delay(200);  

  38.     }   

  39.  }  

void delay(unsigned int x)


  1. {  

  2.    while(x--);  

  3. }  


  1. 实验二、产生一个周期周20ms,脉宽1-19ms可变的PWM波,脉宽可以用按键选择,输出的PWM波去点亮一个led灯,并用示波器观察效果。  


main.c


  1. #include "reg51.h"  

  2. /*用定时器1产生周期为20ms,脉宽为1-19ms*/  

  3. sbit out=P1^0; //PWM output pin  

  4. unsigned int ms;  

  5. unsigned int pwm=10;  

  6. extern void key3();  

  7.   

  8. void Timer1_Init()  

  9. {  

  10.     TMOD|=0x10;  

  11.     TH1=64614/256;  

  12.     TL1=64614%256;  

  13.     TR1=1;  

  14. }  

  15.   

  16. void Isr_Init()  

  17. {  

  18.     EA=1;  

  19.     ET1=1;  

  20. }  

  21.   

  22. void TF1_isr() interrupt 3      //1ms  

  23. {  

  24.     TH1=64614/256;  

  25.     TL1=64614%256;  

  26.     ms++;  

  27.     if(ms>=20)  

  28.     {  

  29.         ms=0;  

  30.     }  

  31.     //...ms=0-19  

  32.     if(ms

  33.     {  

  34.         out=1;  

  35.     }  

  36.     else  

  37.     {  

  38.         out=0;  

  39.     }  

  40. }  

  41. void main()  

  42. {  

  43.     Timer1_Init();  

  44.     Isr_Init();  

  45.     while(1)  

  46.     {  

  47.   

  48.         key3();  

  49.     }  

  50. }  

key.c


  1. #include "reg51.h"  

  2. extern unsigned int pwm;  

  3. sbit K3=P2^6;  

  4.   

  5.  void delay(unsigned int x)  

  6. {  

  7.    while(x--);  

  8. }  

  9.   

  10. void key3()  

  11. {  

  12.     static char st;  

  13. if(K3==0)  

  14. {  

  15.      if(st==0)  

  16.      {  

  17.         delay(5000);  

  18.         if(K3==0)  

  19.         {  

  20.             st=1;  

  21.             pwm++;  

  22.             if(pwm>=20)  

  23.             {  

  24.                 pwm=1;  

  25.             }  

  26.         }  

  27.   

  28.      }  

  29. }  

  30. else  

  31. {  

  32.     st=0;  

  33. }  

  34. }  


关键字:51单片机  定时器 引用地址:51单片机定时器的原理与使用(二)

上一篇:【51单片机】延时函数计算问题以及如何准确延时
下一篇:单片机C语言之指针变量

推荐阅读最新更新时间:2024-03-16 16:01

基于51单片机超声波避障+蓝牙遥控智能小车
单片机源程序如下: #include reg52.h #include intrins.h typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; sbit Sevro_moto_pwm = P2^6; //接舵机信号端输入PWM信号调节速度 sbit ECHO= P1^1; //超声波接口定义 sbit TRIG= P1^0; //超声波接口定义 sbit PWM1 = P2^5; //左电机高电平 sbit PWM2 = P2^
[单片机]
STM32 学习笔记_TIME定时器详解1
STM32 单片机的定时器的确很强大,参考说明书中就占了一百多页,占参考手册1/4 有多了。 STM32的定时器分了好几个类别,各个类别针对功能作用都不大相同。 分有: 一、高级定时器 二、通用定时器 三、基本定时器 四、看门狗定时器 五、SysTick定时器 其中看门狗定时器和SysTick定时器本篇笔记阐述,这里主要记下对平时使用定时器作用的计时计数器的一些自己的理解。 按照参考手册中的定义 高级定时器 通用定时器基本定时器,这三个定时器成上下级的关系,即基本定时器有的功能通用定时器都有,而且还增加了向下、向上/向下计数器、PWM生成、输出比较、输入捕获等等功能;而高级定时器又包含了通用定时器的所有功能,另外还增加了死区互补输
[单片机]
STM32 学习笔记_TIME<font color='red'>定时器</font>详解1
定时器进行计数的一个简单例子
/* 注:该程序主要是如何运用定时器进行计数,体现模块化的子函数,是一个比较浅显的程序 */ #include reg52.h //头文件 #define uchar unsigned char //宏定义 #define uint unsigned int uchar count; //定义全局变量 void display_led() //led显示子函数 { if(count==20) //每隔1S发生变化(晶振为:12MHZ) { count=0; //计数清零,以便下次计数 P2=~P2; //P2的值取反 P2=P2 1; //P2的值左移 P2=~P2; if(P2==0xff) //如果最后一个L
[单片机]
STM32CubeMX之定时器控制微秒延时详解
写在前面的话,为什么另需定时器进行微秒级延时。 1.在HAL固件库中只有使用Systick作为延时计数器,毫秒级延时HAL_Delay()。为了增加精确的微秒级延时,一般都是更改Systick配置参数,但HAL固件库许多地方都使用了HAL_Delay()函数,因此建议大家不要修改系统自动配置的Systick参数; 2.个人觉得到加入操作系统时要占用Systick,而MCU系统自身的时基还要选择其他的定时器,综上所述,对Systick做的更改基本白搭; 因此采用定时器控制微妙延时的方法,是比较灵活的。需要用户增加的代码很少,经济实用,节能环保- -; 步骤1.配置时钟 注意,一定要确定红色部分标记的晶振频率要与实际的晶振保持一致。
[单片机]
51单片机定时器TMOD与TCON、SCON
51单片机中断级别 中断源 默认中断级别 序号(C语言用) INT0---外部中断0 最高 0 T0 ---定时器/计数器0中断 第2 1 INT1---外部中断1 第3 2 T1 ----定时器/计数器1中断 第4 3 TX/RX---串行口中断 第5 4 T2 ---定时器/计数器2中断 最低 5 ———————————————— 定时器/计数器模式控制寄存器TMOD是一个逐位定义的8位寄存器,但只能使用字节寻址,其字节地址为89H。 D0~D3为
[单片机]
<font color='red'>51单片机</font><font color='red'>定时器</font>TMOD与TCON、SCON
51单片机控制SL811HS的USB主机底层驱动
引言 基于USB接口的设备使用方便,性价比高,因此在人们的工作和生活中得到了广泛的应用,如U盘,移动硬盘,光驱,USB摄像头,USB鼠标键盘等,同时,51系列单片机以其成熟的技术和高性价比吸引了大量国内用户,被广泛应用于测控和自动化领域,因此,如果在51单片机系统中增加USB主机接口,实现对USB从机设备的控制,则该单片机系统可以充分利用现有的各种USB从机设备,大大扩展单片机系统功能。 本设计实现了在51单片机系统中增加USB主机功能,采用普通51单片机外接专用USB接口芯片的方案,这种方案虽然会使系统传输速度受到限制,而且在稳定性有所欠缺,但此方案设计灵活性高,且易于移植,为低成本产品的开发提供了广阔前景,设计中采用51单
[单片机]
51单片机串口通信的原理实例
一、原理简介 51单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。 与之前一样,首先我们来了解单片机串口相关的寄存器。 SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1)
[单片机]
<font color='red'>51单片机</font>串口通信的原理实例
STM32F103标准库开发---定时器中断实验---通用定时器TIM3使用
一、STM32F103定时器 二、STM32F103通用定时器 1. 主要功能 通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括: 位于低速的APB1总线上(注意:高级定时器是在高速的APB2总线上); 16位向上、向下、向上/向下自动装载计数器(TIMx_CNT); 16位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为1~65536之间的任意数值; 4个独立通道(TIMx_CH1~4),这些通道可以用来作为:输入捕获、输出比较、PWM生成(边缘或中间对齐模式)、单脉冲模式输出; 使用外部信号控制定时器和定时器互连的同步电路; 如下事件发生时产生中断/DMA:更新(计数
[单片机]
STM32F103标准库开发---<font color='red'>定时器</font>中断实验---通用<font color='red'>定时器</font>TIM3使用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved