|
代碼直接貼出來嗷 需要的友友直接下載就好了
pcf8563.c
- /**
- *****************************************************************************
- * 時鐘芯片PCF8563驅(qū)動
- * @File : pcf8563.c
- * @By : shun
- * @Version : V1.0
- * @Date : 2018 / 12 / 13
- *
- *****************************************************************************
- **/
- #include "pcf8563.h"
- /******************************************************************************
- 定義相關(guān)的變量函數(shù)
- ******************************************************************************/
- unsigned char buffer[4]; //年月日周
- unsigned char buffer1[4]; //時分秒
- /**
- *****************************************************************************
- * @Name : 將BIN轉(zhuǎn)換為BCD
- *
- * @Brief : none
- *
- * @Input : BINValue: 輸入BIN
- *
- * @Output : none
- *
- * @Return : BCD格式數(shù)值
- *****************************************************************************
- **/
- static unsigned char RTC_BinToBcd2(unsigned char BINValue)
- {
- unsigned char bcdhigh = 0;
-
- while (BINValue >= 10)
- {
- bcdhigh++;
- BINValue -= 10;
- }
-
- return ((unsigned char)(bcdhigh << 4) | BINValue);
- }
- /**
- *****************************************************************************
- * @Name : 將BCD轉(zhuǎn)換為BIN
- *
- * @Brief : none
- *
- * @Input : BCDValue: 輸入BCD
- *
- * @Output : none
- *
- * @Return : BIN格式數(shù)值
- *****************************************************************************
- **/
- static unsigned char RTC_Bcd2ToBin(unsigned char BCDValue)
- {
- unsigned char tmp = 0;
-
- tmp = ((unsigned char)(BCDValue & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
- return (tmp + (BCDValue & (unsigned char)0x0F));
- }
- /******************************************************************************
- * @Name : PCF8563某寄存器寫入一個字節(jié)數(shù)據(jù)
- *
- * @Brief : none
- *
- * @Input : REG_ADD:要操作寄存器地址
- * dat: 要寫入的數(shù)據(jù)
- *
- * @Output : none
- *
- * @Return : none
- **/
- void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
- {
- IIC_Start(); //啟動IIC
- if(!(IIC_Write_Byte(PCF8563_Write))) //發(fā)送寫命令并檢查應(yīng)答位
- {
- IIC_Write_Byte(REG_ADD); //寫入地址
- IIC_Write_Byte(dat); //發(fā)送數(shù)據(jù)
- }
- IIC_Stop(); //關(guān)閉IIC
- }
- /******************************************************************************
- * @Name : PCF8563某寄存器讀取一個字節(jié)數(shù)據(jù)
- *
- * @Brief : none
- *
- * @Input : REG_ADD:要操作寄存器地址
- *
- * @Output : none
- *
- * @Return : 讀取得到的寄存器的值
- *****************************************************************************
- **/
- unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
- {
- unsigned char ReData; //定義變量接收數(shù)據(jù)
-
- IIC_Start(); //啟動IIC
- if(!(IIC_Write_Byte(PCF8563_Write))) //發(fā)送寫命令并檢查應(yīng)答位
- {
- IIC_Write_Byte(REG_ADD); //確定要操作的寄存器
- IIC_Start(); //重啟總線
- IIC_Write_Byte(PCF8563_Read); //發(fā)送讀取命令
- ReData = IIC_Read_Byte( ); //讀取數(shù)據(jù)
- IIC_Ack(1); //發(fā)送非應(yīng)答信號結(jié)束數(shù)據(jù)傳送
- }
- IIC_Stop(); //關(guān)閉IIC
- return ReData;
- }
- /******************************************************************************
- * @Name : PCF8563寫入多組數(shù)據(jù)
- *
- * @Brief : none
- *
- * @Input : REG_ADD:要操作寄存器起始地址
- * num: 寫入數(shù)據(jù)數(shù)量
- * *WBuff: 寫入數(shù)據(jù)緩存
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
- {
- unsigned char i = 0; //定義i輔助循環(huán)發(fā)送
-
- IIC_Start(); //啟動IIC
- if(!(IIC_Write_Byte(PCF8563_Write))) //發(fā)送寫命令并檢查應(yīng)答位
- {
- IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
- for(i = 0;i < num;i++) //循環(huán)num次,達(dá)到多個數(shù)據(jù)寫入
- {
- IIC_Write_Byte(*pBuff); //寫入數(shù)據(jù)
- pBuff++; //數(shù)據(jù)緩存地址增加
- }
- }
- IIC_Stop(); //關(guān)閉IIC
- }
- /******************************************************************************
- * @Name : PCF8563讀取多組數(shù)據(jù)
- *
- * @Brief : none
- *
- * @Input : REG_ADD:要操作寄存器起始地址
- * num: 讀取數(shù)據(jù)數(shù)量
- *
- * @Output : *WBuff: 讀取數(shù)據(jù)緩存
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
- {
- unsigned char i = 0; //定義變量i輔助多次讀取
-
- IIC_Start(); //啟動IIC
- if(!(IIC_Write_Byte(PCF8563_Write))) //發(fā)送寫命令并檢查應(yīng)答位
- {
- IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
- IIC_Start(); //重啟總線
- IIC_Write_Byte(PCF8563_Read); //發(fā)送讀取命令
- for(i = 0;i < num;i++) //循環(huán)num次完成多次讀取
- {
- *pBuff = IIC_Read_Byte(); //讀取數(shù)據(jù)
- if(i == (num - 1)) IIC_Ack(1);//發(fā)送非應(yīng)答信號,知道完成數(shù)據(jù)量
- else IIC_Ack(0); //發(fā)送應(yīng)答信號
- pBuff++; //讀取緩沖區(qū)地址增加
- }
- }
- IIC_Stop(); //關(guān)閉IIC
- }
- /******************************************************************************
- * @Name : PCF8563檢測是否存在
- *
- * @Brief : 向定時器倒計(jì)時寄存器寫入一個數(shù)值再讀取出來做對比,相同正確,不同則錯誤
- *
- * @Input : none
- *
- * @Output : none
- *
- * @Return : 0: 正常
- * 1: PCF8563錯誤或者損壞
- *****************************************************************************
- **/
- unsigned char PCF8563_Check(void)
- {
- unsigned char test_value = 0;
- unsigned char Time_Count = 0; //定時器倒計(jì)時數(shù)據(jù)緩存
- if(PCF8563_Read_Byte(PCF8563_Address_Timer) & 0x80) //如果打開了定時器,則先關(guān)閉
- {
- PCF8563_Write_Byte(PCF8563_Address_Timer, PCF_Timer_Close); //先關(guān)閉定時器
- Time_Count = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //先保存計(jì)數(shù)值
- }
- PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, PCF8563_Check_Data); //寫入檢測值
- for(test_value = 0;test_value < 50;test_value++) {} //延時一定時間再讀取
- test_value = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //再讀取回來
- if(Time_Count != 0) //啟動了定時器功能,則恢復(fù)
- {
- PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, Time_Count); //恢復(fù)現(xiàn)場
- PCF8563_Write_Byte(PCF8563_Address_Timer, PCF_Timer_Open); //啟動定時器
- }
- if(test_value != PCF8563_Check_Data) return 1; //器件錯誤或者損壞
-
- return 0; //正常
- }
- /**
- *****************************************************************************
- * @Name : PCF8563啟動
- *
- * @Brief : none
- *
- * @Input : none
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_Start(void)
- {
- unsigned char temp = 0;
-
- temp = PCF8563_Read_Byte(PCF8563_Address_Control_Status_1); //讀取控制/狀態(tài)寄存器1
- if (temp & PCF_Control_ChipStop)
- {
- temp &= PCF_Control_ChipRuns; //運(yùn)行芯片
- }
- if ((temp & (1<<7)) == 0) //普通模式
- {
- temp &= PCF_Control_TestcClose; //電源復(fù)位模式失效
- }
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp); //再寫入數(shù)值
- }
- /**
- *****************************************************************************
- * @Name : PCF8563停止
- *
- * @Brief : 時鐘頻率輸出CLKOUT 在 32.768kHz 時可用
- *
- * @Input : none
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_Stop(void)
- {
- unsigned char temp = 0;
-
- temp = PCF8563_Read_Byte(PCF8563_Address_Control_Status_1); //讀取控制/狀態(tài)寄存器1
- temp |= PCF_Control_ChipStop; //停止運(yùn)行
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp); //再寫入數(shù)值
- }
- /**
- *****************************************************************************
- * @Name : PCF8563設(shè)置運(yùn)行模式
- *
- * @Brief : none
- *
- * @Input : Mode: 運(yùn)行模式
- * = PCF_Mode_Normal
- * = PCF_Mode_EXT_CLK
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_SetMode(unsigned char Mode)
- {
- unsigned char temp = 0;
-
- temp = PCF8563_Read_Byte(PCF8563_Address_Control_Status_1); //讀取寄存器值
- if (Mode == PCF_Mode_EXT_CLK) //EXT_CLK測試模式
- {
- temp |= PCF_Control_Status_EXT_CLKMode;
- }
- else if (Mode == PCF_Mode_Normal)
- {
- temp &= PCF_Control_Status_NormalMode;
- temp &= ~(1<<3); //電源復(fù)位功能失效
- }
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp);
- }
- /**
- *****************************************************************************
- * @Name : PCF8563設(shè)置電源復(fù)位功能開啟與關(guān)閉
- *
- * @Brief : none
- *
- * @Input : NewState: 狀態(tài),PCF8563_PowerResetEnablePCF8563_PowerResetDisable
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_SetPowerReset(unsigned char NewState)
- {
- unsigned char TestC = 0;
-
- TestC = PCF8563_Read_Byte(PCF8563_Address_Control_Status_1); //獲取寄存器值
- TestC &= ~(1<<3); //清除之前設(shè)置
- if (NewState == PCF8563_PowerResetEnable) //復(fù)位功能有效
- {
- TestC |= PCF8563_PowerResetEnable;
- }
- else if (NewState == PCF8563_PowerResetDisable)
- {
- TestC &= ~PCF8563_PowerResetEnable; //失效,普通模式是值邏輯0,即失效
- }
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, TestC); //寫入數(shù)值
- }
- /**
- *****************************************************************************
- * @Name : PCF8563設(shè)置輸出頻率
- *
- * @Brief : none
- *
- * @Input :*PCF_CLKOUTStruct: 頻率結(jié)構(gòu)指針
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_SetCLKOUT(_PCF8563_CLKOUT_Typedef* PCF_CLKOUTStruct)
- {
- unsigned char tmp = 0;
-
- tmp = PCF8563_Read_Byte(PCF8563_Address_CLKOUT); //讀取寄存器值
- tmp &= 0x7c; //清除之前設(shè)置
- if (PCF_CLKOUTStruct->CLKOUT_NewState == PCF_CLKOUT_Open)
- {
- tmp |= PCF_CLKOUT_Open;
- }
- else
- {
- tmp &= PCF_CLKOUT_Close;
- }
- tmp |= PCF_CLKOUTStruct->CLKOUT_Frequency;
-
- PCF8563_Write_Byte(PCF8563_Address_CLKOUT, tmp);
- }
- /**
- *****************************************************************************
- * @Name : PCF8563設(shè)置定時器
- *
- * @Brief : none
- *
- * @Input :*PCF_TimerStruct: 定時器結(jié)構(gòu)指針
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_SetTimer(_PCF8563_Timer_Typedef* PCF_TimerStruct)
- {
- unsigned char Timer_Ctrl = 0;
- unsigned char Timer_Value = 0;
-
- Timer_Ctrl = PCF8563_Read_Byte(PCF8563_Address_Timer); //獲的控制寄存器值
- Timer_Value = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //獲取倒計(jì)時數(shù)值
- //
- //先停止定時器
- //
- Timer_Ctrl &= PCF_Timer_Close;
- PCF8563_Write_Byte(PCF8563_Address_Timer, Timer_Ctrl);
-
- Timer_Ctrl &= 0x7c; //清除定時器之前設(shè)置
-
- if (PCF_TimerStruct->RTC_Timer_NewState == PCF_Timer_Open) //開啟
- {
- Timer_Ctrl |= PCF_Timer_Open;
- Timer_Ctrl |= PCF_TimerStruct->RTC_Timer_Frequency; //填上新的工作頻率
- if (PCF_TimerStruct->RTC_Timer_Value) //需要填上新的計(jì)數(shù)值
- {
- Timer_Value = PCF_TimerStruct->RTC_Timer_Value; //填上新的計(jì)數(shù)值
- }
- }
- else
- {
- Timer_Ctrl &= PCF_Timer_Close;
- }
- PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, Timer_Value); //寫入倒計(jì)時數(shù)值
-
- if (PCF_TimerStruct->RTC_Timer_Interrupt == PCF_Time_INT_Open) //開啟了中斷輸出
- {
- Timer_Value = PCF8563_Read_Byte(PCF8563_Address_Control_Status_2); //獲取控制/狀態(tài)寄存器2數(shù)值
- Timer_Value &= PCF_Time_INT_Close; //清除定時器中斷使能
- Timer_Value &= ~(1<<2); //清除定時器中斷標(biāo)志
- Timer_Value &= ~(1<<4); //當(dāng) TF 有效時 INT 有效 (取決于 TIE 的狀態(tài))
- Timer_Value |= PCF_Time_INT_Open; //開啟定時器中斷輸出
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_2, Timer_Value);
- }
- else
- {
- Timer_Value = PCF8563_Read_Byte(PCF8563_Address_Control_Status_2); //獲取控制/狀態(tài)寄存器2數(shù)值
- Timer_Value &= PCF_Time_INT_Close; //清除定時器中斷使能
- Timer_Value |= PCF_Time_INT_Open; //開啟定時器中斷輸出
- PCF8563_Write_Byte(PCF8563_Address_Control_Status_2, Timer_Value);
- }
-
- PCF8563_Write_Byte(PCF8563_Address_Timer, Timer_Ctrl); //設(shè)置定時器控制寄存器
- }
- /**
- *****************************************************************************
- * @Name : 設(shè)置時間,主要用于后臺調(diào)用,或者初始化時間用
- *
- * @Brief : 秒默認(rèn)就設(shè)置成0x00了,形參里面不體現(xiàn),星期值范圍:0 ~ 6
- *
- * @Input : PCF_Format: 數(shù)據(jù)格式
- * = PCF_Format_BIN
- * = PCF_Format_BCD
- * PCF_Century: 世紀(jì)位設(shè)定
- * = PCF_Century_19xx
- * = PCF_Century_20xx
- * Year: 年
- * Month: 月
- * Date: 日
- * Week: 星期
- * Hour: 時
- * Minute: 分
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void PCF8563_Set_Times(unsigned char PCF_Format,\
- unsigned char PCF_Century,\
- unsigned char Year, unsigned char Month, unsigned char Date, unsigned char Week,\
- unsigned char Hour, unsigned char Minute)
- {
- _PCF8563_Time_Typedef Time_InitStructure;
- _PCF8563_Date_Typedef Date_InitStructure;
-
- if (PCF_Format == PCF_Format_BIN)
- {
- //
- //判斷數(shù)據(jù)是否符合范圍
- //
- if (Year > 99) Year = 0; //恢復(fù)00年
- if (Month > 12) Month = 1; //恢復(fù)1月
- if (Date > 31) Date = 1; //恢復(fù)1日
- if (Week > 6) Week = 1; //恢復(fù)星期一
-
- if (Hour > 23) Hour = 0; //恢復(fù)0小時
- if (Minute > 59) Minute = 0; //恢復(fù)0分鐘
-
- //
- //轉(zhuǎn)換一下
- //
- Date_InitStructure.RTC_Years = RTC_BinToBcd2(Year);
- Date_InitStructure.RTC_Months = RTC_BinToBcd2(Month);
- Date_InitStructure.RTC_Days = RTC_BinToBcd2(Date);
- Date_InitStructure.RTC_WeekDays = RTC_BinToBcd2(Week);
-
- Time_InitStructure.RTC_Hours = RTC_BinToBcd2(Hour);
- Time_InitStructure.RTC_Minutes = RTC_BinToBcd2(Minute);
- }
- Time_InitStructure.RTC_Seconds = 0x00; //恢復(fù)0秒
- Time_InitStructure.RTC_Seconds &= PCF_Accuracy_ClockYes; //保證準(zhǔn)確的時間
- //
- //判斷世紀(jì)位
- //
- if (PCF_Century == PCF_Century_19xx)
- {
- Date_InitStructure.RTC_Months |= PCF_Century_SetBitC;
- }
- else
- {
- Date_InitStructure.RTC_Months &= ~PCF_Century_SetBitC;
- }
- //
- //寫入信息到寄存器
- //
- buffer[0] = Time_InitStructure.RTC_Seconds;
- buffer[1] = Time_InitStructure.RTC_Minutes;
- buffer[2] = Time_InitStructure.RTC_Hours;
- PCF8563_Write_nByte(PCF8563_Address_Seconds, 3, buffer); //寫入時間信息
-
- buffer[0] = Date_InitStructure.RTC_Days;
- buffer[1] = Date_InitStructure.RTC_WeekDays;
- buffer[2] = Date_InitStructure.RTC_Months;
- buffer[3] = Date_InitStructure.RTC_Years;
- PCF8563_Write_nByte(PCF8563_Address_Days, 4, buffer); //寫入日期信息
- }
- /**
- ============================================================================
- #### 所有寄存器全部操作功能函數(shù) ####
- ============================================================================
- **/
- /**
- *****************************************************************************
- * @Name : 判斷時間信息是否符合范圍,超出將恢復(fù)初值
- *
- * @Brief : 星期值范圍:0 ~ 6
- *
- * @Input : PCF_DataStruct: 寄存器結(jié)構(gòu)指針
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- static void IS_PCF8563_Data(_PCF8563_Register_Typedef* PCF_DataStruct)
- {
- if (PCF_DataStruct->Years > 99) PCF_DataStruct->Years = 0; //恢復(fù)00年
- if (PCF_DataStruct->Months_Century > 12) PCF_DataStruct->Months_Century = 1; //恢復(fù)1月
- if (PCF_DataStruct->Days > 31) PCF_DataStruct->Days = 1; //恢復(fù)1日
- if (PCF_DataStruct->WeekDays > 6) PCF_DataStruct->WeekDays = 1; //恢復(fù)星期一
-
- if (PCF_DataStruct->Hours > 23) PCF_DataStruct->Hours = 0; //恢復(fù)0小時
- if (PCF_DataStruct->Minutes > 59) PCF_DataStruct->Minutes = 0; //恢復(fù)0分鐘
- if (PCF_DataStruct->Seconds > 59) PCF_DataStruct->Seconds = 0; //恢復(fù)0秒
- }
- /**
- *****************************************************************************
- * @Name : PCF8563寫入寄存器
- *
- * @Brief : 星期數(shù)值范圍是: 0 ~ 6,十進(jìn)制格式
- *
- * @Input : PCF_Format: 數(shù)據(jù)格式
- * = PCF_Format_BIN
- * = PCF_Format_BCD
- * PCF_Century: 世紀(jì)位設(shè)定
- * = PCF_Century_19xx
- * = PCF_Century_20xx
- * PCF_DataStruct: 寄存器結(jié)構(gòu)指針
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
復(fù)制代碼
這邊有點(diǎn)亂碼 我就直接上傳文件了 有什么問題歡迎討論
注意代碼里面只有上圖2個文件,請自行移植到各MCU系統(tǒng)中去:
c文件和h文件下載.7z
(9.45 KB, 下載次數(shù): 13)
2024-4-28 14:51 上傳
點(diǎn)擊文件名下載附件
部分代碼
|
|