欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
關于STM32單片機PCF8563 IIC驅動 pcf8563.c pcf8563.h文件
[打印本頁]
作者:
Aisyle
時間:
2024-4-28 11:33
標題:
關于STM32單片機PCF8563 IIC驅動 pcf8563.c pcf8563.h文件
代碼直接貼出來嗷 需要的友友直接下載就好了
pcf8563.c
/**
*****************************************************************************
* 時鐘芯片PCF8563驅動
* @File : pcf8563.c
* @By : shun
* @Version : V1.0
* @Date : 2018 / 12 / 13
*
*****************************************************************************
**/
#include "pcf8563.h"
/******************************************************************************
定義相關的變量函數
******************************************************************************/
unsigned char buffer[4]; //年月日周
unsigned char buffer1[4]; //時分秒
/**
*****************************************************************************
* @Name : 將BIN轉換為BCD
*
* @Brief : none
*
* @Input : BINValue: 輸入BIN
*
* @Output : none
*
* @Return : BCD格式數值
*****************************************************************************
**/
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轉換為BIN
*
* @Brief : none
*
* @Input : BCDValue: 輸入BCD
*
* @Output : none
*
* @Return : BIN格式數值
*****************************************************************************
**/
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某寄存器寫入一個字節數據
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器地址
* dat: 要寫入的數據
*
* @Output : none
*
* @Return : none
**/
void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
{
IIC_Start(); //啟動IIC
if(!(IIC_Write_Byte(PCF8563_Write))) //發送寫命令并檢查應答位
{
IIC_Write_Byte(REG_ADD); //寫入地址
IIC_Write_Byte(dat); //發送數據
}
IIC_Stop(); //關閉IIC
}
/******************************************************************************
* @Name : PCF8563某寄存器讀取一個字節數據
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器地址
*
* @Output : none
*
* @Return : 讀取得到的寄存器的值
*****************************************************************************
**/
unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
{
unsigned char ReData; //定義變量接收數據
IIC_Start(); //啟動IIC
if(!(IIC_Write_Byte(PCF8563_Write))) //發送寫命令并檢查應答位
{
IIC_Write_Byte(REG_ADD); //確定要操作的寄存器
IIC_Start(); //重啟總線
IIC_Write_Byte(PCF8563_Read); //發送讀取命令
ReData = IIC_Read_Byte( ); //讀取數據
IIC_Ack(1); //發送非應答信號結束數據傳送
}
IIC_Stop(); //關閉IIC
return ReData;
}
/******************************************************************************
* @Name : PCF8563寫入多組數據
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器起始地址
* num: 寫入數據數量
* *WBuff: 寫入數據緩存
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
void PCF8563_Write_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))) //發送寫命令并檢查應答位
{
IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
for(i = 0;i < num;i++) //循環num次,達到多個數據寫入
{
IIC_Write_Byte(*pBuff); //寫入數據
pBuff++; //數據緩存地址增加
}
}
IIC_Stop(); //關閉IIC
}
/******************************************************************************
* @Name : PCF8563讀取多組數據
*
* @Brief : none
*
* @Input : REG_ADD:要操作寄存器起始地址
* num: 讀取數據數量
*
* @Output : *WBuff: 讀取數據緩存
*
* @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))) //發送寫命令并檢查應答位
{
IIC_Write_Byte(REG_ADD); //定位起始寄存器地址
IIC_Start(); //重啟總線
IIC_Write_Byte(PCF8563_Read); //發送讀取命令
for(i = 0;i < num;i++) //循環num次完成多次讀取
{
*pBuff = IIC_Read_Byte(); //讀取數據
if(i == (num - 1)) IIC_Ack(1);//發送非應答信號,知道完成數據量
else IIC_Ack(0); //發送應答信號
pBuff++; //讀取緩沖區地址增加
}
}
IIC_Stop(); //關閉IIC
}
/******************************************************************************
* @Name : PCF8563檢測是否存在
*
* @Brief : 向定時器倒計時寄存器寫入一個數值再讀取出來做對比,相同正確,不同則錯誤
*
* @Input : none
*
* @Output : none
*
* @Return : 0: 正常
* 1: PCF8563錯誤或者損壞
*****************************************************************************
**/
unsigned char PCF8563_Check(void)
{
unsigned char test_value = 0;
unsigned char Time_Count = 0; //定時器倒計時數據緩存
if(PCF8563_Read_Byte(PCF8563_Address_Timer) & 0x80) //如果打開了定時器,則先關閉
{
PCF8563_Write_Byte(PCF8563_Address_Timer, PCF_Timer_Close); //先關閉定時器
Time_Count = PCF8563_Read_Byte(PCF8563_Address_Timer_VAL); //先保存計數值
}
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) //啟動了定時器功能,則恢復
{
PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, Time_Count); //恢復現場
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); //讀取控制/狀態寄存器1
if (temp & PCF_Control_ChipStop)
{
temp &= PCF_Control_ChipRuns; //運行芯片
}
if ((temp & (1<<7)) == 0) //普通模式
{
temp &= PCF_Control_TestcClose; //電源復位模式失效
}
PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp); //再寫入數值
}
/**
*****************************************************************************
* @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); //讀取控制/狀態寄存器1
temp |= PCF_Control_ChipStop; //停止運行
PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp); //再寫入數值
}
/**
*****************************************************************************
* @Name : PCF8563設置運行模式
*
* @Brief : none
*
* @Input : Mode: 運行模式
* = 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); //電源復位功能失效
}
PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, temp);
}
/**
*****************************************************************************
* @Name : PCF8563設置電源復位功能開啟與關閉
*
* @Brief : none
*
* @Input : NewState: 狀態,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); //清除之前設置
if (NewState == PCF8563_PowerResetEnable) //復位功能有效
{
TestC |= PCF8563_PowerResetEnable;
}
else if (NewState == PCF8563_PowerResetDisable)
{
TestC &= ~PCF8563_PowerResetEnable; //失效,普通模式是值邏輯0,即失效
}
PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, TestC); //寫入數值
}
/**
*****************************************************************************
* @Name : PCF8563設置輸出頻率
*
* @Brief : none
*
* @Input :*PCF_CLKOUTStruct: 頻率結構指針
*
* @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; //清除之前設置
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設置定時器
*
* @Brief : none
*
* @Input :*PCF_TimerStruct: 定時器結構指針
*
* @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); //獲取倒計時數值
//
//先停止定時器
//
Timer_Ctrl &= PCF_Timer_Close;
PCF8563_Write_Byte(PCF8563_Address_Timer, Timer_Ctrl);
Timer_Ctrl &= 0x7c; //清除定時器之前設置
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) //需要填上新的計數值
{
Timer_Value = PCF_TimerStruct->RTC_Timer_Value; //填上新的計數值
}
}
else
{
Timer_Ctrl &= PCF_Timer_Close;
}
PCF8563_Write_Byte(PCF8563_Address_Timer_VAL, Timer_Value); //寫入倒計時數值
if (PCF_TimerStruct->RTC_Timer_Interrupt == PCF_Time_INT_Open) //開啟了中斷輸出
{
Timer_Value = PCF8563_Read_Byte(PCF8563_Address_Control_Status_2); //獲取控制/狀態寄存器2數值
Timer_Value &= PCF_Time_INT_Close; //清除定時器中斷使能
Timer_Value &= ~(1<<2); //清除定時器中斷標志
Timer_Value &= ~(1<<4); //當 TF 有效時 INT 有效 (取決于 TIE 的狀態)
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); //獲取控制/狀態寄存器2數值
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); //設置定時器控制寄存器
}
/**
*****************************************************************************
* @Name : 設置時間,主要用于后臺調用,或者初始化時間用
*
* @Brief : 秒默認就設置成0x00了,形參里面不體現,星期值范圍:0 ~ 6
*
* @Input : PCF_Format: 數據格式
* = PCF_Format_BIN
* = PCF_Format_BCD
* PCF_Century: 世紀位設定
* = 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)
{
//
//判斷數據是否符合范圍
//
if (Year > 99) Year = 0; //恢復00年
if (Month > 12) Month = 1; //恢復1月
if (Date > 31) Date = 1; //恢復1日
if (Week > 6) Week = 1; //恢復星期一
if (Hour > 23) Hour = 0; //恢復0小時
if (Minute > 59) Minute = 0; //恢復0分鐘
//
//轉換一下
//
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; //恢復0秒
Time_InitStructure.RTC_Seconds &= PCF_Accuracy_ClockYes; //保證準確的時間
//
//判斷世紀位
//
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); //寫入日期信息
}
/**
============================================================================
#### 所有寄存器全部操作功能函數 ####
============================================================================
**/
/**
*****************************************************************************
* @Name : 判斷時間信息是否符合范圍,超出將恢復初值
*
* @Brief : 星期值范圍:0 ~ 6
*
* @Input : PCF_DataStruct: 寄存器結構指針
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
static void IS_PCF8563_Data(_PCF8563_Register_Typedef* PCF_DataStruct)
{
if (PCF_DataStruct->Years > 99) PCF_DataStruct->Years = 0; //恢復00年
if (PCF_DataStruct->Months_Century > 12) PCF_DataStruct->Months_Century = 1; //恢復1月
if (PCF_DataStruct->Days > 31) PCF_DataStruct->Days = 1; //恢復1日
if (PCF_DataStruct->WeekDays > 6) PCF_DataStruct->WeekDays = 1; //恢復星期一
if (PCF_DataStruct->Hours > 23) PCF_DataStruct->Hours = 0; //恢復0小時
if (PCF_DataStruct->Minutes > 59) PCF_DataStruct->Minutes = 0; //恢復0分鐘
if (PCF_DataStruct->Seconds > 59) PCF_DataStruct->Seconds = 0; //恢復0秒
}
/**
*****************************************************************************
* @Name : PCF8563寫入寄存器
*
* @Brief : 星期數值范圍是: 0 ~ 6,十進制格式
*
* @Input : PCF_Format: 數據格式
* = PCF_Format_BIN
* = PCF_Format_BCD
* PCF_Century: 世紀位設定
* = PCF_Century_19xx
* = PCF_Century_20xx
* PCF_DataStruct: 寄存器結構指針
*
* @Output : none
*
* @Return : none
*****************************************************************************
**/
復制代碼
這邊有點亂碼 我就直接上傳文件了 有什么問題歡迎討論
51hei.png
(2.54 KB, 下載次數: 36)
下載附件
2024-4-28 14:49 上傳
注意代碼里面只有上圖2個文件,請自行移植到各MCU系統中去:
c文件和h文件下載.7z
(9.45 KB, 下載次數: 13)
2024-4-28 14:51 上傳
點擊文件名下載附件
部分代碼
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1