Dotcpp  >  编程教程  >  定时器  >  定时器&数码管扫描显示

定时器&数码管扫描显示

点击打开在线编译器,边学边练

1.定时器中断实现间隔切换

在第六章第4讲的测试代码中提到过数码管微闪烁问题,这是由于三八译码器的IO端口切换的间隔时间不均匀导致,这部分的问题宋老师已经在《手把手教你学51单片机》文档6.4.2节有详细解释,并在6.5.2节里解决了这个问题。数码管扫描函数我们使用定时器0强制实现间隔1ms切换三八译码器的IO输出,这样保证了每个数码管被点亮的时间都是均匀的。我们在主函数里不停地执行数码管显示函数。这里是测试代码,用定时器1实现add间隔50ms自增1,数码管显示add的值。

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
#include <timer.h>
 
u32 add=9999;
 
void main()
{   
    LED_Init();          //初始化LED硬件模块
    EA = 1;              //闭合总中断开关
    TIM0_Init(1000,33);  //定时1ms,因为中断函数占用时间多一点,所以微调的值跨度比较大
    TIM1_Init(50000,10); //定时50ms,10是微调使定时更精确
    
    while(1)
    {   
        ShowNumber(add);
    }   
}
 
void TIM0_IRQHandler() interrupt 1
{
    TH0 = T0RH; //重新加载重载值
    TL0 = T0RL;
    SEG_Scan(); //间隔1ms执行三八译码器的不同IO输出低电平
}
 
void TIM1_IRQHandler() interrupt 3
{
    TH1 = T1RH; //重新加载重载值
    TL1 = T1RL;
    add++; 
}


2.PWM简单入门

PWM概念在《手把手教你学51单片机》文档10.2节有很好的解释,这里笔者就不费笔墨讲解了,我们简单入门PWM来让8盏小灯实现较暗地点亮。P0端口输出如下

P0端口输出图

代码实现如下

#include <reg52.h> 
#include <function.h> //详见第六章第8讲
#include <timer.h>

u8 pwm=0;
void main()
{   
    LED_Init();            //初始化LED硬件模块
    EA = 1;                //闭合总中断开关
    TIM0_Init(1000,10);    //定时1ms,10是微调使定时更精确
    
    while(1)
    {   
        if(pwm<=8)P0=0xFF; //pwm在0~8之间都会执行“P0=0xFF;”,也就是占空比为90%,小灯显示较暗
        else P0=0x00; 
    }   
}
 
void TIM0_IRQHandler() interrupt 1
{ 
    TH0 = T0RH;       //重新加载重载值
    TL0 = T0RL;
  
    pwm++;
    if(pwm>=10)pwm=0; //pwm在0~9之间间隔1ms变化
}


3.浅谈例程代码

在宋老师的lesson10_2例程代码中的“void ConfigPWM(unsigned int fr, unsigned char dc)”函数里大家阅读起来可能有点吃力,这里笔者解析一下。

我们先再次复习一下知识,定时器每加1经过的时间是(12/11059200)秒,如果计数到11059200(多次溢出),时间也就过去了12秒。时间过去了1秒的时候计数值就是(11059200/12)。

“ConfigPWM(100, 10);”意味着tmp的数值周期是(1/100)秒,也就是频率为100Hz。这个周期里高电平定时持续的时间为“(1/100)*0.1”秒,低电平定时持续的时间为“(1/100)*0.9”秒。所以占空比为10%。

主函数里的延时就是让这个PWM波形持续一段时间,然后又到下一个占空比为40%的PWM波形持续一段时间。4个阶段的占空比不同,也就表现为小灯的显示亮度不同。

这里笔者做个效果图给大家理解吧

PWM效果图


本文固定URL:https://www.dotcpp.com/course/426

上一课:

数据类型强制转换

下一课:

呼吸灯

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

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

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

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

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

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

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

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

单片机教程
第一章 单片机入门
第二章 LED及入门
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)