还是C51单片机中关于数码管显示问题

还是C51单片机中关于数码管显示问题

P0=table[Count/100];---------------->百位

P1=table[(Count%100)/10];----------->十位

P2=table[(Count%100)%10];----------->个位

/*******************************************/

P0=table[Count/1000];-------------------->千位

P1=table[(Count%1000)/100];-------------->百位

P2=table[(Count%1000)%100/10];----------->十位

P3=table[(Count%1000)%100%10];----------->个位

以此类推,要注意的是当最高位为0,是不是要显示的问题,那就是另一回事了。

基于89C52单片机电子时钟的设计,硬件图在下面~~

 单片机时钟c程序   89c52  1602电子时钟c程序

让单片机的数码管显示的数从0开始递增一直到255,然后重新置0,再递增,如此循环.

  还是用到了将要显示的数进行百位,十位,个位的分离.

#include <reg52.h>  

#define uint unsigned int  

#define uchar unsigned char  

 

sbit lcdrs = P1^0;  

sbit lcdrw = P1^1;  

sbit lcden = P1^2;  

 

sbit key0 = P2^0;//功能键,选择时分秒  

sbit key1 = P2^1;//加1键  

sbit key2 = P2^2;//减1键  

sbit key4 = P2^4;  

 

uchar key0_count;//按键0被按的次数(0~3)  

 

char hour,minute,second; //时分秒  

uint timer_count;  //定时器中断计数  

 

uchar table_date[] = 2009-4-12  Mon;  

uchar table_time[] = 00:00:00;  

 

/****** 函数申明 ********/ 

void write_cmd_1602(uchar cmd);  

void write_data_1602(uchar dat);  

void write_add(uchar add,uchar dat);  

void init1602();  

void delay(uint z);  

uchar reverse(uchar c);  

void keyscan();  

void init();  

/****** 主函数 ********/ 

void main()  

{  

    init();  

    //init1602();  

    //while(1);  

    while(1)  

    {      keyscan();      delay(5);  

    }  

}  

//1602液晶初始化  

void init1602()  

{  

    lcdrw = 0;    //本程序只读不写,故将其置低  

    lcden = 0;    //关闭1602  

    delay(5);  

    write_cmd_1602(0x01);  //清屏  

    write_cmd_1602(0x38);  //显示模式  

    write_cmd_1602(0x0c);  //开显示,不显示光标,不闪烁  

    write_cmd_1602(0x06);  //地址指针自动加1  

    write_cmd_1602(0x80+1);//将光标指向第一行第二个位置  

    delay(5);  

}  

void delay(uint z)  

{  

    uint x,y;  

    for(x=z;x>0;x--)      for(y=110;y>0;y--);  

}  

/** 将发送的数据进行翻转,高位到低位,低位转到高位 **/    uchar reverse(uchar c)    {    uchar chbuff=0;    if (c&0x01) chbuff=chbuff|0x80;    if (c&0x02) chbuff=chbuff|0x40;    if (c&0x04) chbuff=chbuff|0x20;    if (c&0x08) chbuff=chbuff|0x10;    if (c&0x10) chbuff=chbuff|0x08;    if (c&0x20) chbuff=chbuff|0x04;    if (c&0x40) chbuff=chbuff|0x02;    if (c&0x80) chbuff=chbuff|0x01;    return chbuff;    }  

//向液晶写命令  

void write_cmd_1602(uchar cmd)  

{  

    lcdrs = 0; //低表示写命令,高表示写数据  

    delay(5);  

    P0 = reverse(cmd);  

    delay(5);  

    lcden = 1; //给一个高脉冲  

    delay(5);    lcden = 0;  

    delay(5);  

}  

//向液晶写数据  

void write_data_1602(uchar dat)  

{  

    lcdrs = 1; //低表示写命令,高表示写数据  

    delay(5);  

    P0 = reverse(dat);  

    delay(5);  

    lcden = 1; //给一个高脉冲  

    delay(5);    lcden = 0;  

    delay(5);  

}   

//根据地址向液晶写数据  

void write_add(uchar add,uchar dat)  

{  

    uchar shi,ge;  

    shi = dat/10;  

    ge = dat%10;  

    delay(5);  

    write_cmd_1602(0x80+add);  

    write_data_1602(shi+0x30);  

    delay(5);  

    write_data_1602(ge+0x30);  

}  

//键盘扫描函数  

void keyscan()  

{  

    key4 = 0;  

    if(0==key0) //第一个键被按下  

    {      delay(5); //消抖      if(0==key0)      {      key0_count ++;      if(4==key0_count)      key0_count = 0;      while(!key0); //松手检测      if(0==key0_count)      {      TR0 = 1;  //重新开始计时      write_cmd_1602(0x0c);  //禁止显示光标并不让其闪烁        }      if(1==key0_count)      {      TR0 = 0;  //暂停计时      write_cmd_1602(0x80+0x40+11);//将地址指针指向秒的位置      write_cmd_1602(0x0f);  //显示光标并闪烁      delay(5);        }      if(2==key0_count)      {      TR0 = 0;  //暂停计时      write_cmd_1602(0x80+0x40+8);//将地址指针指向分的位置      write_cmd_1602(0x0f);  //显示光标并闪烁      delay(5);      }      if(3==key0_count)      {      TR0 = 0;  //暂停计时      write_cmd_1602(0x80+0x40+5);//将地址指针指向小时的位置      write_cmd_1602(0x0f);  //显示光标并闪烁        delay(5);      }      }  

    }  

    if(0==key1) //第二个键被按下  

    {      delay(5); //消抖      if(0==key1)      {      while(!key1); //松手检测      if(key0_count==1)      {      second ++;      if(60==second)    second = 0;      write_add(0x40+10,second);      }      if(key0_count==2)      {      minute ++;      if(60==minute)    minute = 0;      write_add(0x40+7,minute);      }      if(key0_count==3)      {      hour ++;      if(24==hour)        hour = 0;      write_add(0x40+4,hour);      }      }  

    }  

    if(0==key2) //第三个键被按下  

    {      delay(5); //消抖      if(0==key2)      {      while(!key2); //松手检测      if(key0_count==1)      {      second --;      if(-1==second)    second = 59;      write_add(0x40+10,second);    }      if(key0_count==2)      {      minute --;      if(-1==minute)    minute = 59;      write_add(0x40+7,minute);        }      if(key0_count==3)      {      hour --;      if(-1==hour)        hour = 23;      write_add(0x40+4,hour);       }      }  

    }  

 

}  

//程序初始化函数  

void init()  

{  

    uchar i;  

    hour = 0;  

    minute = 0;  

    second = 0;  

    key0_count = 0;  

    init1602();  

    delay(20);  //延长时间,确保液晶处于非忙状态  

    for(i=0;i<14;i++)  

    {      write_data_1602(table_date[i]);      delay(5);    }  

    write_cmd_1602(0x80+0x40+4);  //调整地址指针  

    for(i=0;i<8;i++)  

    {      write_data_1602(table_time[i]);      delay(5);    }  

    //初始化定时器  

    TMOD = 0x01;   //定时器模式  

    TH0 = (65536-50000)/256;  //装初值  

    TL0 = (65536-50000)%256;  

    EA = 1;//开总中断  

    ET0 = 1;//开定时器0中断  

    TR0 = 1; //启动定时器,此时开始计时  

}  

void timer0() interrupt 1  //定时器0的中断处理函数  

{  

    TH0 = (65536-50000)/256;  //装初值 ,50ms 

    TL0 = (65536-50000)%256;  

    timer_count ++;  

    if(20==timer_count)    //到了1秒更新时分秒的显示  

    {      timer_count = 0; //中断次数清0,重新计数      second ++;   //秒针加1      if(second==60)      {      second = 0;      minute ++;   //分针加1      if(60==minute)      {      minute = 0;      hour ++;  //小时加1      if(24==hour)      {      hour = 0;      }      write_add(0x40+4,hour);  //更新时针    }      write_add(0x40+7,minute);  //更新分针的显示      }      write_add(0x40+10,second);  //更新秒针  

    }  

上一篇:下一篇:3寸屏智能手机屏幕是多大的
下一篇:上一篇:返回栏目