找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3024|回复: 9
打印 上一主题 下一主题
收起左侧

基于1602的ds1302驱动 这个地方的IO为什么要这么操作,谁能解释一下

[复制链接]
跳转到指定楼层
楼主
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int


sbit lcden=P2^7;
sbit lcdrw=P2^5;
sbit lcdrs=P2^6;
sbit T_CLK=P3^6;
sbit T_IO=P3^4;
sbit T_RST=P3^5;
uchar bdata datbyte;
sbit datbyte0=datbyte^0;
sbit datbyte7=datbyte^7;  

uchar code table1[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};                         //读地址命令
uchar code table2[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};                        //写地址命令
uchar  time[7]={0,0,0x08,0x01,0x10,0x06,0x16};
char week[21]={'M','o','n','T','u','e','W','e','d','T','u','e','F','r','i','S','a','t','S','u','n'};

void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)
                for(j=110;j>0;j--);
}


void writeorder(uchar order)                   //1602写命令函数
{
        lcdrs=0;
        P0=order;
        delayms(5);
        lcden=1;
        delayms(5);
        lcden=0;
}


void writedate(uchar date)                          //1602写数据函数
{
        lcdrs=1;
        P0=date;
        delayms(5);
        lcden=1;
        delayms(5);
        lcden=0;
}


void lcdinit()                                                  //1602初始化函数
{
        lcdrw=0;
        writeorder(0x38);
        writeorder(0x0c);
        writeorder(0x06);
        writeorder(0x01);
}
/*************1302写入一个字节*/
void w_1302byte(uchar date)
{
        uchar i;
        datbyte=date;
        for(i=0;i<8;i++)
        {         
                T_CLK=0;  _nop_();
                T_IO=datbyte0;
                T_CLK=1;  _nop_();
                datbyte>>=1;
        }
}
  /************1302读取一个字节********/
uchar r_1302byte(void)
{
        uchar i;
        datbyte=0;
        for(i=0;i<8;i++)
        {
                T_CLK=1;        _nop_();
                datbyte7=T_IO;
                _nop_();
                T_CLK=0; _nop_();
                datbyte>>=1;
        }
        return(datbyte);
}
/**********1302写数据**********/
void write_1302(uchar addr,uchar date)
{
        T_RST=0;
        _nop_();
        T_CLK=0; _nop_();
        T_RST=1;_nop_();
        w_1302byte(addr);
        w_1302byte(date);
        T_CLK=1;  _nop_();
        T_RST=0;  _nop_();
}

/******1302读取一个字节*******/
uchar read_1302(uchar addr)
{
        uchar dat1,dat2,temp;
        T_RST=0; _nop_();
        T_CLK=0; _nop_(); ///sclk为低时rst才能拉高
        T_RST=1;_nop_();
        w_1302byte(addr);
        temp=r_1302byte();
        T_RST=0;        _nop_();
        T_CLK=1;   _nop_();
        T_IO=0;                  
        _nop_();
        T_IO=1;
        _nop_();
        //dat1=temp/16;
        //dat2=temp%16;
        //temp=dat1*10+dat2;
        return(temp);
}


/***********1302初始化********/
void init_1302(void)
{
        uchar i;
        uchar addr=0x80;
        write_1302(0x8e,0x00);
        for(i=0;i<7;i++)
    {
                write_1302(addr,time);
                addr+=2;
        }
        write_1302(0x8e,0x80);
}

        /*******1302的八个数据读取*******/
void get_1302(void)
{
        uchar i,addr=0x81;
        for(i=0;i<7;i++)
        {
                time=read_1302(addr);
                addr+=2;
        }
}



void display()
{
        int n;
        writeorder(0x80+0X40);
        writedate('0'+time[2]/16);                                
        writedate('0'+(time[2]&0x0f));                                 
        writedate('-');
        writedate('0'+time[1]/16);                                
        writedate('0'+(time[1]&0x0f));        
        writedate('-');
        writedate('0'+time[0]/16);                        
        writedate('0'+(time[0]&0x0f));

        writeorder(0x80);
        writedate('2');
        writedate('0');
        writedate('0'+time[6]/16);                        
        writedate('0'+(time[6]&0x0f));
        writedate('-');
        writedate('0'+time[4]/16);               
        writedate('0'+(time[4]&0x0f));
        writedate('-');
        writedate('0'+time[3]/16);                        
        writedate('0'+(time[3]&0x0f));
        writeorder(0x8c);
        for(n=0;n<3;n++)                                                   //星期显示函数
        {
        writedate(week[(3*(time[5]&0x07)-3)+n]);
        }                        
}

void main()
{
        lcdinit();
         init_1302();
        while(1)
        {
                //readtime();
                get_1302();
                display();        
        }
}

评分

参与人数 1黑币 +80 收起 理由
admin + 80 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:103094 发表于 2016-10-16 14:41 | 只看该作者
本帖最后由 45555mkkl 于 2016-10-16 14:42 编辑

/******1302读取一个字节*******/
uchar read_1302(uchar addr)
{
        uchar dat1,dat2,temp;
        T_RST=0; _nop_();
        T_CLK=0; _nop_(); ///sclk为低时rst才能拉高
        T_RST=1;_nop_();
        w_1302byte(addr);
        temp=r_1302byte();
        T_RST=0;        _nop_();
        T_CLK=1;   _nop_();
        T_IO=0;                 
        _nop_();
        T_IO=1;
        _nop_();/////这个地方的IO为什么要这么操作,谁能解释一下
        //dat1=temp/16;
        //dat2=temp%16;
        //temp=dat1*10+dat2;
        return(temp);
}
回复

使用道具 举报

板凳
ID:79544 发表于 2016-10-16 17:32 | 只看该作者
一个跳变沿,低电平变为高电平。1302的时序
回复

使用道具 举报

地板
ID:111634 发表于 2016-10-16 20:52 | 只看该作者
本帖最后由 zl2168 于 2016-10-16 20:53 编辑

实例90  开机显示PC机时间的时钟1302(LCD1602显示)


Proteus仿真一下,确认有效。
实例90 开机显示PC机时间的时钟1302(LCD1602显示).rar (50.36 KB, 下载次数: 6)



摘自张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版


书中电路和程序设计有详细说明,程序语句条条有注解。


回复

使用道具 举报

5#
ID:111634 发表于 2016-10-16 20:54 | 只看该作者
本帖最后由 zl2168 于 2016-10-16 21:01 编辑

实例91  具有校正功能的时钟1302(LCD1602显示)


电路设计
在上例时钟电路的基础上,加入3时钟修正按键:K0(修正)、K1(移位)和K2(加1),分别与80C51P2.7P2.5P2.3连接,7-6所示



程序设计


7-6电路,要求开机显示201211134758秒,星期日(7),且要求K0K1K2具有时钟校正功能,其控制过程为:按下K0(带锁),进入时钟修正;首先年数据(12)快速闪烁,表示可被修正;按一次K1(不带锁),被修正位(快速闪烁)按年、周、月、日、时、分、秒次序循环往复;按一次K2(不带锁),被修正位加1(最大值不超过时钟规定值,超过复0);时钟修正期间,计时继续运行;释放K0,退出时钟修正。
Proteus仿真
摘自张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版


实例91 带校正时钟1302(LCD1602显示).rar (52.74 KB, 下载次数: 6)




回复

使用道具 举报

6#
ID:123289 发表于 2016-10-17 13:27 | 只看该作者
T_IO=0                      ;P3.4输出0                        
_nop_()                       ;让低电平保持一下
T_IO=1                       ;P3.4输出1
_nop_()                      ;让高电平保持一下

其实:就是让P3.4产生一个上升沿
回复

使用道具 举报

7#
ID:103094 发表于 2016-10-17 18:33 | 只看该作者
腾飞的龙 发表于 2016-10-16 17:32
一个跳变沿,低电平变为高电平。1302的时序

时序上面没有数据口的这个操作吧?我记得只是需要对sclk和e进行操作
回复

使用道具 举报

8#
ID:137078 发表于 2016-10-17 20:17 | 只看该作者
1302的复位稳定时间,不可以少的。
回复

使用道具 举报

9#
ID:137078 发表于 2016-10-17 20:21 | 只看该作者
并不是SCLK的低电平变高电平的转换时的写入操作,而是为了1302复位,有个稳定时间。
回复

使用道具 举报

10#
ID:103094 发表于 2016-10-17 21:32 | 只看该作者
柳铁钢 发表于 2016-10-17 20:17
1302的复位稳定时间,不可以少的。

嗯,明白了,多谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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