标题:
DS1302不能写入,完全断电重新启动后能写入一次,在想写入还需要完全断电重新启动
[打印本页]
作者:
1076658053
时间:
2022-10-28 22:38
标题:
DS1302不能写入,完全断电重新启动后能写入一次,在想写入还需要完全断电重新启动
请教一下,用STM32F103CBT6驱动DS1302,只有完全掉电后再上电才会向写入1302写入一次数据更新时钟,程序运行过程中向1302中写数据没反应。
DS1302.c
#include "ds1302.h"
#include "delay.h"
//初始化时间定义
u8 time_buf[8] = {0x20,0x22,0x10,0x30,0x11,0x09,0x55,0x07}; //初始时间2010年6月1号23点59分55秒 星期二
extern u8 time[15];
//DS1302初始化
void DS1302_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_10); //PB10拉高
GPIO_ResetBits(GPIOA, GPIO_Pin_9 | GPIO_Pin_11); //PB9,PB11置低
}
//static void DS1302_IO_IN(void) //设置IO数据引脚的输入模式的配置
//{
// GPIO_InitTypeDef GPIO_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启GPIOD的时钟
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //设置引脚
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速率50MHz
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //配置输入模式为上拉输入模式
//
// GPIO_Init(GPIOA, &GPIO_InitStructure);//把上面的配置初始化
//}
//
//static void DS1302_IO_OUT(void)//设置IO数据引脚的输出模式的配置
//{
// GPIO_InitTypeDef GPIO_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOD时钟
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//设置引脚
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//配置为推挽输出
//
// GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
//}
//向DS1302写入一个字节数据
void DS1302_Write_Byte(u8 addr, u8 data)
{
u8 i;
DS1302_RST = 0; //停止DS1302总线
delay_us(10);
DS1302_RST = 1; //启动DS1302总线
addr = addr & 0xFE; //最低位置零,写数据
DS1302_IO_OUT();
for(i = 0; i < 8; i ++) //写地址
{
if (addr & 0x01)
DS1302_DATA_OUT = 1;
else
DS1302_DATA_OUT = 0;
DS1302_SCK = 1; //产生时钟
delay_us(10);
DS1302_SCK = 0;
addr = addr>>1;
}
for (i = 0; i < 8; i ++) //写数据
{
if(data & 0x01)
DS1302_DATA_OUT = 1;
else
DS1302_DATA_OUT = 0;
DS1302_SCK = 1; //产生时钟
delay_us(10);
DS1302_SCK = 0;
data = data>>1;
}
DS1302_RST = 0; //停止DS1302总线
}
//从DS1302读出一个字节数据
u8 DS1302_Read_Byte(u8 addr)
{
u8 i,temp;
DS1302_RST = 0; //停止DS1302总线
delay_us(10);
DS1302_RST = 1; //启动DS1302总线
addr = addr | 0x01; //最低位置高,读数据
DS1302_IO_OUT();
for(i = 0; i < 8; i ++) //写地址
{
if (addr & 0x01)
DS1302_DATA_OUT = 1;
else
DS1302_DATA_OUT = 0;
DS1302_SCK = 1; //产生时钟
delay_us(10);
DS1302_SCK = 0;
addr = addr>>1;
}
DS1302_IO_IN();
for (i = 0; i < 8; i ++) //读数据
{
temp = temp >> 1;
if(DS1302_DATA_IN)
temp |= 0x80;
else
temp &= 0x7F;
DS1302_SCK = 1; //产生时钟
delay_us(10);
DS1302_SCK = 0;
}
DS1302_RST = 0; //停止DS1302总线
return temp;
}
//向DS1302写入时间数据
void DS1302_Write_Time(void)
{
DS1302_Write_Byte(ds1302_control_add, 0x00); //关闭写保护
DS1302_Write_Byte(ds1302_sec_add, 0x80); //暂停时钟
//DS1302_Write_Byte(ds1302_charger_add, 0xA9); //涓流充电
DS1302_Write_Byte(ds1302_year_add,time_buf[1]); //年
DS1302_Write_Byte(ds1302_month_add,time_buf[2]); //月
DS1302_Write_Byte(ds1302_date_add,time_buf[3]); //日
DS1302_Write_Byte(ds1302_hr_add,time_buf[4]); //时
DS1302_Write_Byte(ds1302_min_add,time_buf[5]); //分
DS1302_Write_Byte(ds1302_sec_add,time_buf[6]); //秒
DS1302_Write_Byte(ds1302_day_add,time_buf[7]); //周
DS1302_Write_Byte(ds1302_control_add,0x80); //打开写保护
}
//从DS302读出时钟数据
void DS1302_Read_Time(void)
{
time[1] = DS1302_Read_Byte(ds1302_year_add); //年
time[2] = DS1302_Read_Byte(ds1302_month_add); //月
time[3] = DS1302_Read_Byte(ds1302_date_add); //日
time[4] = DS1302_Read_Byte(ds1302_hr_add); //时
time[5] = DS1302_Read_Byte(ds1302_min_add); //分
time[6] = (DS1302_Read_Byte(ds1302_sec_add))&0x7f; //秒,屏蔽秒的第7位,避免超出59
time[7] = DS1302_Read_Byte(ds1302_day_add); //周
}
////DS1302向上层返回时间数据
//void DS1302_Get_Time(u8 *time)
//{
// DS1302_Read_Time();
// time[0]=(time_buf[0]>>4); //年
// time[1]=(time_buf[0]&0x0f);
//
// time[2]=(time_buf[1]>>4);
// time[3]=(time_buf[1]&0x0f);
//
// time[4]=(time_buf[2]>>4); //月
// time[5]=(time_buf[2]&0x0f);
// time[6]=(time_buf[3]>>4); //日
// time[7]=(time_buf[3]&0x0f);
//
// time[8]=(time_buf[7]&0x07); //星期
//
// time[9]=(time_buf[4]>>4); //时
// time[10]=(time_buf[4]&0x0f);
// time[11]=(time_buf[5]>>4); //分
// time[12]=(time_buf[5]&0x0f);
// time[13]=(time_buf[6]>>4); //秒
// time[14]=(time_buf[6]&0x0f);
//}
复制代码
DS1302.h
#ifndef __DS1302_H
#define __DS1302_H
#include "sys.h"
//IO方向设置
#define DS1302_IO_IN() {GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=8<<8;}
#define DS1302_IO_OUT() {GPIOA->CRH&=0XFFFFF0FF;GPIOA->CRH|=3<<8;}
//IO操作函数
#define DS1302_DATA_OUT PAout(10) //数据端口 PA10
#define DS1302_DATA_IN PAin(10) //数据端口 PA10
#define DS1302_SCK PAout(11)
#define DS1302_RST PAout(9)
//DS1302地址定义
#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
void DS1302_Init(void);
void DS1302_Write_Byte(u8 addr, u8 data);
u8 DS1302_Read_Byte(u8 addr);
void DS1302_Write_Time(void);
void DS1302_Read_Time(void);
//void DS1302_Get_Time(u8 *time);
#endif
复制代码
作者:
人中狼
时间:
2022-10-28 23:41
1302的地址错了,1302读和写是不同的地址
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1