📄 ds1302.c
字号:
/*****************************************************************
***********ATmega128 DS1302测试程序*******************************
******************************************************************/
#include <iom128v.h>
#include <macros.h>
////////////////////////////端口定义////////////////////////////////
#define RST_CLR PORTE &=~(1 << PE4) /*电平置低*/
#define RST_SET PORTE |= (1 << PE4) /*电平置高*/
#define RST_IN DDRE &=~(1 << PE4) /*方向输入*/
#define RST_OUT DDRE |= (1 << PE4) /*方向输出*/
/*双向数据*/
#define IO_CLR PORTE &=~(1 << PE3) /*电平置低*/
#define IO_SET PORTE |= (1 << PE3) /*电平置高*/
#define IO_R PINE &= (1 << PE3) /*电平读取*/
#define IO_IN DDRE &=~(1 << PE3) /*方向输入*/
#define IO_OUT DDRE |= (1 << PE3) /*方向输出*/
/*时钟信号*/
#define SCK_CLR PORTE &=~(1 << PE2) /*时钟信号*/
#define SCK_SET PORTE |= (1 << PE2) /*电平置高*/
#define SCK_IN DDRE &=~(1 << PE2) /*方向输入*/
#define SCK_OUT DDRE |= (1 << PE2) /*方向输出*/
#define ds1302_sec_add 0x80 //秒数据地址
#define ds1302_min_add 0x82 //分数据地址
#define ds1302_hr_add 0x84 //时数据地址
#define ds1302_date_add 0x86 //日数据地址
#define ds1302_month_add 0x88 //月数据地址
#define ds1302_day_add 0x8a //星期数据地址
#define ds1302_year_add 0x8c //年数据地址
#define ds1302_control_add 0x8e //控制数据地址
#define ds1302_charger_add 0x90 //涓流充电
#define ds1302_clkburst_add 0xbe //时钟多字节
/////////////////////////////////////////////////////////////////////////
///////////////////////////////全局变量定义//////////////////////////////
unsigned char sj[7] = {0x09,0x01,0x01,0x00,0x00,0x00,0x00};
///----------------- 年---月---日---时----分---秒---周--------
/////////////////////////////////////////////////////////////////////////
void delay_us(unsigned int n) /*延时函数*/
{
if (n)
{
while (--n);
}
}
/////////////////////////////////////////////////////////////////////////
void delay_ms(unsigned int i) /*延时函数*/
{
unsigned int a, b;
for (a = 1; a < i; a++)
{
for (b = 1; b; b++) {;}
}
}
/////////////////////////////////////////////////////////////////////////
void ds1302_write_byte(unsigned char addr, unsigned char d)
{
unsigned char i; //向DS1302写入一字节数据
RST_SET; //启动DS1302总线
IO_OUT; //写入目标地址:addr
//////////////////////////////////////////////////
addr = addr & 0xFE; //最低位置零
for (i = 0; i < 8; i ++)
{
if (addr & 0x01)
IO_SET;
else
IO_CLR;
SCK_SET;
SCK_CLR;
addr = addr >> 1;
}
IO_OUT; //写入数据:d
///////////////////////////////////////////////////
for (i = 0; i < 8; i ++)
{
if (d & 0x01)
IO_SET;
else
IO_CLR;
SCK_SET;
SCK_CLR;
d = d >> 1;
}
RST_CLR; //停止DS1302总线
///////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////
unsigned char ds1302_read_byte(unsigned char addr)
{ //从DS1302读出一字节数据
unsigned char i;
unsigned char temp;
RST_SET; //启动DS1302总线
IO_OUT; //写入目标地址:addr
//////////////////////////////////////////////////
addr = addr | 0x01; //最低位置高
for (i = 0; i < 8; i ++)
{
if (addr & 0x01)
IO_SET;
else
IO_CLR;
SCK_SET;
SCK_CLR;
addr = addr >> 1; //输出数据:temp
}
IO_IN;
//////////////////////////////////////////////////
for (i = 0; i < 8; i ++)
{
temp = temp >> 1;
if (IO_R)
temp |= 0x80;
else
temp &= 0x7F;
SCK_SET;
SCK_CLR;
}
RST_CLR; //停止DS1302总线
//////////////////////////////////////////////////
return temp;
}
/////////////////////////////////////////////////////////////////////////
void write_time(void)
{ //向DS302写入时钟数据
ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
ds1302_write_byte(ds1302_sec_add,0x80); //暂停
ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电
// 0x00 不
ds1302_write_byte(ds1302_year_add,sj[0]); //年
ds1302_write_byte(ds1302_month_add,sj[1]); //月
ds1302_write_byte(ds1302_date_add,sj[2]); //日
ds1302_write_byte(ds1302_day_add,sj[6]); //周
ds1302_write_byte(ds1302_hr_add,sj[3]); //时
ds1302_write_byte(ds1302_min_add,sj[4]); //分
ds1302_write_byte(ds1302_sec_add,0x00); //秒
ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
}
//////////////////////////////////////////////////////////////////////////
void read_time(void)
{ //从DS302读出时钟数据
sj[0]=ds1302_read_byte(ds1302_year_add); //年
sj[1]=ds1302_read_byte(ds1302_month_add); //月
sj[2]=ds1302_read_byte(ds1302_date_add); //日
sj[3]=ds1302_read_byte(ds1302_hr_add); //时
sj[4]=ds1302_read_byte(ds1302_min_add); //分
sj[5]=(ds1302_read_byte(ds1302_sec_add))&0xFF; //秒
sj[6]=ds1302_read_byte(ds1302_day_add); //周
}
//////////////////////////////////////////////////////////////////////////
void ds1302_init(void)
{ //DS302初始化函数
RST_CLR; //RST脚置低
SCK_CLR; //SCK脚置低
RST_OUT; //RST脚设置为输出
SCK_OUT; //SCK脚设置为输出
}
//////////////////////////////////////////////////////////////////////////
/*
void main(void)
{
unsigned char temp;
//PORTE = 0x04;
//DDRE = 0x04;
//PORTG = 0x18;
//DDRG = 0x18;
uart0_init();
//LCD_init();
ds1302_init();
ds1302_write_byte(ds1302_sec_add,0);
while(1){
read_time();
uart0_sentstr(sj);
}
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -