系列文章目录

第一章 51单片机Proteus仿真(一) DS1302使用


文章目录

  • 系列文章目录
  • 前言
  • 一、DS1302时序解读
  • 二、BCD码转十进制解读
  • 三、Proteus仿真
  • 四、详细代码

前言

51单片机使用Proteus仿真。小白一枚记录自己学习日常。疫情期间Proteus走起,这软件很强大,使用中也遇到很多问题,求助度娘已解决。代码解释不是特别详细,文笔不好,请各位大神见谅。本人记录自己大四毕业之际准备毕业论文随笔,如有能帮助到您的地方,跪求点赞关注。诸君共勉,共同进步。本文代码实现当前时间 21时02分39秒。万年历下次再写以及显示温度等


提示:以下是本篇文章正文内容,下面案例可供参考

一、DS1302时序解读

时序解释:
写时序 ( 给DS1302写入数据) 需要先确定写哪个寄存器,再写入数据。因为每个寄存器存储数据不同,有存储秒、分、小时、日期、年等寄存器
这里要理解数据输入(单片机向时钟芯片写数据)是SCLK上升沿,数据输出(单片机读取时钟芯片数据)是SCLK下降沿。
向某一个寄存器写入一个字节,就是送入16位(就是数据输入),需16个脉冲。先0后1算一个脉冲(上升沿实现)。
CE=1时,先写命令字,确定给哪个寄存器写数据。最低位设置写还是读,当时钟上升沿来临时,最低位被写入,依次时钟上升沿来临读入一位数据。最高位默认为1。第六位为0是时钟芯片数据,为1是RAM数据。A0-A4是寄存器地址。一个时钟上升沿写入一位数据。写完命令字,再写入数据指令。

因为时钟芯片要一位一位的读写,所以取出一位数据即可。使用Data&0X01读取最低位(第一位),Data&0X02读取第二位,使用for循环8次即可读取8位数据。代码如下

DS1302_IO=Data&(0x01<<i);

因为时钟脉宽是ns级别,而51单片机运行速度慢,一个机器周期是1微妙,即运行一行代码需要1微妙,所以在SCLK=1和SCLK=0之间可以不加延时。若单片机运行速度很快,必须加延时。

读时序 (读取DS1302数据,需要先确定哪个寄存器,再读取数据)
读寄存器数据与写入有很大不同 观察时序图发现,读数据时只有15个脉冲。这是因为输入数据是上升沿,输出数据是下降沿。先确定哪个寄存器,应该是写入数据,若依照写数据代码,先SCLK=1;(上升沿写入)再SCLK=0; 会发现第一个for循环最后一次0导致时钟芯片输出了一位数据(下降沿输出),造成读写操作不连贯,我们目的只是写入数据确定哪个寄存器。读数据代码还没有作用。

 for(i=0;i<8;i++){DS1302_IO=command&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}for(i=0;i<8;i++){DS1302_IO=Data&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}

此时第一个for循环改为先SCLK=0;再SCLK=1;循环8次就写入了一个字节指令,确定是哪个寄存器(8个脉冲)。
然后第二个for循环写SCLK=1;相当于将SCLK=1脉宽变大了,不影响时序,只是为了满足15个脉冲,这里赋值操作最关键,需认真理解。此时再将SCLK=0;读出第一位数据。循环8次则读出8位数据,也满足15个脉冲。
**

for(i=0;i<8;i++){DS1302_IO=command&(0x01<<i);DS1302_SCLK=0;DS1302_SCLK=1;//写入数据,即上升沿到来}for(i=0;i<8;i++){DS1302_SCLK=1;//很关键,将写命令的第8个脉冲宽度延长,满足15个脉冲DS1302_SCLK=0;//读取DS1302数据,下降沿输出if(DS1302_IO==1) //当数据输出为1时,保存下来,第几位就左移几位Data|=(0x01<<i);//输出为0不用处理}

二、BCD码转十进制解读

BCD码 用4位二进制数表示1位十进制数
DS1302寄存器默认使用BCD码存储数据
0001 0011表示13 0010 0101表示25 0001 1010不合法因为后四位10在十进制个位里面没有10
BCD码转十进制 DEC=BCD/1610+BCD%16; (两位BCD)
十进制转BCD码 BCD=DEC/10
16+DEC%10; (两位BCD)
这里很关键,不然10会显示16,下面解释为何显示16
由于读取寄存器返回的是BCD码,0X10十进制是16,所以将BCD转为10进制。BCD/16*10+BCD%16 很好理解。BCD码将10变成16,因此先除以16,再乘以10就表示几个10了,这是十位。个位直接对16取余。其实这相当于16的几次方相加,这个几次方对于十进制也是相同的。BCD转十进制,就是求出这个几次方
关于秒显示从9变成16解释说明

LCD_ShowNum(2,1,second,2);

这样写,到9之后加一就显示16
0000 1001这是9,加上1变成10,0001 0000这是10的BCD码。但程序默认转化为十六进制0X10就是十进制16,所以用LCD1602十进制显示函数时显示16。
有初学者一定不明白,写入0X03为何就显示3呢。这就要从寄存器说起了,DS1302寄存器存储数据使用BCD码,0X03表示十进制3,读取寄存器数据就是0X03,所以用LCD1602显示没问题。
但是当秒加到9(0000 1001)(注意芯片秒寄存器最高位为0时,芯片动作,每秒加一),下一秒加到10,由于BCD码,会将1进到第5位 (BIT4位)(0001 0000)此时表示10秒,因为秒寄存器BIT4-7位表示10秒。而0001 0000用十六进制表示16 0X10,读出这个数据显示就是16。

三、Proteus仿真

有关Proteus需要再写

四、详细代码

代码如下(示例):

#include <regx52.h>
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;//LCD1602引脚定义
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
//LCD1602函数
void LCD_Delay();
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
//DS1302函数
void DS1302_Init();
void DS1302_WriteByte(unsigned char command,Data);
unsigned char DS1302_ReadByte(unsigned char command);int main()
{unsigned char second;unsigned char min;unsigned char hour;LCD_Init();DS1302_Init();LCD_ShowString(1,1,"RTC");DS1302_WriteByte(0x80,0x55);//0X55转化为BCD就是55while(1){second=DS1302_ReadByte(0x81);min=DS1302_ReadByte(0X83);hour=DS1302_ReadByte(0X85);LCD_ShowNum(2,7,second/16*10+second%16,2);//BCD转为十进制LCD_ShowChar(2,6,'-');LCD_ShowNum(2,4,min/16*10+min%16,2);LCD_ShowChar(2,3,'-');LCD_ShowNum(2,1,hour/16*10+hour%16,2);}return 0;
}
void DS1302_Init()
{DS1302_CE=0;DS1302_SCLK=0;
}
/**
*@brief DS1302Ð写入命令和数据
*@param 命令确定哪个寄存器
*@retval
*/
void DS1302_WriteByte(unsigned char command,Data)
{int i;DS1302_CE=1;for(i=0;i<8;i++){DS1302_IO=command&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}for(i=0;i<8;i++){DS1302_IO=Data&(0x01<<i);DS1302_SCLK=1;DS1302_SCLK=0;}DS1302_CE=0;
}
/**
*@brief   DS1302读一个字节
*@param
*@retval
*/
unsigned char DS1302_ReadByte(unsigned char command)
{int i;unsigned char Data=0x00;DS1302_CE=1;for(i=0;i<8;i++){DS1302_IO=command&(0x01<<i);DS1302_SCLK=0;DS1302_SCLK=1;//写入数据,即上升沿到来}for(i=0;i<8;i++){DS1302_SCLK=1;//很关键,将写命令的第8个脉冲宽度延长,满足15个脉冲DS1302_SCLK=0;//读取DS1302数据,下降沿输出if(DS1302_IO==1) //当数据输出为1时,保存下来,第几位就左移几位Data|=(0x01<<i);//输出为0不用处理}DS1302_IO=0;DS1302_CE=0;return Data;}
/*** @brief  LCD1602延时,12MHz1ms* @param  * @retval */
void LCD_Delay()
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}/*** @brief  LCD1602写命令* @param  Command * @retval */
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602写数据* @param  Data * @retval */
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602设置RAM指针位置* @param  Line :1~2* @param  Column :1~16* @retval ?*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));//RAM指针默认最高位为1,从0X00开始}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));//RAM指针从0X40开始}
}/*** @brief  LCD1602* @param  ?* @retval ?*/
void LCD_Init()
{LCD_WriteCommand(0x38);//LCD1602 显示16*2LCD_WriteCommand(0x0c);//LCD1602开显示光标不亮LCD_WriteCommand(0x06);//LCD1602指针自动加一光标加一LCD_WriteCommand(0x01);//清屏
}
//显示字符
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}
//显示字符串
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{LCD_SetCursor(Line,Column);while(*String!='\0')//指针解引用贼秀{LCD_WriteData(*String++);}
}
/**
*@brief
*@param  返回X的Y次方
*@retval
*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief  LCD1602十进制显示数字* @param  Line :1~2* @param  Column :1~16* @param  Number :0~65535* @param  Length :1~5* @retval */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');//涉及ASCLL码,有需要再写}
}# 总结
以上就是今天要讲的内容,本文仅仅简单介绍了51单片机与DS1302结合使用。

51单片机DS1302时钟芯片应用Proteus仿真相关推荐

  1. (给自己看)51单片机DS1302时钟芯片

    老规矩先上DS1302.c的代码 #include <regx52.h>//首先 DS1302_Init(); // DS1302_SetTime();//再在while中DS1302_R ...

  2. 基于51单片机的八路电压表采集Proteus仿真(源码+仿真+原理图+全套资料)

    资料编号:110 程序语言:C语言 仿真软件:Proteus8.9版本 功能讲解如下: 利用单片机及其外围器件(A/D转换器等)实现一款简易电压表,实现以下功能: 1   电压表能够进行8路模拟电压测 ...

  3. 51单片机12864大液晶屏proteus仿真

    51单片机竞赛设计实例程序44例(Proteus仿真资料),可以做参赛设计的参考,可以用来做毕业设计,也可以做项目参考,平时的练习项目,带源码,可以说费了很多时间才集齐的,希望对你们有帮助,闯客网技术 ...

  4. 基于51单片机智能导盲拐杖Proteus仿真

    功能介绍: 采用51单片机作为主控CPU,采用HC-SR04超声波模块测量障碍物距离,LCD1602显示屏显示当前的障碍物距离,并且可以设置报警的阈值,通过传感器测量障碍物的距离的远近来进行相关报警, ...

  5. 基于51单片机的自动售货机Proteus仿真(源码+仿真+设计报告)

    资料编号:137 视频讲解: 137-基于51单片机的自动售货机Proteus仿真(源码+仿真+设计报告) 功能介绍: 基本原理:通过矩阵键盘来选择货物的种类与数量过后自动售货机提示投币.自动售货机的 ...

  6. 基于51单片机的简易数字计算器Proteus仿真(源码+仿真+全套资料)

     资料编号:115 全套资料齐全,功能说明: 该计算器系统51 系列的单片机进行的数字计算器系统设计,可以完成计算器的键盘输入, 进行加. 减.乘.除的简单四则运算,并在 LCD屏幕上相应的显示结果. ...

  7. 基于51单片机ds1302时钟、ds18b20、lcd12864的恒温器

    目录 项目:基于51单片机ds1302时钟.ds18b20的恒温器 功能说明: 运行流程: 效果展示: 供电方式: 用途: 提高: 附: ​                              ...

  8. 蓝桥杯单片机DS1302时钟芯片驱动代码注释

    蓝桥杯单片机DS1302时钟芯片驱动代码之前的疑惑注释了下 /* DS1302 芯片包含一个 实时时钟/日历和 31 字节的静态 RAM. 与时钟/RAM 通讯只需要三根线: CE,I/O (数据线) ...

  9. 【011】基于51单片机的低频信号发生proteus仿真与实物设计

    ​一.资料内容 (1).基于51单片机的低频信号发生proteus仿真设计一份: (2).基于51单片机的低频信号发生proteus仿真设计keli源代码一份: (3).基于51单片机的低频信号发生A ...

最新文章

  1. 英伟达发布史上最强GPU,却叫停了自动驾驶车路测
  2. OCRNet: 目标区域上下文信息的特征表达 | ECCV 2020
  3. Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述
  4. 架构师已死(转自UML软件工程组织)
  5. 会员连锁配置以及金额走向
  6. Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解
  7. 新疆特岗计算机考试题,2020新疆特岗教师笔试资料领取(小学信息技术)
  8. linux怎么让cat运行,使用lolcat让你的Linux命令行出现七彩虹
  9. linux-优化内核参数 /etc/sysctl.conf
  10. 在crontab中利用scp命令自动备份文件
  11. 我买了个阿里云服务器并在上面部署了一个项目
  12. editplus3编辑器颜色修改
  13. Atitit 学习方法 -------体系化学习方法 Excel 科目,分类,专业 三级分类。。 知识点。。 课程就是每一个知识点的详细化。。 比如经济学 类别 专业 xx概论知识点 3、金
  14. pycharm 无法安装模块 nothing to show
  15. 安卓蓝牙USB连接热敏打印机二
  16. 使用Pytorch来拟合函数
  17. 计算机科学中的计算机思维在本质上源自于,计算思维对学习计算机知识有何作用?...
  18. android 平板怎么截图,平板电脑怎样截图
  19. 希捷硬盘无法安全弹出如何解决?
  20. android api 和版本对应表汇总

热门文章

  1. BIEE 11g学习
  2. isEmpty和isBlank的区别
  3. APP开发绿行租车项目
  4. js数组指定位置删除和添加元素
  5. MySQL——数据库日志
  6. 计算机等级考试中有没有样张,2010年计算机等级考试(一级)整理的基础题
  7. 详解 CSS position定位的五种方式
  8. ES入门之CURD-1
  9. 软件测试不得不知的基础知识
  10. 谷歌应用商店的85个广告软件安装900万次