微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 矩阵键盘调节DS1302数码管显示

矩阵键盘调节DS1302数码管显示

时间:10-02 整理:3721RD 点击:
求助,虽然能正常显示时分秒年月日,但调节时间这块老不成功,已经调了很久,一直不知道是为什么,现在把代码贴出来求高手指点,有仿真原理图
/********H文件****************/
#ifndef _123_H__
#define __123_H__
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dsclk=P3^1;//ds时钟输入端
sbit dsdata=P3^2;//ds数据双向通信端
sbit dsret=P3^0;//ds 复位端
uchar code tabled[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};//数码管0-9数字
uchar code tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0Xbf,0X7f};//数码管显示位选端
void show();
void get_time();
uchar read(uchar address);
void write(uchar address,uchar number);
void delay(uchar i);
uchar GetKey(void);
uchar Keyscan(void) ;
#endif
/********C文件****************/
#include"123.h"
uchar a,w,adjust_flag=0;
uchar  buf[8];//申请数据暂存空间
uchar current_time[7];
/**************************************************************
* 名称: delay(uchar i)
* 功能: 延时
* 输出:
***************************************************************/
void delay(uchar i)
{
while(--i);
}
/**************************************************************
* 名称: read(uchar address)
* 功能: 从DS1302指定位置读数据
* 输出: address
***************************************************************/
uchar read(uchar address)
{
  uchar i;
  dsclk=0;
  dsdata=0;
  dsret=0;
  dsret=1;//ret处于高电平时可对1302进行读操作
  for(i=0;i<8;i++)
   {
    dsclk=0;//上升沿时进行写数据
    dsdata=address&0x01;//数据传送都是从低位开始
    address=address>>1;//右移一位
    dsclk=1;//上升沿写数据
   }
  for(i=0;i<8;i++)
   {
    dsclk=0;//上升沿动作
    address=address>>1;
   if(dsdata)
    address=address|0x80;
    dsclk=1;//上升沿动作
    dsclk=1;//等待
   }
   dsclk=1;//时钟置高
   dsret=0;//片选无效
   return (address);
}
/**************************************************************
* 名称: write(uchar address,uchar number)
* 功能: 向DS1302某地址写数据
* 输出:
***************************************************************/
void write(uchar address,uchar number)
{
   uchar i;
   dsclk=0;//清零时钟总线
   dsdata=0;//清零数据总线
   dsret=0;//片选端无效
   dsret=1;//逻辑控制有效,可对1302操作
   for(i=16;i>0;i++)
    {
     dsclk=0;
     if(i>8)
      {
       dsdata=address&0x01;//低地址输入
       address=address>>1;//地址数据右移一位
      }
     else
     {
      dsdata=number&0x01;//进行数据传送
      number=number>>1;//数据右移一位
     }
     dsclk=1;
    }
    dsclk=1;//上升沿动作
    dsret=0;//片选无效,不可进行操作
}
/**************************************************************
* 名称: show()
* 功能: 实时显示时间与日期
* 输出:
***************************************************************/
void show()
{
uchar i;
for(i=0;i<8;i++)
{
  P0=~tabled[buf[i]];//P0数据输出
  P2=tab[i];
  delay(100);
  P2=0xff;
}
}
/**************************************************************
* 名称: get_time()
* 功能: 从DS1302的相关寄存器里读出当前时间值和日期值
* 输出:
***************************************************************/
void get_time()
{
   current_time[0]=read(0x81);
   current_time[1]=read(0x83);
   current_time[2]=read(0x85);
   current_time[3]=read(0x87);
   current_time[4]=read(0x89);
   current_time[5]=read(0x8d);
}
/**************************************************************
* 名称: settime_ds1302(uchar add,uchar value)
* 功能: 设置时间函数
* 输出:
***************************************************************/
void settime_ds1302(uchar add,uchar value)
     {//地址为80h,82h,84h,86h,88h,8ch
      write(0x8e,0x00);
   write(0x8e,0x00);
      write(add,((value/10)<<4|(value%10)));
   write(0x8e,0x80);
     }
/**************************************************************
* 名称: Keyscan()
* 功能: P1外接4×4按键, 按照扫描法读出键值
* 输出: 按键值0~15/如无键按下, 返回16
***************************************************************/
uchar Keyscan(void)
{
    uchar i, j, temp, key_Buffer[4] = {0xef,0xdf,0xbf,0x7f};
    for(j = 0; j < 4; j++) //循环四次
{
      P1 = key_Buffer[j]; //在P3高四位分别输出一个低电平
      temp = 0x01;       //计划先判断P3.0位
      for(i = 0; i < 4; i++)//循环四次
   {
        if(!(P1 & temp)) //从P3低四位,截取1位
        return (i + j * 4); //返回取得的按键值
        temp <<= 1;  //判断的位,左移一位
     }
}
    return 16; //判断结束,没有键按下,返回16
}  
/**************************************************************
* 名称: GetKey()
* 功能: 读出按键、消抖、等待按键释放
* 输出: 按键值0~15/如无键按下, 返回16
***************************************************************/
uchar GetKey()
{
    uchar  Key_Temp1, Key_Temp2; //两次读出的键值
    P1 = 0xff;
    Key_Temp1 = Keyscan();       //先读入按键
    if(Key_Temp1 == 16)  return 16; //没有键按下,返回16
    show();                //用显示代替延时
    Key_Temp2 = Keyscan();       //再读一次按键
    if(Key_Temp1 != Key_Temp2)  return 16; //不同,返回16
    while(Keyscan() < 16)    //等待按键释放
     show();          //等待期间显示
    return Key_Temp1;
}  
void main()
{
  uchar Key_Value;
  while(1)
  {
   if(adjust_flag==0)get_time();
   buf[0]=current_time[2]/16;//小时数据转换成十进制
   buf[1]=current_time[2]%16;//小时数据转换成十进制
   buf[2]=0x0A;//小时与分之间的横线
   buf[3]=current_time[1]/16;//分数据转换成十进制
   buf[4]=current_time[1]%16;//分数据转换成十进制
   buf[5]=0x0A;//分与秒之间的横线
   buf[6]=current_time[0]/16;//秒数据转换成十进制
   buf[7]=current_time[0]%16;//秒数据转换成十进制
   show();//将时间通过数码管进行显示
   if(GetKey()==10)
    {
  adjust_flag=1;
  while(adjust_flag==1)
   {
    Key_Value=GetKey();
    w++;
    if(Key_Value<10)
     {
    current_time[0]%=10;
    current_time[0]=current_time[0]*10+Key_Value;
  }
  buf[6]=current_time[0]/16;//秒数据转换成十进制
        buf[7]=current_time[0]%16;//秒数据转换成十进制   
  show();
  if(Key_Value==10)
   {
    settime_ds1302(0x80,current_time[0]);
    settime_ds1302(0x82,current_time[1]);
    settime_ds1302(0x84,current_time[2]);
    adjust_flag=0;
   }
   }
}
}  
}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top