历史上的今天
今天是:2025年08月13日(星期三)
2019年08月13日 | 壹拾柒:DS1302的操作
2019-08-13 来源:eefocus
DS1302是DALLAS公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31字节静态RAM
可通过简单的串行接口与单片机进行通信
可提供:
-秒分时日日期月年的信息
-每月的天数和闰年的天数可自动调整
-可通过AM/PM指示决定采用24或12小时格式
-保持数据和时钟信息时功率小于1mW
引脚图

控制原理

参考电路

#控制字与操作时序


#读写一个字节


#读/写操作


#寄存器


#初始化代码 
#原理图
#代码
* 【课程18】 ****DS1302的实验***********
*
* 【说 明】 ****
*
* 【描 述】 ****设置DS1302初始化时间为6:0:0,调用读出时间函数
并通过LCD1602显示
*
******************************************************************/
#include
#include
//---------常用的两个宏定义--------------
#define uint8 unsigned char
#define uint16 unsigned int
//--------1602的控制引脚定义-------------
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
//---------DS1302的控制引脚定义----------
sbit SCK=P1^1; //时钟
sbit SDA=P1^0; //数据
sbit RST = P1^2;// DS1302复位
uint8 l_tmpdate[7]={0,0,6,0,0,0,0};//秒分时日月周年08-05-15 12:00:00
code uint8 write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
code uint8 read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uint8 l_tmpdisplay[8];
//----------液晶模块的声明---------------
bit BUSY(void);
void Write_cmd(uint8 cmd);
void Write_dat(uint8 dat);
void LCD_Init(void);
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void Write_Ds1302_byte(uint8 temp);
void Write_Ds1302( uint8 address,uint8 dat );
uint8 Read_Ds1302 ( uint8 address );
void Read_RTC(void);//read RTC
void Set_RTC(void); //set RTC
void main(void)
{
uint8 i;
LCD_Init();
Set_RTC(); //设置时间
while(1)
{
Read_RTC(); //读出时间
l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开
l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[2]=0x0a; //":"
l_tmpdisplay[3]=l_tmpdate[1]/16;
l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[5]=0x0a;
l_tmpdisplay[6]=l_tmpdate[0]/16;
l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
Write_cmd(0x80);
for(i=0;i<8;i++)
Write_dat(l_tmpdisplay[i]+0x30);
}
}
/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(12M的晶振)
** 入口参数 :dly
用户的延时参数
** 出口参数 :无
*********************************************************/
void DelayMS(uint16 dly)
{
uint16 x,y;
for(x=dly;x>0;x--)
for(y=124;y>0;y--);
}
/********************************************************
** 名称 :bit BUSY(void)
** 功能 :检测LCD1602是否处于忙状态;
** 入口参数 :无
** 出口参数 :bit Bit
返回1,则BUSY
返回0,则OK
*********************************************************/
bit BUSY(void)
{
bit Bit;
RS = 0;
RW = 1;
EN = 1;
DelayMS(1);
Bit = (bit)(P0 & 0x80); //最高位为忙信号位
EN = 0;
return Bit;
}
/********************************************************
** 名称 :void Write_cmd(uint8 cmd)
** 功能 :写命令
** 入口参数 :cmd
控制命令
** 出口参数 :无
*********************************************************/
void Write_cmd(uint8 cmd)
{
while(BUSY()); //测忙
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
EN = 1;
DelayMS(1);
EN = 0;
}
/********************************************************
** 名称 :void Write_dat(uint8 dat)
** 功能 :写数据
** 入口参数 :dat
要显示的数据
** 出口参数 :无
*********************************************************/
void Write_dat(uint8 dat)
{
while(BUSY()); //测忙
RS = 1;
RW = 0;
EN = 0;
P0 = dat;
EN = 1;
DelayMS(1);
EN = 0;
}
/********************************************************
** 名称 :void LCD_Init(void)
** 功能 :液晶的初始化
** 入口参数 :无
** 出口参数 :无
*********************************************************/
void LCD_Init(void)
{
Write_cmd(0x38); //功能设置
DelayMS(1);
Write_cmd(0x0c); //显示开关控制
DelayMS(1);
Write_cmd(0x06); //输入方式设置
DelayMS(1);
Write_cmd(0x01); //清除LCD的显示内容
DelayMS(1);
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void Write_Ds1302_Byte(uint8 temp)
{
uint8 i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCK=0;
SDA=temp&0x01; //每次传输低字节
temp>>=1; //右移一位
SCK=1;
}
}
/******************************************************************/
/* 写入DS1302 */
/******************************************************************/
void Write_Ds1302( uint8 address,uint8 dat )
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_(); //启动
Write_Ds1302_Byte(address); //发送地址
Write_Ds1302_Byte(dat); //发送数据
RST=0; //恢复
_nop_();
SCK=1;
SDA=1;
}
/******************************************************************/
/* 读出DS1302数据 */
/******************************************************************/
uint8 Read_Ds1302( uint8 address )
{
uint8 i,temp=0x00;
RST=0;
_nop_();
_nop_();
SCK=0;
_nop_();
_nop_();
RST=1;
_nop_();
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循环8次 读取数据
{
temp>>=1; //右移一位
SCK=0;
if(SDA)
temp|=0x80; //每次传输低字节
SCK=1;
}
RST=0;
_nop_(); //以下为DS1302复位的稳定时间
_nop_();
SCK=1;
SDA=1;
_nop_();
_nop_();
return (temp); //返回
}
/******************************************************************/
/* 读时钟数据 */
/******************************************************************/
void Read_RTC(void) //读取 日历
{
uint8 i,*p;
p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 秒分时日月周年
{
l_tmpdate[i]=Read_Ds1302(*p);
p++;
}
}
/******************************************************************/
/* 设定时钟数据 */
/******************************************************************/
void Set_RTC(void) //设定 日历
{
uint8 i,*p;
Write_Ds1302(0x8E,0X00);
p=write_rtc_address; //传地址
for(i=0;i<7;i++) //7次写入 秒分时日月周年
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8E,0x80); //WP=1
}
上一篇:壹拾陆:LCD1602的显示
下一篇:壹拾捌:LCD12864的显示
史海拾趣
|
1.AGC ON/OFF(Auto Gain Control,自动增益控制):摄像头内有一个将来自CCD的信号放大到可以使用水准的视频放大器,其放大量即增益,等效于有较高的灵敏度,然而在亮光照的环境下放大器将过载,使视频信号畸变。当开关在ON时,在低亮度条件下完全 ...… 查看全部问答> |
|
一个很简单的按键小功能, 以前用51何avr做过, 功能都非常理想 现在改用PIC16F877, 按各个键时分别在数码管上显示相应的数字,出现如下问题: 1. 快速同时按键多个键时,会出现没有反应的情况, 之后再按单个的键, 都没有反应 (正常功能是按 ...… 查看全部问答> |
|
本帖最后由 辛昕 于 2018-5-3 16:39 编辑 后来这个问题我没什么兴趣了,唯一的可能就是,其实它启发了 编程里的 数据加锁 以避免冲突。 小弟最近做数字电路的基础实验。 其中被 组合逻辑竞争冒险现象 困扰 呃,我看过一些资料,但是,很多 ...… 查看全部问答> |
|
现在在程序界面上,想要做一个方块(红 绿 黄等),颜色的切换来表示 网络状况的好坏,如果不能表示好坏,来表示连接着或断开 这两种也行,最好能像网卡上接网线的地方的指示灯一样的效果。 不知怎么~~~处理… 查看全部问答> |
|
#include<msp430x44x.h> void main(void) { WDTCTL=WDTPW+WDTHOLD; // stop watchdog TACTL=TASSEL0+TACLR; //ACLK,CLEAR TAR CCTL0=CCIE; //CCR0 INT EN CCR0=16384; //32KHZ,=0.5S ...… 查看全部问答> |




