找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2700|回复: 2
收起左侧

求帮助,按键五按下是记录下当前1602显示的时间,按下按键六会显示出保存的时间,...

[复制链接]
ID:233394 发表于 2017-11-5 21:57 | 显示全部楼层 |阅读模式
#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
#include<intrins.h>
#define LCD1602_DATAPINS P0
#define uchar unsigned char
#define uint unsigned int
uchar m=50,f=5,s=12;
uchar nu,count,g,n,a,v,p,flag,flag1;
sbit LCD1602_RW=P0^3;
sbit LCD1602_RS=P2^6;
sbit LCD1602_E=P2^7;
sbit k1=P2^0;
sbit k2=P2^1;
sbit k3=P2^2;
sbit k4=P2^3;
sbit k5=P1^0;
sbit k6=P1^1;
sbit beep=P1^5;
sbit SCL=P2^1;
sbit SDA=P2^0;
void writekey(uchar key);
void writenum(uchar num);
void write_sfm(uchar add,uchar date);
void bee1(void);
void bee2(void);
void bee4(void);
void bee3(void);
void jian(void);
void I2cStart();
void I2cStop();
unsigned char I2cSendByte(unsigned char dat);
unsigned char I2cReadByte();
void At24c02Write(unsigned char addr,unsigned char dat);
unsigned char At24c02Read(unsigned char addr);
void Keypros(void);
uchar code table[]="12:05:50";
uchar code table1[]="12:06:06";
uchar code table2[]="start";
void delay1(uint o)  //o=1,10us
{
while(o--);
}
void delay(uint z)  //按键延时
{   
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Delay10us()   // 延时10us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
void Lcd1602_Delay1ms(uint c)   //1ms
{
    uchar a,b;
for (; c>0; c--)
{for (b=199;b>0;b--)
{for(a=1;a>0;a--);}}
}
void writekey(uchar key) //写指令
{
    LCD1602_E=0;    //使能清零
LCD1602_RS=0;    //选择写入命令
LCD1602_RW=0;    //选择写入
LCD1602_DATAPINS=key; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E=1;    //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
LCD1602_DATAPINS=key<<4;  //发送低四位
Lcd1602_Delay1ms(1);
LCD1602_E=1;    //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
void writenum(uchar num)   //写数据
{
    LCD1602_E=0;     //使能清零
LCD1602_RS=1;     //选择写入数据
LCD1602_RW=0;     //选择写入
LCD1602_DATAPINS=num; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E=1;     //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
LCD1602_DATAPINS=num<<4; //写入低四位
Lcd1602_Delay1ms(1);
LCD1602_E=1;     //写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
void init()
{
writekey(0x32);     //将8位总线转为4位总线
writekey(0x28);     //在四位线下的初始化
writekey(0x0c);     //开显示不显示光标
writekey(0x06);     //写一个指针加1
writekey(0x01);     //清屏
writekey(0x80);     //设置数据指针起点
}
void init1(void)
{
SCON=0X50;    //设置为工作方式1
    TMOD|=0x20;             //定时器初始化
PCON=0X80;    //波特率加倍
TH1=0XF3;    //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
ES=1;     //打开接收中断
    EA=1;
TR1=1;     //打开计数器
}
void init2(void)
{  
    TMOD|=0x01;                  //定时器初始化
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    EA=1;
    ET0=1;
    TR0=1;
    for(n=0;n<8;n++)
    {
        writenum(table[n]);
    }
writekey(0x80+0x40);    //显示闹钟时间
for(nu=0;nu<8;nu++)
    {
        writenum(table1[nu]);
    }
}
void write_sfm(uchar add,uchar date)  //读出时分秒变量
{
    uchar shi,ge;
    shi=date/10;      //十位
    ge=date%10;       //个位
    writekey(0x80+add);     //显示的位置
    writenum(0x30+shi);     //显示十位
    writenum(0x30+ge);     //显示个位
}
void I2cStart()  // 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿,起始之后SDA和SCL都为0
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//建立时间是SDA保持时间>4.7us
SDA=0;
Delay10us();//保持时间是>4us
SCL=0;   
Delay10us();  
}
void I2cStop()   // 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
{       //结束之后保持SDA和SCL都为1;表示总线空闲
SDA=0;
Delay10us();
SCL=1;
Delay10us();//建立时间大于4.7us
SDA=1;
Delay10us();  
}
unsigned char I2cSendByte(unsigned char dat)   //通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定
{            // 0或1。发送成功返回1,发送失败返回0,发送完一个字节SCL=0,SDA=1
unsigned char a=0,b=0;  //最大255,一个机器周期为1us,最大延时255us。  
for(a=0;a<8;a++)   //要发送8位,从最高位开始
{
  SDA=dat>>7;     //起始信号之后SCL=0,所以可以直接改变SDA信号
  dat=dat<<1;
  Delay10us();
  SCL=1;
  Delay10us();   //建立时间>4.7us
  SCL=0;
  Delay10us();   //时间大于4us  
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)  //等待应答,也就是等待从设备把SDA拉低
{
  b++;
  if(b>200)  //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
  {
   SCL=0;
   Delay10us();
   return 0;
  }
}
SCL=0;
Delay10us();
  return 1;  
}
unsigned char I2cReadByte()    //使用I2c读取一个字节,接收完一个字节SCL=0,SDA=1.
{
unsigned char a=0,dat=0;
SDA=1;   //起始和发送一个字节之后SCL都是0
Delay10us();
for(a=0;a<8;a++)//接收8个字节
{
  SCL=1;
  Delay10us();
  dat<<=1;
  dat|=SDA;
  Delay10us();
  SCL=0;
  Delay10us();
}
return dat;         
}
void At24c02Write(unsigned char addr,unsigned char dat)// 往24c02的一个地址写入一个数据
{
I2cStart();
I2cSendByte(0xa0);//发送写器件地址
I2cSendByte(addr);//发送要写入内存地址
I2cSendByte(dat); //发送数据
I2cStop();
}
unsigned char At24c02Read(unsigned char addr) // 读取24c02的一个地址的一个数据
{
unsigned char num;
I2cStart();
I2cSendByte(0xa0); //发送写器件地址
I2cSendByte(addr); //发送要读取的地址
I2cStart();
I2cSendByte(0xa1); //发送读器件地址
num=I2cReadByte(); //读取数据
I2cStop();
return num;
}
void bee1(void)         //模式一
{
while(1)
{
  beep=0;
  delay1(20);      //延时大约200us  通过修改此延时时间达到不同的发声效果
  beep=1;
  delay1(20);
  if(s==12&&f==6&&m==11)    //自动到12:06:09退出或者按键到12:06:06退出
  break;
}
}
void bee2(void)         //模式二
{
  while(1)
{
  beep=0;
  delay1(40);       //延时大约400us  通过修改此延时时间达到不同的发声效果
  beep=1;
  delay1(40);
  if(s==12&&f==6&&m==6)     //提前5秒叫,5秒以后尖叫
  {
   while(1)
   {
    beep=0;
    delay1(10);      //延时大约100us  通过修改此延时时间达到不同的发声效果
    beep=1;
    delay1(10);
    if(s==12&&f==6&&m==11)
    break;
      }
  }
  if(s==12&&f==6&&m==11)
  break;
}
}
void bee4(void)
{
while(1)
{
  beep=0;
  delay1(20);      //延时大约200us  通过修改此延时时间达到不同的发声效果
  beep=1;
  delay1(20);
  if((m==11)||(m==41))      
  break;
}
}
void bee3(void)
{
if(k4==0)     //k5按键按下
    {
       delay(5);
       if(k4==0)
       {      
     while(!k4);
     g++;
       }
     }
  if(g==1)
  {
   if(s==12&&f==6&&m==1)
   {bee2();}
  }
   
  if(g==2)
  {
   if(s==12&&f==6&&m==6)
   {bee1();}
  }
  if(g==3)
  {
   if(s==12&&f==6&&m==1)
   bee1();
   if((m==1)||(m==31))
   bee4();
  }   
}                     
void jian(void)      //按键设置
{
uchar as;     //计算按键三按下次数
    if(k3==0)
    {
     delay(5);
     if(k3==0)
        {     
          as++;
          while(!k3);
  }
    }                  
    if(as==1)     //按键三按下一次为秒针设置
    {
       TR0=0;    //关闭计时
       writekey(0x0f);    //开光标闪烁
       writekey(0x80+7);    //位置
       if(k1==0)
       {
          delay(5);
          if(k1==0)
          {
             m++;
    while(!k1);
             if(m==60)
             {
                m=0;
             }
             write_sfm(6,m);
           }
        }
      if(k2==0)
      {
         delay(5);
         if(k2==0)
         {
            m--;
   while(!k2);
            if(m==-1)
            {
               m=59;
            }
            write_sfm(6,m);
         }
      }                           
    }
        if(as==2)  //分针设置
        {     
           TR0=0;
           writekey(0x0f);
           writekey(0x80+4);
           if(k1==0)
           {
              delay(5);
              if(k1==0)
              {
                 f++;
     while(!k1);
                 if(f==60)
                 {
                    f=0;
                 }
                  write_sfm(3,f);
               }
             }
   if(k2==0)
            {
               delay(5);
               if(k2==0)
               {
                   f--;
     while(!k2);
                    if(f==-1)
                    {
                       f=59;
                    }
                    write_sfm(3,f);
                }
             }
    }
  if(as==3)  //时针设置
        {     
           TR0=0;
           writekey(0x0f);
           writekey(0x80+1);
           if(k1==0)
           {
               delay(5);
               if(k1==0)
               {
                   s++;
     while(!k1);
                    if(s==24)
                    {
                        s=0;
                    }
                    write_sfm(0,s);
                }
             }
                if(k2==0)
                {
                    delay(5);
                    if(k2==0)
                    {
                       s--;
      while(!k2);
                       if(s==-1)
                        {
                          s=23;
                        }
                        write_sfm(0,s);
                    }
                 }
            }
         if(as==4)  //时间自己走走动
         {
            TR0=1;
            writekey(0x0c);
         }
  if(as==4)  //时间走动
        {
            TR0=1;
            writekey(0x0c);
            as=0;            
         }
}
void Keypros(void)
{
if(k5==0)
{   
  delay(5);  //消抖处理
  if(k5==0)
  {
   At24c02Write(1,s);
   At24c02Write(2,f);
   At24c02Write(3,m);
  }
  while(!k5);
}
if(k6==0)
{
  delay(5);   //消抖
  if(k6==0)
  {
   s=At24c02Read(1);
   write_sfm(0,s);
   f=At24c02Read(2);   
   write_sfm(3,f);
   m=At24c02Read(3);
    write_sfm(6,m);
  }
  while(!k6);
}  
}
void main(void)
{   
init1();
init();
while(1)
{
  if(flag==1)
  {
   writekey(0x80+0x40+9);
   for(v=0;v<5;v++)
      {
          writenum(table2[v]);
      }  
   Lcd1602_Delay1ms(1000);
   flag1=1;
   writekey(0x01);   
  }
  if(flag1==1)
  break;
}
init2();  
while(1)
{
  jian();
  bee3();
  Keypros();
}
}

void timer0() interrupt 1   //重装初值
{
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    count++;
    if(count==20)      //1s
    {
        m++;
        count=0;
        if(m==60)
        {
   m=0;f++;
         if(f==60)
         {
    f=0;s++;
          if(s==24)
          {
     s=0;
    }
         write_sfm(0,s);     //写入小时
          }
          write_sfm(3,f);      //写入分钟
         }
         write_sfm(6,m);    //写入秒
     }
}
void Usart() interrupt 4
{
a=SBUF;   //接收到的数据
RI=0;   //清除接收中断标志位,取消中断
flag=1;   //标志,看是否已经执行过串口中断
}



例如存的应该是06;可是显示的是17。。求助啊,大佬们
回复

使用道具 举报

ID:82765 发表于 2017-11-6 13:07 来自手机 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

ID:233394 发表于 2017-11-7 20:17 | 显示全部楼层
cjjcjj1 发表于 2017-11-6 13:07
注意一下进制转换

进制转换什么意思?具体点。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表