請教一下,用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
復制代碼
|