595输出驱动数码管闪烁

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baidu_33836580/article/details/50578918

/*
有个题目,是用595输出,驱动6位数码管显示时、分、秒。
用两个按键进行修改,一个变换修改的位置,另一个是加一。

提问者希望让待调整的位闪烁。

题目可见:
http://zhidao.baidu.com/question/443865187.html
http://zhidao.baidu.com/question/449232374.html

提问者给出了部分程序。但是,程序太简单了,百度知道的排版也太滥,程序基本不能用。

根据问题的要求,做而论道重新设计了程序,并画出了显示电路。
运行效果如下图所示:

595输出驱动数码管闪烁 - 非著名博主 - 电子信息角落

图片链接:
http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/album/item/8dd9ee940a7b0208c4d7847162d9f2d3562cc862.html

图中上部是正常显示,下部是调整“分”的时候,闪烁期间、“黑屏”时的效果。

全部程序如下。

*/
#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit KEY1 = P3^6;
sbit KEY2 = P3^7;

sbit CP = P2^0;
sbit DA = P2^1;
sbit LE = P2^2;

uchar H, M, S, keynum, a;
bit b;                  //--交替黑屏的控制位
uchar code table[] = {
    0xc0, 0xf9, 0xa4, 0xb0, 0x99,
    0x92, 0x82, 0xf8, 0x80, 0x10, 255};//255是黑屏的代码
uchar disp_buf[6] = {0};//--显示缓冲
//------------------------------------------
void delay(uint z)        //延时
{
    uint x, y;
    for(x = z; x > 0; x--)  for(y = 110; y > 0; y--);
}
//------------------------------------------
void write_595(uchar date)//写入595
{
    uchar i;
    for(i = 0; i < 8; i++) {
      CP = 0;  DA = date & 0x80;
      CP = 1;  date <<= 1;
    }
}
//------------------------------------------
void display(void)
{
    write_595(table[disp_buf[0]]);
    write_595(table[disp_buf[1]]);
    write_595(table[disp_buf[2]]);
    write_595(table[disp_buf[3]]);
    write_595(table[disp_buf[4]]);
    write_595(table[disp_buf[5]]);
    LE = 1; LE = 0;       //令595输出
}
//------------------------------------------
void UpData(uchar S,uchar M,uchar H)
{
    disp_buf[0] = S % 10;
    disp_buf[1] = S / 10;
    disp_buf[2] = M % 10;
    disp_buf[3] = M / 10;
    disp_buf[4] = H % 10;
    disp_buf[5] = H / 10;
}
//------------------------------------------
void init(void)
{
    TMOD = 0x01;//T0定时方式1
    TH0 = 0x4c; //50ms@11.0592MHz
    TR0 = 1;
    ET0 = 1;
    EA = 1;

    H = 12;
    M = 59;
    S = 45;

    keynum = 0;
}
//------------------------------------------
void keyscan(void)    //键盘扫描
{
    if(!KEY1)  {      //选择键按下
      delay(5);
      if(!KEY1)  {
        while(!KEY1);
        keynum++;     //按键次数
        if(keynum == 4) {
          keynum = 0;      //这将停止闪烁
          UpData(S, M, H); //更新数据,消除闪烁
          display();       //显示正常数据
    } } }
//------------
    if(keynum != 0)  {
      if(!KEY2)  {    //调整键按下
        delay(5);
        if(!KEY2)  {
          while(!KEY2);
          if(keynum == 1) { H++; if(H == 24)  H = 0; }
          if(keynum == 2) { M++; if(M == 60)  M = 0; }
          if(keynum == 3) { S++; if(S == 60)  S = 0; }
    } } }
}
//------------------------------------------
void main()
{
    init();
    while(1)
      keyscan();  //调用键盘扫描函数
}
//------------------------------------------
void timer0() interrupt 1 //T0中断
{
    TH0 = 0x4c;
    a++;
//-----------------------
    if((a % 5) == 0)  {//0.25s
      b = ~b;          //0.25翻转一次
      UpData(S, M, H); //更新数据
      if (b)  {        //黑屏
        if (keynum == 1) {disp_buf[4] = 10; disp_buf[5] = 10;}//H黑屏
        if (keynum == 2) {disp_buf[2] = 10; disp_buf[3] = 10;}//M黑屏
        if (keynum == 3) {disp_buf[0] = 10; disp_buf[1] = 10;}//S黑屏
      }
      display();       //显示
    }
//-----------------------
    if(a == 20)  {//1s
      a = 0;
      if(!keynum) {
        S++;
        if(S == 60)  {
          S = 0;
          M++;
          if(M == 60)  {
            M = 0;
            H++;
            if(H == 24)  H = 0;
      } } }
      UpData(S, M, H);   //更新数据
    }
}
//------------------------------------------

//提问者对回答的评价:谢谢啊,你给的程序很好,我把12887的部分加上调试通了,接下来要弄串口通信和RS485/422通信了,再会!

展开阅读全文

没有更多推荐了,返回首页