基於STM32F1的時鐘晶片DS1302驅動
阿新 • • 發佈:2018-12-15
目錄
DS1302.h原始碼
/** ****************************************************************************** * @file DS1302.h * @author Velscode * @email [email protected] * @version 學習完全版 1.0 * @brief 基於STM32F1x的時鐘晶片DS1302驅動 ****************************************************************************** */ #ifndef __DS1302_H #define __DS1302_H /* 標頭檔案 ------------------------------------------------------------------ */ #include "stm32f10x.h" #include "delay.h" /* 引腳配置 ------------------------------------------------------------------ */ #define DS1302_IO_CLOCK RCC_APB2Periph_GPIOC //使用到的IO口時鐘源,多個可用或|連線 #define DS1302_CLK_GPIO GPIOC //CLK線 #define DS1302_CLK_PIN GPIO_Pin_0 #define DS1302_CLK PCout(0) #define DS1302_DIO_GPIO GPIOC //DIO線 #define DS1302_DIO_PIN GPIO_Pin_1 #define DS1302_DATIN PCin(1) #define DS1302_DATOUT PCout(1) #define DS1302_RST_GPIO GPIOC //RST線 #define DS1302_RST_PIN GPIO_Pin_2 #define DS1302_RST PCout(2) /* 暫存器地址 -------------------------------------------------------------- */ #define DS1302_REG_SEC 0x80 //秒資料地址 #define DS1302_REG_MIN 0x82 //分資料地址 #define DS1302_REG_HR 0x84 //時資料地址 #define DS1302_REG_DATE 0x86 //日資料地址 #define DS1302_REG_MONTH 0x88 //月資料地址 #define DS1302_REG_DAY 0x8a //星期幾資料地址 #define DS1302_REG_YEAR 0x8c //年資料地址 #define DS1302_REG_CONTROL 0x8e //防寫暫存器地址 #define DS1302_REG_CHARGER 0x90 //涓流充電暫存器 /* 全域性變數 ------------------------------------------------------------------ */ /* 函式宣告 ------------------------------------------------------------------ */ void DS1302_Init(void); //初始化DS1302 void Ds1302_WriteReg( unsigned char address, unsigned char dat ); unsigned char DS1302_ReadReg(unsigned char address); unsigned char DS1302_Get_Sec ( void ); unsigned char DS1302_Get_Min ( void ); unsigned char DS1302_Get_Hour ( void ); unsigned char DS1302_Get_Date ( void ); unsigned char DS1302_Get_Mouth( void ); unsigned char DS1302_Get_Day ( void ); unsigned char DS1302_Get_Year ( void ); void DS1302_Set_Sec ( unsigned char val ); void DS1302_Set_Min ( unsigned char val ); void DS1302_Set_Hour ( unsigned char val ); void DS1302_Set_Date ( unsigned char val ); void DS1302_Set_Mouth( unsigned char val ); void DS1302_Set_Day ( unsigned char val ); void DS1302_Set_Year ( unsigned char val ); #endif /* __DS1302_H */ /* End of File ------------------------------------------------------------- */
DS1302.c原始碼
/** ****************************************************************************** * @file DS1302.c * @author Velscode ([email protected]) * @version 學習完全版 1.0 * @brief 基於STM32F1x的時鐘晶片DS1302驅動 ****************************************************************************** */ #include "DS1302.h" /* 巨集定義 ------------------------------------------------ */ /* 內部函式宣告 ------------------------------------------ */ void DS1302_Config_DIO_Input(void); void DS1302_Config_DIO_Output(void); /** ********************************************************** * 函式名稱:DS1302_Init * 功 能:初始化IO口 * 備 注:所有IO引數已使用巨集定義替換,只需要更改標頭檔案即可 ********************************************************** */ void DS1302_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(DS1302_IO_CLOCK, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置IO速度 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置IO輸出模式 //CLK GPIO_InitStructure.GPIO_Pin =DS1302_CLK_PIN; GPIO_Init(DS1302_CLK_GPIO, &GPIO_InitStructure); //DIO GPIO_InitStructure.GPIO_Pin =DS1302_DIO_PIN; GPIO_Init(DS1302_DIO_GPIO, &GPIO_InitStructure); //RST GPIO_InitStructure.GPIO_Pin =DS1302_RST_PIN; GPIO_Init(DS1302_RST_GPIO, &GPIO_InitStructure); //設定為24小時工作制 } /** ********************************************************** * 函式名稱:DS1302_Config_DIO_Input * 功 能:將DIO口配置為輸入模式,用於讀取資料 ********************************************************** */ void DS1302_Config_DIO_Input(void) { GPIO_InitTypeDef GPIO_InitStructure; //IO GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC, &GPIO_InitStructure); } /** ********************************************************** * 函式名稱:DS1302_Config_DIO_Output * 功 能:將DIO口配置為輸出模式,用於寫入資料 ********************************************************** */ void DS1302_Config_DIO_Output(void) { GPIO_InitTypeDef GPIO_InitStructure; //IO GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); } /** ********************************************************** * 函式名稱:DS1302_SPI_ReadByte * 功 能:模擬SPI通訊讀取一個位元組 * 返 回:讀取到的位元組 ********************************************************** */ unsigned char DS1302_SPI_ReadByte(void) { unsigned char i = 0, data = 0; DS1302_Config_DIO_Input(); //DIO配置為輸入模式 for(i = 0; i <8; i++) { data = data >> 1; if(DS1302_DATIN == 1) data = data | 0x80; DS1302_CLK = 1; DS1302_CLK = 0; } return data; } /** ********************************************************** * 函式名稱:DS1302_SPI_WriteByte * 功 能:模擬SPI通訊寫入一個位元組 * 參 數:dat 待寫入的位元組 ********************************************************** */ void DS1302_SPI_WriteByte(u8 dat) { u8 i = 0, data = dat; DS1302_Config_DIO_Output(); for(i = 0; i < 8; i++) { DS1302_DATOUT = data&0x01; //將資料送到IO口 DS1302_CLK = 1; //拉高時鐘,保持詩句穩定,可以延時100us DS1302_CLK = 0; //拉低時鐘,準備傳輸下一位 data = data >> 1; } DS1302_DATOUT = 1; // } /** ********************************************************** * 函式名稱:DS1302_ReadReg * 功 能:讀取DS1302暫存器中的值 * 參 數:address 暫存器的地址(無須刻意加1,軟體實現) * 返 回:目標暫存器中的值 ********************************************************** */ unsigned char DS1302_ReadReg(unsigned char address) { unsigned char data = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302_SPI_WriteByte(address|0x01); //讀取地址需要與0x01相或,最低為變成1 data = DS1302_SPI_ReadByte(); DS1302_CLK = 1; DS1302_RST = 0; return data; } /** ********************************************************** * 函式名稱:Ds1302_WriteReg * 功 能:向DS1302暫存器中寫入一個值 * 參 數:address 暫存器的地址 * 參 數:dat 待寫入的值 ********************************************************** */ void Ds1302_WriteReg( unsigned char address, unsigned char dat ) { DS1302_CLK = 0; DS1302_RST = 1; DS1302_SPI_WriteByte(address); DS1302_SPI_WriteByte(dat); DS1302_CLK = 1; DS1302_RST = 0; } /** ********************************************************** * 函式名稱:DS1302_Get_Sec * 功 能:獲取秒 * 返 回:一個整數,當前秒的值 * * 80H Bit 7 | 6 5 4 | 3 2 1 0 | 範圍 * CH | 10 Seconds | Seconds | 00-59 * 秒 - 十位 秒 - 個位 ********************************************************** */ unsigned char DS1302_Get_Sec( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_SEC); val = ((val >> 4) &0x07 ) * 10 + ( val & 0x0F ); //把BCD碼轉換為實際的數值 // 取高4位 中的 低3位的值 取低四位的值 return val; } /** ********************************************************** * 函式名稱:DS1302_Get_Min * 功 能:獲取分 * 返 回:一個整數,當前分的值 * * 82H Bit 7 6 5 4 | 3 2 1 0 | 範圍 * 10 Minutes | Minutes | 00-59 ********************************************************** */ unsigned char DS1302_Get_Min( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_MIN); val = (val >> 4) * 10 + (val & 0x0F); return val; } /** ******************************************************************** * 函式名稱:DS1302_Get_Hour * 功 能:獲取小時 * 返 回:一個整數,當前小時的值 * * 84H Bit 7 | 6 | 5 | 4 | 3 2 1 0 | 範圍 * 12/24 | 0 | 10/AP |10Hours | Hours | 1-12或0-24 * 備 注:當BIT7=1時為12小時制,此時,BIT=1代表PM * 當BIT7=0時為24小時制,BIT5表示小時十位的數字 * 本程式未支援12小時制 ********************************************************************* */ unsigned char DS1302_Get_Hour( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_HR); val =((val >> 4) & 0x03) * 10 + (val & 0x0F); return val; } /** ******************************************************************** * 函式名稱:DS1302_Get_Date * 功 能:獲取日的值 * 返 回:一個整數,當前日的值 * * 8+H Bit 7 6 | 5 4 | 3 2 1 0 | 範圍 * 0 0 | 10DATE | DATE |01-28/29或01-30或01-31 ********************************************************************* */ unsigned char DS1302_Get_Date( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_DATE); val =(val >> 4) * 10 + (val & 0x0F); return val; } /** ******************************************************************** * 函式名稱:DS1302_Get_Mouth * 功 能:獲取月份 * 返 回:一個整數,當前月份的值 * * 88H Bit 7 6 5 | 4 | 3 2 1 0 | 範圍 * 0 0 0 | 10Mouths | Mouths | 01-12 ********************************************************************* */ unsigned char DS1302_Get_Mouth( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_MONTH); val =(val >> 4) * 10 + (val & 0x0F); return val; } /** ******************************************************************** * 函式名稱:DS1302_Get_Day * 功 能:獲取星期幾 * 返 回:一個整數,當前星期幾的值 * * 88H Bit 7 6 5 4 3 | 2 1 0 | 範圍 * 0 0 0 0 0 | DAY | 01-07 ********************************************************************* */ unsigned char DS1302_Get_Day( void ) { return DS1302_ReadReg(DS1302_REG_DAY); //BCD碼等於真實值,無須轉換 } /** ******************************************************************** * 函式名稱:DS1302_Get_Day * 功 能:獲取星期幾 * 返 回:一個整數,當前星期幾的值 * * 88H Bit 7 6 5 4 | 3 2 1 0 | 範圍 * 10YEAR | YEAR | 00-99 ********************************************************************* */ unsigned char DS1302_Get_Year( void ) { unsigned char val = DS1302_ReadReg(DS1302_REG_YEAR); val =(val >> 4) * 10 + (val & 0x0F); return val; } void DS1302_Set_Sec ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_SEC, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Min ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_MIN, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Hour ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_HR, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Date ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_DATE, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Mouth( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_MONTH, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Day ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_DAY, val ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } void DS1302_Set_Year ( unsigned char val ) { Ds1302_WriteReg( DS1302_REG_CONTROL, 0x00 ); Ds1302_WriteReg( DS1302_REG_YEAR, ((val/10)<<4)+val%10 ); Ds1302_WriteReg( DS1302_REG_CONTROL, 0x80 ); } /* End of File ------------------------------------------------------------- */