以下是我編寫的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);//設(shè)置秒
- DS1302WriteRegister(0x82,0x18);//設(shè)置分
- DS1302WriteRegister(0x84,0x17);//設(shè)置時
- DS1302WriteRegister(0x86,0x29);//設(shè)置日
- DS1302WriteRegister(0x88,0x11);//設(shè)置月
- DS1302WriteRegister(0x8a,0x04);//設(shè)置星期
- DS1302WriteRegister(0x8c,0x12);//設(shè)置年
- */
- }
- }
- void DS1302TimeUpdate(unsigned char *data)
- {
- //data 數(shù)據(jù)應(yīng)為壓縮bcd碼
- DS1302WriteRegister(0x8e, 0x00);//允許寫操作
- DS1302WriteRegister(0xc0, 0xaa);//置標志位
-
- DS1302WriteTime(data);//連續(xù)寫入 時鐘/日歷 寄存器數(shù)據(jù)
- DS1302WriteRegister(0x8e, 0x80);//禁止寫操作
- }
復制代碼 |