用字节读取模式可以正常读取,burst模式能写,但是读出来是乱码。
一下是代码,哪位学长有空帮忙看下。
- /*********************************************************************
- VyoMeng 51单片机实习训练
-
- **********************************************************************
- 程序名称:DS1302 Burst模式读写
- 程序版本:V1.0
- 作 者: VyoMeng
- 编写时间:2021年09月11日
- 硬件支持:
- 接口说明:
- 修改日志:
- N0.1:
- **********************************************************************/
- /*
- **********************************************************************
- * 头文件包含/SFR定义
- **********************************************************************
- */
- #include<reg52.h>
- /*
- **********************************************************************
- * 本地数据类型/宏定义
- **********************************************************************
- */
- typedef signed char int8; //8位有符号字符型
- typedef signed int int16; //16位有符号整型
- typedef signed long int32; //32位有符号长整型
- typedef unsigned char uint8; //8位无符号字符型
- typedef unsigned int uint16; //16位无符号整型
- typedef unsigned long uint32; //32位无符号长整型
- /*
- **********************************************************************
- * 单片机IO口位定义
- **********************************************************************
- */
- sbit DS1302_CE = P2^3; //定义DS1302芯片CE引脚 使能引脚
- sbit DS1302_IO = P2^4; //定义DS1302芯片IO引脚 数据读写引脚
- sbit DS1302_SCLK = P2^5; //定义DS1302芯片SCLK引脚 锁存引脚
- sbit DX = P2^1; //定义数码管显示内容
- sbit WX = P2^2; //定义数码管显示位置
- /*
- **********************************************************************
- * 本地全局变量/数组定义
- **********************************************************************
- */
- uint8 code zifu[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x7f,0xbf,0xc8}; //数码管所有显示情况加入数组
- uint8 Time_Set[7] = {0x00,0x01,0x02,0x03,0x04,0x05,0x21}; //设置初始时间 2021年9月8日23点59分50秒周3
- uint8 tm[8]; //定义数组放读取出的时间数据
- /*
- **********************************************************************
- * 函数原型声明
- **********************************************************************
- */
- void DS1302Init();
- void delay(uint16 x_ms); //延迟 x_ms*1 毫秒
- void xiaoying();
- void DS1302ByteWrite(uint8 dat);
- uint8 DS1302ByteRead();
- void DS1302TimeWrite();
- void DS1302TimeRead(uint8 *time);
- /*********************************************************************
- *函数名称:main
- *函数功能:主函数
- *函数调用:
- *参数列表:无
- *返 回 值:无
- *结 果:
- *备 注:
- *********************************************************************/
- void main()
- {
- DS1302Init(); //初始化DS1302芯片
-
- while(1)
- {
- DS1302TimeRead(tm);
- //////////////////// 数码管第1位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X01; //显示位置在数码管 第1位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[3] >> 4]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第2位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X02; //显示位置在数码管 第2位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[3] & 0x0F]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第3位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X04; //显示位置在数码管 第3位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[4] >> 4]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第4位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X08; //显示位置在数码管 第4位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[4] & 0x0F]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
- //////////////////// 数码管第5位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X10; //显示位置在数码管 第5位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[5] >> 4]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第6位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X20; //显示位置在数码管 第6位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[5] & 0x0F]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第7位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X40; //显示位置在数码管 第7位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[6] >> 4]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
-
- //////////////////// 数码管第8位
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X80; //显示位置在数码管 第8位
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=zifu[tm[6] & 0x0F]; //写入数字
- DX=1; //给高电平
- DX=0; //给低电平 电平下衍 将显示内容写入数码管内容显示锁存器
- xiaoying(); //数码管消影
- }
- }
- /*********************************************************************
- *函数名称:DS1302Init
- *函数功能:初始化DS1302芯片
- *函数调用:DS1302Init();
- *参数列表:
- *返 回 值:无
- *结 果:
- *备 注:初始化DS1302
- *********************************************************************/
- void DS1302Init()
- {
- uint8 state;
- DS1302TimeRead(tm); //读取时间数据
- state = tm[0]; //读取秒位
- state = state >> 7; //数据右移7位,将CH值移到右边最低位
-
- if (state == 0x01) //如果CH值=1,说明时钟停止了,需要进行初始化
- {
- DS1302_CE = 1; //打开DS1302使能引脚
- DS1302ByteWrite(0x8E); //操作写保护位
- DS1302ByteWrite(0x00); //关闭写保护
- DS1302_CE = 0; //关闭DS1302使能引脚
-
- DS1302TimeWrite(); //写入初始时间
-
- DS1302_CE = 1; //打开DS1302使能引脚
- DS1302ByteWrite(0x8E); //操作写保护位
- DS1302ByteWrite(0x80); //打开写保护
- DS1302_CE = 0; //关闭DS1302使能引脚
-
- }
- }
- /*********************************************************************
- *函数名称:DS1302ByteWrite
- *函数功能:写入一个字节数据
- *函数调用:DS1302ByteWrite(uint8 dat);
- *参数列表:dat
- *返 回 值:无
- *结 果:
- *备 注:dat为时间日期的数据
- *********************************************************************/
- void DS1302ByteWrite(uint8 dat)
- {
- uint8 i;
- // DS1302_SCLK = 0; //拉低锁存器电平准备写入数据
- for(i=0;i<8;i++) //循环8次写入8组数据
- {
- DS1302_IO = dat & 0x01; //DS1302写入数据是从最低位开始写,所以先取最低为数值
- dat = dat >> 1; //取完最低位后将dat右移1位,将原来第2位数移到最低位
- DS1302_SCLK = 1; //拉高锁存器电平产生上升沿,写入数据
- DS1302_SCLK = 0; //拉高锁存器电平产生上升沿,写入数据
- }
- DS1302_IO =1;
- }
- /*********************************************************************
- *函数名称:DS1302ByteRead
- *函数功能:读取一个字节数据
- *函数调用:DS1302ByteRead();
- *参数列表:无
- *返 回 值:dat
- *结 果:返回读取到的时间数据
- *备 注:
- *********************************************************************/
- uint8 DS1302ByteRead()
- {
- uint8 i;
- uint8 dat=0; //先给dat赋值 0X00 即 0000 0000
- // DS1302_SCLK=0; //拉低锁存器电平准备写入数据
- for(i=0;i<8;i++) //循环8次读取8组数据
- {
- if (DS1302_IO == 0) //判断IO口数据是否为0
- {
- dat = dat << 1; //如果IO口为0,dat左移1位,左移最低位默认补0
- }
- else
- {
- dat = dat << 1; //如果IO口不为0,dat左移1位,最低位先补个0
- dat = dat | 0x01; //最低位或上0x01,最低位变成1
- }
- DS1302_SCLK = 1; //拉高锁存器电平产生上升沿,读入数据
- DS1302_SCLK = 0; //拉高锁存器电平产生上升沿,读入数据
- }
- return dat; //返回读取到的时间数据数组
- }
- /*********************************************************************
- *函数名称:DS1302TimeWrite
- *函数功能:读取一个字节数据
- *函数调用:DS1302TimeWrite();
- *参数列表:
- *返 回 值:无
- *结 果:
- *备 注:
- *********************************************************************/
- void DS1302TimeWrite()
- {
- uint8 i;
- DS1302_CE = 1; //打开DS1302使能引脚
- DS1302ByteWrite(0xBE); //开启burst写入模式,0XBE为burst写入地址
- for(i=0;i<7;i++) //循环7次,将 [年月日时分秒周] 七个字节写入
- {
- DS1302ByteWrite(Time_Set[i]); //从Time_Set数组里提取数值写入
- }
- DS1302ByteWrite(0x00); //burst模式一次要读写8个字节,实际日期总共7个字节,所以最后补充一个无意义的0x00字节
- DS1302_CE = 0; //关闭DS1302使能引脚
- }
- /*********************************************************************
- *函数名称:DS1302TimeRead
- *函数功能:读取一个字节数据
- *函数调用:DS1302TimeRead(uint8 *time);
- *参数列表:time
- *返 回 值:无
- *结 果:
- *备 注:
- *********************************************************************/
- void DS1302TimeRead(uint8 *time)
- {
- uint8 i;
- DS1302_CE = 1; //打开DS1302使能引脚
- DS1302ByteWrite(0xBF); //开启burst读取模式,0XBF为burst读取地址
- for (i=0;i<7;i++) //burst模式一次要读写8个字节,实际日期总共7个字节,所以最后一个无意义
- {
- time[i]=DS1302ByteRead(); //循环8次,将 [年月日时分秒周] 7个字节及保护字节读取出来
- }
- delay(3);
- DS1302_CE = 0; //关闭DS1302使能引脚
- }
- /*********************************************************************
- *函数名称:delay
- *函数功能:延时函数
- *函数调用:delay(uint16 x_ms);
- *参数列表:x_ms
- *返 回 值:无
- *结 果:延迟时间=1* x_ms(毫秒)
- *备 注:
- *********************************************************************/
- void delay(uint16 x_ms) //延迟 x_ms*1 毫秒
- {
- uint16 i,j;
- for(i=x_ms;i>0;i--)
- for(j=114;j>0;j--);
- }
- /*********************************************************************
- *函数名称:xiaoying
- *函数功能:数码管扫描延迟及消影函数
- *函数调用:xiaoying();
- *参数列表:无
- *返 回 值:无
- *结 果:数码管扫描延迟及消影
- *备 注:
- *********************************************************************/
- void xiaoying()
- {
- delay(3); //数码管扫描延迟时间 毫秒
- DX=0; //显示内容清空
- WX=0; //显示位置清空
- P0=0X00; //选择显示位置
- WX=1; //给高电平
- WX=0; //给低电平 电平下衍 将显示位置写入数码管位置显示锁存器
- }
复制代码
|