单片机学习笔记(数码管)

点亮一个数码管

TF0:只要溢出后,tf0就置1.

只需要知道1和2两种工作模式即可。

使用流程如下:

附上数码管真值表:

完整代码如下:(每秒增加一个显示)

#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

//用数组来存储数码管的真值表,数组将在下一章详细介绍
unsigned char code LedChar[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

void main()
{
    unsigned char cnt = 0;  //记录T0中断次数
    unsigned char sec = 0;  //记录经过的秒数

    ENLED = 0;    //使能U3,选择数码管DS1
    ADDR3 = 1;
    ADDR2 = 0;
    ADDR1 = 0;
    ADDR0 = 0;
    TMOD = 0x01;  //设置T0为模式1
    TH0  = 0xB8;  //为T0赋初值0xB800
    TL0  = 0x00;
    TR0  = 1;     //启动T0
    
    while (1)
    {
        if (TF0 == 1)        //判断T0是否溢出
        {
            TF0 = 0;         //T0溢出后,清零中断标志
            TH0 = 0xB8;      //并重新赋初值
            TL0 = 0x00;
            cnt++;           //计数值自加1
            if (cnt >= 50)   //判断T0溢出是否达到50次
            {
                cnt = 0;            //达到50次后计数值清零
                P0 = LedChar[sec];  //当前秒数对应的真值表中的值送到P0口
                sec++;              //秒数记录自加1
                if (sec >= 16)      //当秒数超过0x0F(15)后,重新从0开始
                {
                    sec = 0;
                }
            }
        }
    }
}

 关于如何算th和tl:

 比如当晶振频率为11.0592M的晶振。则每秒可产生机器周期为11.0592/12=0.9216M的机器周期,也就是921600个机器周期。50ms等于0.05秒,所以需要921600*0.05=46080个机器周期;定时器在方式1工作,为16位,最大值为65536,所以需设初值为65536-46080=19456;转为16进制为(4c00),所以高位TH0=0x4c; TL0=0x00;


 动态显示多个数码管

10ms内需要刷新同一个数码管。

关于中断 : 


完整代码:

/*
*******************************************************************************
*                     《手把手教你学51单片机(C语言版)》
*                    配套 KST-51 单片机开发板 示例源代码
*
*         (c) 版权所有 2014 金沙滩工作室/清华大学出版社 保留所有权利
*                 获取更多资料请访问:http://www.kingst.org
*
* 文件名:main.c
* 描  述:第6章 数码管动态显示原理示例(if...else if...语句示例)
* 版本号:v1.0.0
* 备  注:详情见第6章6.4节
*******************************************************************************
*/

#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

 unsigned char i = 0;    //动态扫描的索引
 unsigned int  cnt = 0;  //记录T0中断次数
unsigned char flagls =0;

unsigned char code LedChar[] = {  //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = {  //数码管显示缓冲区,初值0xFF确保启动时都不亮		
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF		//缓冲区的作用就是先把该显示的数据存进去,后再取出值,这样可以提高运行速度
};

void main()
{
   
    unsigned long sec = 0;  //记录经过的秒数

    ENLED = 0;    //使能U3,选择控制数码管
    ADDR3 = 1;    //因为需要动态改变ADDR0-2的值,所以不需要再初始化了
    TMOD = 0x01;  //设置T0为模式1
    TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
    TL0  = 0x67;
    TR0  = 1;     //启动T0
    EA = 1;
	ET0 = 1; //开启中断
	    

    while (1)
    {
           
            if (flagls == 1)  //判断T0溢出是否达到1000次	 (一秒)
            {
                flagls = 0;
                sec++;        //秒计数自加1
                //以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符
                LedBuff[0] = LedChar[sec%10];			 //sec如果等于123456秒 %10就赋值6
                LedBuff[1] = LedChar[sec/10%10];
                LedBuff[2] = LedChar[sec/100%10];
                LedBuff[3] = LedChar[sec/1000%10];
                LedBuff[4] = LedChar[sec/10000%10];
                LedBuff[5] = LedChar[sec/100000%10];
            }
            
        
    		}
}


void InterruptTime0() interrupt 1	  //TF自动清零
{
  TH0 = 0XFC;
  TL0 =0X67;
  cnt ++;
  if(cnt >= 1000)
  {
   cnt =0;
   flagls = 1;
   }
   //以下代码完成数码管动态扫描刷新
			P0=0xff;//杜绝鬼影现象,即addr没有完全切换时,产生的错误显示。
            switch (i)
            {
                case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
                case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
                case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
                case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
                case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
                case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
                default: break;
            }


}  

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永瞬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值