微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机DS1302模块编程的时候,实验效果:秒显示每四秒更新一次,而不是一秒

51单片机DS1302模块编程的时候,实验效果:秒显示每四秒更新一次,而不是一秒

时间:10-02 整理:3721RD 点击:
#include<reg51.h>
#include<intrins.h>
//定义DS1302使用的端口
sbit DSIO=P3^4;
sbit SCLK=P3^6;
sbit CE=P3^5;
//定义LCD使用的端口
sbit LCD_E=P2^7;
sbit LCD_RW=P2^5;
sbit LCD_RS=P2^6;
#define LCDIO P0
unsigned char code ds1302readaddr[7]={0x8B,0x81,0x83,0x85,0x87,0x89,0x8D};//读寄存器地址
unsigned char code ds1302writeaddr[7]={0x8A,0x80,0x82,0x84,0x86,0x88,0x8C};//写寄存器地址
unsigned char Time[7]={0x01,0,0,0,0x14,0x08,0x17};//星期 秒 分 时 日 月 年        //初始时间2017年8月3日00点00分00秒星期四  BCD码表示
void lcddisplay();
void ds1302write(unsigned char addr,unsigned char dat);
unsigned char ds1302read(unsigned char addr);
void ds1302init();
void ds1302readtime();
void lcd1602writecom(unsigned char com);
void lcd1602writedata(unsigned char dat);
void lcdinit();
void delayms(unsigned char c);
void main()           //主程序,显示时间
{
   lcdinit();//初始化LCD
   ds1302init();//初始化ds1302
   while(1)
  {
    ds1302readtime();//读取ds1302的数据
    lcddisplay();//lcd显示ds1302的数据
  }
}
void lcddisplay()
{
  lcd1602writecom(0x80);//在第一行显示
  lcd1602writedata('0'+Time[3]/16);
  lcd1602writedata('0'+(Time[3]&0x0f));         //时
  lcd1602writedata(':');
  lcd1602writedata('0'+Time[2]/16);
  lcd1602writedata('0'+(Time[2]&0x0f));          //分
  lcd1602writedata(':');
  lcd1602writedata('0'+Time[1]/16);
  lcd1602writedata('0'+(Time[1]&0x0f));         //秒
  lcd1602writecom(0xc0);
  lcd1602writedata('2');
  lcd1602writedata('0');
  lcd1602writedata('0'+Time[6]/16);                //年十位
  lcd1602writedata('0'+(Time[6]&0x0f));        //年个位
  lcd1602writedata('-');
  lcd1602writedata('0'+Time[5]/16);                //月十位
  lcd1602writedata('0'+(Time[5]&0x0f));        //月个位
  lcd1602writedata('-');
  lcd1602writedata('0'+(Time[4]/16));        //日十位
  lcd1602writedata('0'+(Time[4]&0x0f));        //日个位
  lcd1602writedata('-');
  lcd1602writedata('0'+(Time[0]&0x07));        //周
}

//DS1302程序段
//写入地址和数据
void ds1302write(unsigned char addr,unsigned char dat)
{
   unsigned char n;
   CE=0;
   SCLK=0;
   CE=1;
  for(n=0;n<8;n++)  //写入地址码
  {
   DSIO=addr&0x01;
   addr>>=1;
   SCLK=1;
   SCLK=0;
   }  
   for(n=0;n<8;n++)  //写入数据码
  {
   DSIO=dat&0x01;
   dat>>=1;
   SCLK=1;
   SCLK=0;
   }  
   CE=0;
}
unsigned char ds1302read(unsigned char addr)//读取数据
{
  unsigned char n,dat1,dat;
   CE=0;
   SCLK=0;
   CE=1;
   for(n=0;n<8;n++)
   {
   DSIO=addr&0x01;
   addr>>=1;
   SCLK=1;
   SCLK=0;
   }
   _nop_();
   for(n=0;n<8;n++)
   {
    dat1=DSIO&0x01;
    dat1=dat1<<7;
    dat=(dat>>1)|(dat1);
    SCLK=1;
    SCLK=0;
   }
   CE=0;
   _nop_();
   SCLK=1;
   _nop_();
   DSIO=0;
  _nop_();
   DSIO=1;
  _nop_();
  return dat;
}
void ds1302init() //初始化DS1302
{
  unsigned char n;
  ds1302write(0x8E,0x00);     //关闭写保护
  for(n=0;n<7;n++)
{
  ds1302write(ds1302writeaddr[n],Time[n]);
}
ds1302write(0x8E,0x80);     //开启写保护
}

void ds1302readtime() //读取时钟信息
{
  unsigned char n;
  for(n=0;n<7;n++)
  {
   Time[n]=ds1302read(ds1302readaddr[n]);
   }
}
//LCD程序段
void lcd1602writecom(unsigned char com)    //lcd1602写命令程序
{
   LCD_E=0;                 //使能端为0
   LCD_RS=0;                //数据命令端为0,代表命令
   LCD_RW=0;                //读写端为0,代表写入
   LCDIO=com;               //输入端输入一个命令字节
   delayms(4);             //延迟40ns
   LCD_E=1;                 
   delayms(15);            //使能端至少延迟150ns
   LCD_E=0;                 //复位
}
void lcd1602writedata(unsigned char dat)    //lcd1602写数据程序
{
   LCD_E=0;                 //使能端为0
   LCD_RS=1;                //数据命令端为1,代表数据
   LCD_RW=0;                //读写端为0,代表写入
   LCDIO=dat;               //输入端输入一个命令字节
   delayms(4);             //延迟40ns
   LCD_E=1;                 
   delayms(15);            //使能端至少延迟150ns
   LCD_E=0;                 //复位
}
void lcdinit()                //初始化LCD1602
{
  lcd1602writecom(0x38);
  lcd1602writecom(0x0c);
  lcd1602writecom(0x06);
  lcd1602writecom(0x01);
  lcd1602writecom(0x80);
}
void delayms(unsigned char c)   //误差 0us
{
    unsigned char a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}

你在void ds1302readtime() 函数中加一个延时四秒的函数

能告诉我具体是哪个吗?我真没看出来

LCDIO=dat;               //输入端输入一个命令字节
   delayms(4);             //延迟40ns
   LCD_E=1;                 
   delayms(15);            //使能端至少延迟150ns
   LCD_E=0;                 //复位
这里可以不用delayms(),加几个 _nop_();就行了,最好能写个1602的查忙程序,看1602的手册有说明。
4秒刷新一次,时间是否连续的,另外4秒刷新一次这个时间是否是稳定的。

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

网站地图

Top