标题:请帮忙看看下面的万年历程序,为什么键盘不能用?O(∩_∩)O谢谢
只看楼主
大神求帮助
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2015-6-3
 问题点数:0 回复次数:0 
请帮忙看看下面的万年历程序,为什么键盘不能用?O(∩_∩)O谢谢
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar temp1,a,ri,yue,nian,week,flag,key1n,temp,key1n;
char miao,shi,fen;
#define yh 0x80 //第一行                           
#define er 0x80+0x40  //第二行                  

sbit rs=P0^0;
sbit en=P0^2;
sbit rw=P0^1;                               //如果硬件上rw接地,就不用写这句和后面的rw=0了
 
                           
//DS1302时钟芯片引脚连接定义
sbit IO=P3^4;
sbit SCLK=P3^3;
sbit RST=P3^5;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;

//校时按键与C51的引脚连接定义
//sbit rd=P2^4;
//sbit key1=P2^0;                             //设置键
//sbit key2=P2^1;                             //加键
//sbit key3=P2^2;                             //减键
//sbit buzzer=P2^3;                            //蜂鸣器,通过三极管9012驱动,端口低电平响

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

uchar code tab1[]={"2015-11-11"};             //年显示的固定字符
uchar code tab2[]={"11:11:11"};                //时间显示的固定字符

//延时函数,后面经常调用
void delay(uint xms)                         //延时函数,有参函数
{
    uint x,y;
    for(x=xms;x>0;x--)
     for(y=110;y>0;y--);
}

/********液晶写入指令函数与写入数据函数,以后可调用**************/

write_1602com(uchar com)                      //****液晶写入指令函数****
{

    P0=(P0&0x0f)|(com&0xf0);//高四位
    rs=0;
    rw=0;
    delay(10);
    en=1;
    delay(10);
    en=0;
   
    com=com<<4;
    P0=(P0&0x0f)|(com&0xf0);//低四位
    rs=0;
    rw=0;
    delay(10);
    en=1;
    delay(10);
    en=0;                                   //en由高变低,产生下降沿,液晶执行命令
}


write_1602dat(uchar dat)                        //***液晶写入数据函数****
{
   
    P0=(P0&0x0f)|(dat&0xf0);
    rs=1;
    rw=0;
    delay(10);
    en=1;
    delay(10);
    en=0;

    dat=dat<<4;
    P0=(P0&0x0f)|(dat&0xf0);
    rs=1;
    rw=0;
    delay(10);
    en=1;
    delay(10);
    en=0;

}

lcd_init()                                     //***液晶初始化函数****
{
    write_1602com(0x38);                      //设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
    write_1602com(0x0c);                      //开显示不显示光标
    write_1602com(0x06);                      //整屏不移动,光标自动右移
    write_1602com(0x01);                      //清显示
    write_1602com(yh);                      //日历显示固定符号从第一行第1个位置之后开始显示
    for(a=0;a<10;a++)
    {
    write_1602dat(tab1[a]);                      //向液晶屏写日历显示的固定符号部分
    delay(5);
    }
    write_1602com(er);                       //时间显示固定符号写入位置,从第2个位置后开始显示
    for(a=0;a<8;a++)
    {
    write_1602dat(tab2[a]);                      //写显示时间固定符号,两个冒号
    delay(5);
    }

}


/*********************over***********************/

/***************DS1302有关子函数********************/

void write_byte(uchar dat)//写一个字节
{
    ACC=dat;
    RST=1;
    for(a=8;a>0;a--)
    {
        IO=ACC0;
        SCLK=0;
        SCLK=1;
        ACC=ACC>>1;
    }
}

uchar read_byte()                                   //读一个字节
{
    RST=1;
    for(a=8;a>0;a--)
    {
        ACC7=IO;
        SCLK=1;
        SCLK=0;
        ACC=ACC>>1;

    }
    return (ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)                   //向1302芯片写函数,指定写入地址,数据
{

    RST=0;
    SCLK=0;
    RST=1;
    write_byte(add);
    write_byte(dat);
    SCLK=1;
    RST=0;
}

uchar read_1302(uchar add)                          //从1302读数据函数,指定读取数据来源地址
{
    uchar temp;
    RST=0;
    SCLK=0;
    RST=1;
    write_byte(add);
    temp=read_byte();
    SCLK=1;
    RST=0;
    return(temp);
}
uchar BCD_Decimal(uchar bcd)                //BCD码转十进制函数,输入BCD,返回十进制
{
 uchar Decimal;
 Decimal=bcd>>4;
 return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init()                           //1302芯片初始化子函数(2015-01-01,00:00:00,week4)
{
RST=0;
SCLK=0;

write_1302(0x8e,0x00);                      //允许写,禁止写保护
write_1302(0x80,0x50);                     //向DS1302内写秒寄存器80H写入初始秒数据00
write_1302(0x82,0x59);                     //向DS1302内写分寄存器82H写入初始分数据00
write_1302(0x84,0x23);                     //向DS1302内写小时寄存器84H写入初始小时数据00
write_1302(0x8a,0x01);                     //向DS1302内写周寄存器8aH写入初始周数据4
write_1302(0x86,0x11);                     //向DS1302内写日期寄存器86H写入初始日期数据01
write_1302(0x88,0x09);                     //向DS1302内写月份寄存器88H写入初始月份数据01
write_1302(0x8c,0x15);                     //向DS1302内写年份寄存器8cH写入初始年份数据15
write_1302(0x8e,0x80);                      //打开写保护

}


/*
//温度显示子函数
void write_temp(uchar add,uchar dat)            //向LCD写温度数据,并指定显示位置
{
    uchar gw,sw;
    gw=dat%10;                            //取得个位数字
    sw=dat/10;                             //取得十位数字
    write_1602com(er+add);                  //er是头文件规定的值0x80+0x40
    write_1602dat(0x30+sw);                 //数字+30得到该数字的LCD1602显示码
    write_1602dat(0x30+gw);                 //数字+30得到该数字的LCD1602显示码
    write_1602dat(0xdf);                     //显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码
     write_1602dat(0x43);                      //显示"C"符号,0x43是液晶屏字符库里大写C的地址码        
}
*/
//时分秒显示子函数
void write_sfm(uchar add,uchar dat)           //向LCD写时分秒,有显示位置、显示数据,两个参数
{
    uchar gw,sw;
    gw=dat%10;                          //取得个位数字
    sw=dat/10;                           //取得十位数字
    write_1602com(er+add);                //er是头文件规定的值0x80+0x40
    write_1602dat(0x30+sw);               //数字+30得到十位的LCD1602显示码           
    write_1602dat(0x30+gw);               //数字+30得到个位的LCD1602显示码
               
}

//年月日显示子函数
void write_nyr(uchar add,uchar dat)           //向LCD写年月日,有显示位置、显示数据,两个参数
{
    uchar gw,sw;
    gw=dat%10;                         //取得个位数字
    sw=dat/10;                          //取得十位数字
    write_1602com(yh+add);               //设定显示位置为第一行第一个位置+add
    write_1602dat(0x30+sw);               //数字+30得到该数字的LCD1602显示码         
    write_1602dat(0x30+gw);               //数字+30得到该数字的LCD1602显示码
   
}

void write_week(uchar week)                //写星期函数
{
    write_1602com(yh+0x0b);              //星期字符的显示位置
    switch(week)
    {
        case 1:write_1602dat('M');          //星期数为1时,显示
               write_1602dat('O');
               write_1602dat('N');
               break;
      
        case 2:write_1602dat('T');           //星期数据为2时显示
               write_1602dat('U');
               write_1602dat('E');
               break;
        
        case 3:write_1602dat('W');           //星期数据为3时显示
               write_1602dat('E');
               write_1602dat('D');
               break;
        
        case 4:write_1602dat('T');            //星期数据为4是显示
               write_1602dat('H');
               write_1602dat('U');
               break;

        case 5:write_1602dat('F');            //星期数据为5时显示
               write_1602dat('R');
               write_1602dat('I');
               break;
        
        case 6:write_1602dat('S');            //星期数据为6时显示
               write_1602dat('T');
               write_1602dat('A');
               break;
        
        case 7:write_1602dat('S');            //星期数据为7时显示
               write_1602dat('U');
               write_1602dat('N');
               break;

}

}

//****************键盘扫描有关函数**********************

void keyscan()
{
   P2=0xfe;
   temp1=P2;
   temp1=temp1&0xf0;
   while(temp1!=0xf0)
   {
      delay(5);
      temp1=P2;
      temp1=temp1&0xf0;
      while(temp1!=0xf0)
      {
         temp1=P2;
         while(temp1!=0xf0)
         {
          temp1=P2;
          temp1=temp1&0xf0;
         }
      }

    if(temp1==0xee)                          //key1为功能键(设置键)
    {
      delay(10);                            //延时,用于消抖动
      if(temp1==0xee)                          //延时后再次确认按键按下
      {
       while(temp1!=0xee);
       key1n++;
       if(key1n==9)
        key1n=1;                      //设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环
    switch(key1n)
    {
   
    case 1: TR0=0;                          //关闭定时器
        
            write_1602com(er+7);         //设置按键按动一次,秒位置显示光标
               write_1602com(0x0f);            //设置光标为闪烁
    /*           temp=(miao)/10*16+(miao)%10;    //秒数据写入DS1302
               write_1302(0x8e,0x00);
               write_1302(0x80,0x80|temp);//miao
            write_1302(0x8e,0x80);  */
               break;
    case 2:  write_1602com(er+4);             //按2次fen位置显示光标
             write_1602com(0x0f);
            break;
    case 3: write_1602com(er+1);               //按动3次,shi
             write_1602com(0x0f);
            break;
    case 4: write_1602com(yh+0x0e);           //按动4次,week
             write_1602com(0x0f);
            break;
    case 5: write_1602com(yh+0x0a);           //按动5次,ri
             write_1602com(0x0f);
            break;
    case 6: write_1602com(yh+0x07);           //按动6次,yue
             write_1602com(0x0f);
            break;
    case 7: write_1602com(yh+0x04);           //按动7次,nian
             write_1602com(0x0f);
            break;
    case 8:
            write_1602com(0x0c);             //按动到第8次,设置光标不闪烁
            TR0=1;//打开定时器
            break;                                                            
            
    }

    }

    }

//------------------------------加键key2----------------------------        
    if(key1n!=0)                     //当key1按下以下。再按以下键才有效(按键次数不等于零)
    {

    if(temp1==0xde)                     //上调键
    {
    delay(10);
    if(temp1==0xde)
    {
 
    while(temp1!=0xde);
    switch(key1n)
    {
    case 1:miao++;                  //设置键按动1次,调秒
        if(miao==60)
            miao=0;           
            write_sfm(0x06,miao);   
            temp=(miao)/10*16+(miao)%10;//转为16进制
               write_1302(0x8e,0x00);
               write_1302(0x80,temp);   
               write_1302(0x8e,0x80);
            write_1602com(er+0x07);
            //write_1602com(0x0b);
            break;
    case 2:fen++;
        if(fen==60)
            fen=0;
            write_sfm(0x03,fen);         
            temp=(fen)/10*16+(fen)%10;  
               write_1302(0x8e,0x00);      
               write_1302(0x82,temp);      
               write_1302(0x8e,0x80);      
            write_1602com(er+4);     
            break;
    case 3:shi++;
        if(shi==24)
            shi=0;
            write_sfm(0x00,shi);            
            temp=(shi)/10*16+(shi)%10;   
               write_1302(0x8e,0x00);      
               write_1302(0x84,temp);     
               write_1302(0x8e,0x80);      
            write_1602com(er+1);      
            break;
    case 4:week++;
        if(week==8)
            week=1;
           write_1602com(yh+0x0b) ;   
            write_week(week);      
            temp=(week)/10*16+(week)%10;
               write_1302(0x8e,0x00);      
               write_1302(0x8a,temp);      
               write_1302(0x8e,0x80);      
            write_1602com(yh+0x0c);
            break;
    case 5:ri++;
        if(ri==32)
            ri=1;
            write_nyr(8,ri);            
            temp=(ri)/10*16+(ri)%10;   
               write_1302(0x8e,0x00);     
               write_1302(0x86,temp);      
               write_1302(0x8e,0x80);      
            write_1602com(yh+9);      
            break;
    case 6:yue++;
        if(yue==13)
            yue=1;
            write_nyr(5,yue);            
            temp=(yue)/10*16+(yue)%10;  
               write_1302(0x8e,0x00);      
               write_1302(0x88,temp);      
               write_1302(0x8e,0x80);      
            write_1602com(yh+6);      
            break;
    case 7:nian++;
         if(nian==100)
            nian=0;
            write_nyr(2,nian);            
            temp=(nian)/10*16+(nian)%10;  
               write_1302(0x8e,0x00);      
               write_1302(0x8c,temp);
               write_1302(0x8e,0x80);      
            write_1602com(yh+3);      
            break;
            

    }

    }

    }

//------------------减键key3,各句功能参照'加键'注释---------------
    if(temp1==0xbe)
    {
    delay(10);                        //调延时,消抖动
    if(temp1==0xde)
    {
   
    while(temp1!=0xde);
    switch(key1n)
    {
        case 1:miao--;
            if(miao==-1)
                miao=59;  
                write_sfm(0x06,miao);
                temp=(miao)/10*16+(miao)%10;
                   write_1302(0x8e,0x00);     
                   write_1302(0x80,temp);   
                  write_1302(0x8e,0x80);   
               write_1602com(er+0x07);   
                //write_1602com(0x0b);
                break;
        case 2:fen--;
            if(fen==-1)
                fen=59;
                write_sfm(3,fen);
                temp=(fen)/10*16+(fen)%10;
                  write_1302(0x8e,0x00);
                 write_1302(0x82,temp);
                write_1302(0x8e,0x80);
               write_1602com(er+4);
                break;
        case 3:shi--;
             if(shi==-1)
                shi=23;
            write_sfm(0,shi);
            temp=(shi)/10*16+(shi)%10;
               write_1302(0x8e,0x00);
               write_1302(0x84,temp);
               write_1302(0x8e,0x80);
            write_1602com(er+1);
            break;
        case 4:week--;
                if(week==0)
                    week=7;
          write_1602com(yh+0x0b);
            write_week(week);
            temp=(week)/10*16+(week)%10;
               write_1302(0x8e,0x00);
               write_1302(0x8a,temp);
               write_1302(0x8e,0x80);
            write_1602com(yh+0x0c);
            break;
        case 5:ri--;
                if(ri==0)
                    ri=31;
            write_nyr(8,ri);
            temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码
               write_1302(0x8e,0x00);//允许写,禁止写保护
               write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码
               write_1302(0x8e,0x80);//打开写保护
            write_1602com(yh+9);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
            break;

        case 6:yue--;
                if(yue==0)
                    yue=12;
            write_nyr(5,yue);
            temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码
               write_1302(0x8e,0x00);//允许写,禁止写保护
               write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码
               write_1302(0x8e,0x80);//打开写保护
            write_1602com(yh+6);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
            break;   
        case 7:nian--;
         if(nian==-1)
            nian=99;
            write_nyr(2,nian);
            temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码
               write_1302(0x8e,0x00);//允许写,禁止写保护
               write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码
               write_1302(0x8e,0x80);//打开写保护
            write_1602com(yh+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
            break;
            
               
    }

    }

    }

    }
}
}
void init()                             //定时器、计数器设置函数
{
    TMOD=0x01;                      //指定定时/计数器的工作方式为1
    TH0=(65536-100000)/256; //对T0定时器装值
    TL0=(65536-100000)%256;
    EA=1;                            //系统允许有开放的中断
    ET0=1;                           //允许T0中断
    TR0=1;                           //开启中断,启动定时器

}



void main()
{
   
    lcd_init();                          //调用液晶屏初始化子函数
    ds1302_init();                      //调用DS1302时钟的初始化子函数
    init();                             //调用定时计数器的设置子函数
//    led=0;                            //打开LCD的背光电源
    key1n=1;   
//    buzzer=0;                         //蜂鸣器长响一次
 //   delay(80);
//    buzzer=1;

    while(1)                          //无限循环下面的语句:
    {
            
    keyscan();                         //调用键盘扫描子函数
   
    }
}
void timer0() interrupt 1                 //取得并显示日历和时间
{
    TH0=(65536-100000)/256; //对T0定时器重装初值
        TL0=(65536-100000)%256;


//it_DS18B20();            //温度传感器DS18b2初始化子函数,在头文件中
 // flag=ReadTemperature();      //将18b2头文件运行返回的函数结果送到变量flag中,用于显示
  //读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
    miao = BCD_Decimal(read_1302(0x81));
    fen = BCD_Decimal(read_1302(0x83));
    shi  = BCD_Decimal(read_1302(0x85));
    ri  = BCD_Decimal(read_1302(0x87));
    yue = BCD_Decimal(read_1302(0x89));
    nian=BCD_Decimal(read_1302(0x8d));
    week=BCD_Decimal(read_1302(0x8b));

    //显示温度、秒、时、分数据:
   
//   write_temp(9,flag);//显示温度,从第二行第9个字符后开始显示
    write_sfm(6,miao);//秒,从第二行第6个字后开始显示(调用时分秒显示子函数)
    write_sfm(3,fen);//分,从第二行第3个字符后开始显示
    write_sfm(0,shi);//小时,从第二行第1个字符后开始显示
   
    //显示日、月、年数据:
    write_nyr(8,ri);//日期,从第二行第8个字符后开始显示
    write_nyr(5,yue);//月份,从第二行第5个字符后开始显示
    write_nyr(2,nian);//年,从第二行第2个字符后开始显示
    write_week(week);

}


搜索更多相关主题的帖子: 万年历 include 键盘 硬件 
2015-11-09 21:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-459042-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.197250 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved