打印

初学请教大家。

[复制链接]
1609|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
amwrdfe|  楼主 | 2008-11-26 17:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*硬件连接:段选码P0.0~P0.7(a,b,c,d,e,f,g,h,dp),位选码P2.0~P2.5(高到低)
  K1--P3.5;K2--P3.4;K3--P3.3;K4--P3.2*/

#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint  unsigned int 
uchar code BitTab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code DispTab[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar DispBuf[6];    //6字节的显示缓冲区
bit    Sec;            //1s到的标记
bit Minute;            //1m到的标记
bit Hour;            //1h到的标记
bit H_up;
bit H_down;
bit M_up;
bit M_down;
sbit P2_7=P2^7;        //周期测试位
uchar SecValue;        //秒计数
uchar MinuteValue;    //分计数
uchar HourValue;    //时计数

uchar code TH0Val=63075/256;
uchar code TL0Val=63075%256;//晶振为12M,定时2.5ms定时器初值(计算值为63036,校准值为63075)


void Timer0() interrupt 1
{    uchar tmp;
    static uchar dCount;    //计数器,显示程序通过它得知现在显示那个数码管
    static uint Count;        //秒计数器
    const uint CountNum=400;    //预置值(400*2.5ms=1minute)
    P2_7=~P2_7;                   //外部测试位,用于调整定时器初值
    TH0=TH0Val;
    TL0=TL0Val;    
    tmp=BitTab[dCount];        //根据当前的计数值取位值
    P2=P2|0x3f;                //P2与00111111相或,将低6位置1
    P2=P2&tmp;                //P2与取出的值相与,将某一位清0
    tmp=DispBuf[dCount];    //根据当前的计数值,取显示缓冲区的待显示值
    tmp=DispTab[tmp];        //取字形码
    P0=tmp;                    //送出字形码
    dCount++;                //计数值加1
    if(dCount==6)            //如果计数值为6,归0
        dCount=0;    
//以下为秒计数
    Count++;                //计数值加1
    if(Count>=CountNum)        //到达预置计数值
    {    Count=0;            //清零
        Sec=1;                //置1秒到标志位
        SecValue++;                //秒值加1
        if(SecValue>=60)
        {    SecValue=0;            
            Minute=1;         //置1分到标志位
            MinuteValue++;     //分值加1
        }
        if(MinuteValue>=60)
       {    Hour=1;              //置1小时到标志位
            MinuteValue=0;
             HourValue++;      //小时值加1
            if(HourValue>=24)
            {HourValue=0;}
       }
     }
     
}

void Init()
{    TMOD=0x01;
    TH0=TH0Val;
    TL0=TL0Val;    
    ET0=1;                //开T0中断
    EA=1;                //开总中断
    TR0=1;                //T0开始运行
}

void mDelay(unsigned int Delay)  //延时程序,用于键盘消抖
{    unsigned int i;
    for(;Delay>0;Delay--)
    {    for(i=0;i<124;i++)
        {;}
    }
}

uchar Key()               //键盘程序,获得键值
{    uchar KValue;
    uchar tmp;
    P3|=0x3c;           //将P3口接键盘的4位置1
    KValue=P3;
    KValue|=0xc3;        //将未接的四位置1
    if(KValue==0xff)    //中间4位均为1,无键按下
        return(0);        //返回
    mDelay(10);            //延时10mS消抖
    KValue=P3;
    KValue|=0xc3;         //再次读键盘
    if(KValue==0xff)
    return(0);
    for(;;)
    {    tmp=P3;
        if((tmp|0xc3)==0xff)      //等待按键释放
        break;
    }
    return(KValue);
}

void KProce(uchar KValue)          //键值处理程序
{    if((KValue&0x20)==0)          //K1
    H_up=1;
    if((KValue&0x10)==0)          //K2
    H_down=1;
    if((KValue&0x08)==0)          //K3
    M_up=1;
    if((KValue&0x04)==0)          //K4
    M_down=1;
}


void main()
{    uchar KValue;            //存放键值
    Init();                    //初始化
    DispBuf[4]=SecValue/10;
    DispBuf[5]=SecValue%10;
    
    for(;;)
    {
         DispBuf[2]=MinuteValue/10;
         DispBuf[3]=MinuteValue%10;
         DispBuf[0]=HourValue/10;
         DispBuf[1]=HourValue%10;

        if(Sec)                //1s时间到
        {    DispBuf[4]=SecValue/10;
            DispBuf[5]=SecValue%10;
            
            if(DispBuf[4]==0)
        
            Sec=0;            //清除1s到标志位
        }

        if(Minute)
        {    if(DispBuf[2]==0)
            
            Minute=0;                     //清除1m到标志位
         }

         if(Hour)
         {    if(DispBuf[0]==0)
                
            Hour=0;                        //清除1h到标志位
         }

         KValue=Key();         //调键盘程序获得键值
         if(KValue)             //该值不等于0
         {    KProce(KValue);     //调键盘处理程序
         }
         if(H_up)               //小时值调整
         {    HourValue++;
             if(HourValue>=24)
            {    HourValue=0;
            }
             H_up=0;    
         }
         if(H_down)
         {    HourValue--;
             H_down=0;
         }
         if(M_up)                   //分值调整
         {    MinuteValue++;
             if(MinuteValue>=60)
            {MinuteValue=0;
            }
             M_up=0;    
         }
         if(M_down)
         {    MinuteValue--;
             M_down=0;
         }
    }
}



一个51时钟程序,
有个地方不明白,
P0与P2口输出电平不对应的?
我的意思是说:当PO口送出一个相应的字段码,而相对应字段码的位的电平确是不对的,搞不明白。
例如,
Dcount=1,
Dispbuf[0]=0,
则得
P2=oxfe,
p0=oxc0,
两者的极性不会在共阳数码管对应的位上显示0的啊,
可是模拟的时候又是显示正常的,难道动态显示可以这么搞?

相关帖子

沙发
耕在此行| | 2008-11-27 18:45 | 只看该作者

你的程序太长了

没有这个耐心看哦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

755

帖子

3

粉丝