以下是我編寫的DS1302芯片驅(qū)動代碼,已測試,可以正常操作芯片,但是我用到的是stm32單片機,估計會有同學不習慣使用庫的風格,但是不重要,感興趣的同學可以參考程序的步驟就可以了,比如要看時序,就只看那一個 函數(shù)就可以了。。。。。更希望用51單片機開發(fā)的同學要是方便的話,能上傳你寶貴的代碼,讓更多的人簡單清楚的明白驅(qū)動步驟,更好的幫助他們
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "ds1302.h"
#define DS1302_RESET_PORT GPIOC
#define DS1302_RESET_BIT GPIO_Pin_10
#define DS1302_SCLK_PORT GPIOC
#define DS1302_SCLK_BIT GPIO_Pin_11
#define DS1302_DATA_PORT GPIOC
#define DS1302_DATA_BIT GPIO_Pin_12
void DS1302Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//打開時鐘模塊
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS1302_RESET_BIT;//reset
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(DS1302_RESET_PORT, &GPIO_InitStructure);//復位引腳
GPIO_InitStructure.GPIO_Pin = DS1302_SCLK_BIT;
GPIO_Init(DS1302_SCLK_PORT, &GPIO_InitStructure);//SCLK
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);
GPIO_InitStructure.GPIO_Pin = DS1302_DATA_BIT;//data
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//開漏輸出,通過外接上拉電阻,達到雙向通信
GPIO_Init(DS1302_DATA_PORT, &GPIO_InitStructure);
DS1302TimeConfig();
}
unsigned char CommunicationByte(unsigned char value)
{
unsigned char i, temp;
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
temp = 0;
i = 0;
for(i = 0; i < 8; i++)
{
//接收數(shù)據(jù),數(shù)據(jù)是緊接著控制字最后一位輸出的
asm("NOP");asm("NOP");asm("NOP");asm("NOP");
temp >>= 1;//低位在前
if (GPIO_ReadInputDataBit(DS1302_DATA_PORT, DS1302_DATA_BIT) == 1)
{
temp |= 0x80;
}
//發(fā)送數(shù)據(jù)
if ((value & 0x01) != 0)
{
GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_SET);
}
else
{
GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_RESET);
}
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 1, 上升沿
value >>= 1;//低位在前
asm("NOP");asm("NOP");asm("NOP");asm("NOP");
GPIO_WriteBit(DS1302_DATA_PORT, DS1302_DATA_BIT, Bit_SET);//拉高DATA IO,避免影響芯片輸出
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0,下降沿
}
return temp;
}
void DS1302WriteRegister(unsigned char reg, unsigned char value)
{
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//只有在SCLK為低電平時候,才允許將rst置位高電平
CommunicationByte(reg);
CommunicationByte(value);
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;
}
unsigned char DS1302ReadRegister(unsigned char reg)
{
unsigned char temp;
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//只有在SCLK為低電平時候,才允許將rst置位高電平
CommunicationByte(reg);
temp = CommunicationByte(0xff);
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;
return temp;
}
void DS1302WriteTime(unsigned char *data)
{
unsigned char i;
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//reset = 1;
CommunicationByte(0xbe);//連續(xù)寫 日歷/時鐘寄存器
for (i = 0; i < 8; i++)
{
CommunicationByte(data[i]);
}
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;
}
void DS1302ReadTime(unsigned char *buffer)
{
unsigned char i;
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_RESET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_SET);//reset = 1;
CommunicationByte(0xbf);//連續(xù)讀 日歷/時鐘寄存器
for (i = 0; i < 8; i++)
{
buffer[i] = CommunicationByte(0xff);
}
GPIO_WriteBit(DS1302_SCLK_PORT, DS1302_SCLK_BIT, Bit_SET);//sclk = 0;
GPIO_WriteBit(DS1302_RESET_PORT, DS1302_RESET_BIT, Bit_RESET);//reset = 0;
}
void DS1302TimeConfig(void)
{
unsigned char temp;
unsigned char data[8] = {0x01,0x10,0x11,0x30,0x11,0x05,0x12};//for test
temp = DS1302ReadRegister(0xc1);//讀取ds1302ram 數(shù)據(jù)
if (temp != 0xaa)//第一次上電
{
DS1302WriteRegister(0x8e, 0x00);//允許寫操作
DS1302WriteRegister(0xc0, 0xaa);//置標志位
DS1302WriteTime(data);
DS1302WriteRegister(0x8e, 0x80);//禁止寫操作
/*
DS1302WriteRegister(0x80,0x01);//設置秒
DS1302WriteRegister(0x82,0x18);//設置分
DS1302WriteRegister(0x84,0x17);//設置時
DS1302WriteRegister(0x86,0x29);//設置日
DS1302WriteRegister(0x88,0x11);//設置月
DS1302WriteRegister(0x8a,0x04);//設置星期
DS1302WriteRegister(0x8c,0x12);//設置年
*/
}
}
void DS1302TimeUpdate(unsigned char *data)
{
//data 數(shù)據(jù)應為壓縮bcd碼
DS1302WriteRegister(0x8e, 0x00);//允許寫操作
DS1302WriteRegister(0xc0, 0xaa);//置標志位
DS1302WriteTime(data);//連續(xù)寫入 時鐘/日歷 寄存器數(shù)據(jù)
DS1302WriteRegister(0x8e, 0x80);//禁止寫操作
}