51单片机

您所在的位置:网站首页 1302是什么错误代码 51单片机

51单片机

2024-07-01 00:30| 来源: 网络整理| 查看: 265

   写在前面:本节我们学习了51单片机的DS1302的相关内容,包括原理,电路图,相关寄存器的设置以及时序;完成了利用LCD1602与晶体管的结合,实现了时钟显示;如果只需代码,直接转至文末百度网盘;

        在前面的定时器章节学习中,我们知道51单片机内部含有晶振,可以实现定时/计数功能,通过配置定时计数器的初值,可以实现时钟的功能;但是这种定时器计时存在一些缺陷,例如:精度不高、占用CPU时间,不能够掉电使用等等。本节我们学习51单片机开发的一个新模块--DS1302,利用DS1302实现多功能电子时钟,并将其显示在LCD1602以及晶体管表面。

   本节我们要实现的功能是:

1、LCD1602显示日期,时间;格式为:XX-XX-XX(年月日);XX:XX:XX(时分秒);

2、数码管上显示电子时钟时分秒,格式为 XX-XX-XX(时分秒)。

一、DS1302时钟芯片  1、 DS1302简介

         DS1302是一种低功耗实时时钟芯片,实时时钟计算年、月、日、时、分、秒、星期,直到 2100 年,并有闰年调节功能。每月的天数和闰年的天数可自动调整。时钟操作可通过 AM/PM 指示决定采用 24 或 12 小时格式。DS1302 与 单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:1、CE使能线;2、I/O 数据线;3、SCLK 串行时钟线;

 上图为DS1302芯片的管脚定义,以及同CPU相连时的工作电路;其中管脚功能如下所示:

管脚名称功能1VCC2双供电配置中的主电源供应管脚(单片机供电);2X1DS1302 外部晶振引脚,通常需外接 32.768K 晶振;3X2DS1302 外部晶振引脚,通常需外接 32.768K 晶振;4GND电源地;5CE使能引脚,也是复位引脚,CE信号在读写时必须保持高电平;6I/O串行数据引脚,数据输出或者输入7SCLK串行数据引脚8VCC1备用电源

        在典型电路种,CPU与DS1302相连的为CE、SCLK以及I/O引脚;用于芯片的控制,X1\X2为外部 32.768kHz晶体.振荡电路工作时不需要任何外接的电阻或者电容。VCC1 连接备用电源,在VCC2连接主电源。 当 VCC2比 VCC1高 0.2V时,VCC2 给 DS1302供电.当 VCC1 比 VCC2高 时, VCC1给 DS1302供电.

2、DS1302使用

DS1302 有一个控制寄存器、12 个日历、时钟寄存器和 31 个 RAM。

2.1控制寄存器

        控制寄存器用于存放 DS1302 的控制命令字,DS1302 的CE引脚回到高电平后写入的第一个字节就为控制命令。它用于对 DS1302 读写过程进行控制,格式如下:

 上图是 DS1302 的寄存器样式,我们看到:

1、最高位一直为1;

2、第六位中,1表示RAM,寻址内部存储器;

                        0表示CK,寻址内部寄存器;

3、第五至第一位为RAM/CK相关的地址;

4、最低位,高电平1表示 RD,即下一步操作将要“读”;低电平0表示 W,即 下一步操作将要“写”。

2.2日历/时钟寄存器

下图为相关寄存器的读写地址,控制命令;即通过红色框中的地址,控制相关寄存器的读与写;

下图为相关寄存器的位说明: 

秒寄存器:低四位为秒的个位,高的次三位为秒的十位。最高位 CH 为 DS1302 的运行标志,当 CH=0 时,DS1302 内部时钟运行,反之 CH=1 时停止 ;

小时寄存器:时寄存器。最高位为 12/24 小时的格式选择位,该位为 1 时 表示 12 小时格式。当设置为 12 小时显示格式时,第 5 位的高电平表示下午 (PM);而当设置为 24 小时格式时,第 5 位位具体的时间数据;

写保护寄存器:当该寄存器最高位 WP 为 1 时,DS1302 只读不写,所以要在往 DS1302 写数据之前确保 WP 为0;

2.3BCD码

        在日历/时钟寄存器中都是以 BCD 码存放数据,那么 BCD 码是 什么呢?BCD 码是通过 4 位二进制码来表示 1 位十进制中的 0~9 这 10 个数码。 如下所示:

         所以,往相关寄存器中写入数据时先要转化为BCD码格式在进行写入;读取数据时,读到的是BCD码,使用时需要转化为相应的十进制或十六进制;

2.4读写时序

        我们前面说过,CPU与DS1302相连的线有三根,分别为:CE、SCLK以及I/O引脚;那么如何通过这三根线实现两者之间的数据转换呢?这就不得不提及到DS1302的三个时序:

            在控制指令字输入后的下一个 SCLK 时钟的上升沿时,数据被写入 DS1302,数据输入从低位(位 0)开始。同样,在紧跟 8 位的控制指令字后的下一个 SCLK 脉冲的下降沿读出 DS1302 的数据,读出数据时从低位 0 位到高位 7。完成单字节的读写;

1、CE:初始化后为低电平, 在整个读写器件,要保持高电平,一次字节读写完毕之后,在进行置低电平;

2、单字节写入:在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为写入数据,并且地址已给),紧接着的脉冲IO线的数据就会在上升沿进入对应地址的寄存器;

3、单字节读出:在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为读出数据,并且地址已给),紧接着对应地址的寄存器的数据就会在下升沿进入IO线;

注: 要记得在操作 DS1302 之前关闭写保护;不然指令是无法进入控制寄存器的;

二、硬件设计

本次所涉及的硬件如下:

1、DS1302;2、LCD1602;3、动态数码管;

1、DS1302电路图

开发板上 DS1302 时钟模块电路图为:

从上图中可知,DS1302 芯片的控制管脚接至单片机 P3.4-P3.6;X1、X2 管脚处外接了一个 32.768KHZ 晶振,为时钟运行提供一个稳定的时钟频率,C2 和 C3 为旁路电容,目的是消除晶振起振时产生的电感干扰。对于本开发 板无外接备用电池,如果需要可自行将外部备用电源接入第 8 脚 VCC1。

2、LCD1602电路图

开发板上LCD1602 模块电路图为:

        LCD1602的管脚说明以及相关的使用方法在之前的博客中已经说明,如果需要学习了解的可以看看下面这篇博客!

CSDN

 3、晶体数码管电路图

开发板上晶体数码管模块电路图为:

        晶体数码管的管脚说明以及相关的使用方法在之前的博客中已经说明,如果需要学习了解的可以看看下面这篇博客! 

CSDN

 三者在开发板上的位置:

三、软件设计 1、LCD1602显示日期

功能描述:LCD1602显示日期,时间;格式为:XX-XX-XX(年月日);XX:XX:XX(时分秒);

源码

main.c

#include #include "lcd1602.h"//包含LCD1602头文件 #include "DS1302.h"//包含DS1302头文件 void main ()//定义主函数 { LCD_Init(); //LCD1602初始化 DS1302_Init();//DS1302初始化 LCD_ShowString(1,1," - - ");//设置年月日格式 LCD_ShowString(2,1," : : ");//设置时分秒格式 DS1302_SetTime();//设置时间,通过数组进行设置 while(1) { DS1302_ReadTime();//读取内部时间 LCD_ShowNumber(1,1,DS1302_Time[0],2);//显示年 LCD_ShowNumber(1,4,DS1302_Time[1],2);//显示月 LCD_ShowNumber(1,7,DS1302_Time[2],2);//显示日 LCD_ShowNumber(2,1,DS1302_Time[3],2);//显示时 LCD_ShowNumber(2,4,DS1302_Time[4],2);//显示分 LCD_ShowNumber(2,7,DS1302_Time[5],2);//显示秒 LCD_ShowNumber(2,13,DS1302_Time[6], 1);//显示星期 } }

DS1302.h

#include "DS1302.c" extern unsigned char DS1302_Time[];//声明设置时间的数组 void DS1302_Init();//声明初始化函数 void DS1302_WriteBety(unsigned char command,Data);//声明单字节写入函数 unsigned char DS1302_ReadBety(unsigned char command);//声明单字节读出函数 void DS1302_SetTime();//声明设置内部时间函数 void DS1302_ReadTime();//声明读取内部时间函数

 DS1302.c

#include //引脚定义; sbit DS1302_SCLK=P3^6; sbit DS1302_IO=P3^4; sbit DS1302_CE=P3^5; //对应寄存器位置定义 #define DS1302_SECOND 0X80 #define DS1302_MINUTE 0X82 #define DS1302_HOUR 0X84 #define DS1302_DATE 0X86 #define DS1302_MONTH 0X88 #define DS1302_DAY 0X8A #define DS1302_YEAR 0X8C #define DS1302_WP 0X8E //定义数组,用于存放设定的时间,年月日时分秒星期 unsigned char DS1302_Time[]={23,10, 28,19,00,59,6};//顺序:年月日时分秒星期 /** *@breaf DS1302初始化 *@param无 *@retval无 */ void DS1302_Init() { DS1302_CE=0;//将使能位置0,低电平; DS1302_SCLK=0;//将时钟位置0,低电平; } /** *@breaf DS1302单字节写入函数 *@param command:写入控制指令的指令,包含要写入寄存器的地址; *@param Data:将要写入的数据内容; *@retval 无 */ void DS1302_WriteBety(unsigned char command,Data) { unsigned char i; DS1302_CE=1;//使能位置高电平; for(i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3