1.实用性改善

为了使上一讲的功能更加完善,我们编写新的实用型的代码,效果是让数码管显示的数就是输入引脚高电平持续的微秒数,最高能捕获到999999微秒。如果高电平持续的时间超出这个取值范围,那么数码管不够显示,所以超出范围的话我们就让6个数码管显示    FFFFFF。

因为计数器计时到65535之后就会产生溢出,也就是超过71ms就会溢出一次,我们知道计数器溢出也是会产生中断的,所以在中断函数里我们实现让变量x简单的自加1表明时间过去了71毫秒左右。

假设高电平持续的时间有75毫秒左右,那么得出最后的微秒数就是

x*71111+(TH0*256+TL0)*(12/11059200)*1000000;

现在我们首次使用float类型的变量,第一次使用带小数点的数据类型。

不同的数据类型之间运算要进行强制转换,请参考《手把手教你学51单片机》文档10.1.1节。

我们定义的float类型变量capture_val就是用来记录持续高电平的微秒数。请看以下三段代码

capture_val=(float)TH0*256.0+(float)TL0;
capture_val=(capture_val*12.0)/11.0592;
capture_val=x*71111.0+capture_val;

第一段是取出计数器的值。第二段就是把计数器的值乘以(12/11059200),意思是得到的秒数,但是我们需要的是微秒数,所以除以11.0592就是把秒数放大了10的6次方倍。第三段代码则是,溢出过好几次71.111ms,所以需要加上这些时间。

我们记住,浮点型的数据加减乘除其他数时我们要加小数点。

还有函数参数的传递也要强制转换,比如“ShowNumber((u32)capture_val);”

capture_val本身是float类型,想显示正整数就要强制转换为unsigned long类型。


2.代码

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
 
float x=0;
 
//请用杜邦线把P1.6和P3.2连接起来
void main()
{   
    u8 i;
    float capture_val;
    LED_Init();    //初始化LED硬件模块
    TMOD=0x09;     //低四位 1001 
  
    EA=1;          //闭合总中断开关
    ET0=1;
   
    BEEP=0;        //先让P1.6输出低电平
    TR0=1;
    BEEP=1;        //开始计数  
    delay_ms(500); //软件仿真调试出此处的延时时间为698275.8微秒
    BEEP=0;        //停止计数  
  
    capture_val=(float)TH0*256.0+(float)TL0;
    capture_val=(capture_val*12.0)/11.0592;
    capture_val=x*71111.0+capture_val;
  
    if(capture_val>999999.0)
    {
        for(i=0;i<6;i++)LedBuff[i]=LedChar[15]; //超出数码管的显示范围就显示FFFFFF 
    }
    else  ShowNumber((u32)capture_val);         //显示没超过999999时的数
  
    while(1)
    {     
        SEG_Scan();         
    }   
}
 
void TIM0_IRQHandler() interrupt 1
{
    x=x+1.0;
}

我们把“delay_ms(500);”改为“delay_ms(100);”,然后先软件仿真调试看看“delay_ms(100);”花费了多少时间,接着再下载进开发板看看数码管显示的数值是多少,记住要保证P3.2和P1.6用杜邦线相连。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)