日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片

發布時間:2023/12/9 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 硬知識
    • 概述
    • 特性
    • 功能描述
      • 報警功能模式
      • 定時器模式
      • CLKOUT輸出
      • 復位低電壓檢測器和時鐘監視器
      • 低電壓檢測器和時鐘監視器
    • 寄存器結構
      • 寄存器概述
      • BCD編碼格式寄存器概述
      • Control/Status 1 寄存器(內存地址00H)
      • Control/Status 2 寄存器(內存地址01H)
      • Seconds,Minutes,Hours寄存器
      • Days,Weekdays,Months/Century,Years寄存器
      • Alarm寄存器
      • LKOUT頻率寄存器
      • 計數控制寄存器
    • EXT_CLK測試模式
    • 上電復位(POR)override模式
    • 串行接口
      • PCF8563 I2C協議
  • 驅動程序
    • PCF8563.c
    • PCF8563.h
  • 測試程序
    • main.c
    • 實驗現象

STC實驗箱4
IAP15W4K58S4
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知識

???????摘自《PCF8563實時時鐘日歷芯片選型指南》。

概述

???????PCF8563是低功耗的CMOS實時時鐘日歷芯片。它提供一個可編程時鐘輸出一個中斷輸出和掉電檢測器所有的地址和數據,通過12C總線接口串行傳遞最大總線速度為400Kbits/s,每次讀寫數據后內嵌的字地址寄存器會自動產生增量。

特性

低工作電流典型值:0.25 A(VDD=3.0V TambT_{amb}Tamb?=25)
世紀標志;
大工作電壓范圍:1.0V–5.5V;
低休眠電流典型值為:0.25 A(VDD=3.0V,TambT_{amb}Tamb?=25)
400KHz 的I2C接口:(VDD=1.8~5.5V)
可編程時鐘輸出頻率為:32.768KHz,1024Hz、32Hz,1Hz;
報警和定時器;
內部集成的振蕩器、電容、片內電源復位功能掉電檢測器;
I2C 從地址:讀0A3H; 寫0A2H;
開漏中斷引腳。

功能描述

???????PCF8563內有16個8位的地址遞增寄存器,一個32.768 kHz片上集成電容振蕩器,一個實時時鐘源(RTC)的分頻器,可編程的時鐘輸出,一個定時器,報警器,一個低壓檢測器和400KHz的I2C接口。
???????所有16個寄存器被設計成可尋址的8位并行寄存器,雖然不是所有的位都有效。前兩個寄存器(內存地址00H和01H),用于控制與或狀態寄存器。內存地址02H至08H是時鐘功能的計數器,用于(秒、分、時、日、月、年計數器),內存地址09H至0CH包含定義報警的條件的報警寄存器。內存地址0DH控制CLKOUT的輸出頻率.0EH和0FH分別是定時控制器和定時器。
???????秒、分鐘、小時、天、月、年、以及每分鐘報警、小時報警、日報警寄存器都以BCD格式編碼。平日和星期報警寄存器不以BCD格式編碼。
???????當一個RTC寄存器被讀取,所有的寄存器的內容被凍結。因此可以避免在讀指令跳轉期間,讀取時鐘/日歷時發生錯誤。

報警功能模式

???????通過清除一個或多個報警寄存器最高有效位(位AE-報警啟用),相應的報警條件將被激活。這種方式可以產生從每分鐘至每周一次的報警。報警條件設置報警標志,AF(控制/狀態寄存器2的第3位),AF可用于產生一個中斷(INT),AF只能通過軟件清零。

定時器模式

???????8位減數計時器(地址0FH)由定時控制寄存器(地址0EH,參見表25)控制。定時控制寄存器可以選擇定時器的時鐘源頻率(4096,64,1,或1/60Hz)和啟用/禁用計時器。從軟件加載的8位二進制值的倒計時,在每個倒計時結束時,定時器設置的定時器標志TF(見表7)。定時器標志位TF只能由軟件清零。根據定時器標志位TF可以產生一個中斷(INT)。每個倒計時階段都可能會產生中斷脈沖信號,作為一個永久的積極信號,如TF條件下。TI/TP(見表7)用于控制這種模式的選擇。當讀取定時器,當前的倒計時數值作為返回值。

CLKOUT輸出

???????CLKOUT引腳有可編程方波。由CLKOUT頻率寄存器(地址0DH;見表23)控制操作。時鐘頻率32.768KHz(默認),1024,32和1Hz的頻率可以作為系統時鐘,單片機的時鐘,輸入到電荷泵,或校準振蕩器。CLKOUT開漏輸出,上電時啟用。如果禁用它變為高阻抗。

復位低電壓檢測器和時鐘監視器

???????PCF8563的包括內部復位電路,振蕩器停止時,復位電路激活。在復位狀態下,I2C總線初始化,所有寄存器和地址指針被清零,VL,TD1,TD0,TESTC和AE被設置為邏輯1.

低電壓檢測器和時鐘監視器

???????PCF8563芯片的低電壓探測器。當VDD低于Vlow,VL位(秒寄存器第7位)設置表明可靠的時鐘/日歷信息將不再保證.VL標志只能由軟件清零。
???????位VL用于檢測在電池供電情況下,VDD慢慢降低到Vlow的情況。在VDD低于Vlow之前應該把VDD從新拉高。這種情況下,時間可能被損壞。

寄存器結構

寄存器概述

表4

位標記"-": 無效;
"0"標記的,應始終與寫入邏輯0.

BCD編碼格式寄存器概述

表5

位標記"-": 無效;
[1]不是BCD編碼格式。

Control/Status 1 寄存器(內存地址00H)

表6

Control/Status 2 寄存器(內存地址01H)

表7

Seconds,Minutes,Hours寄存器

Days,Weekdays,Months/Century,Years寄存器



Alarm寄存器

???????當一個或多個報警寄存器加載一個有效的分、時、日或平日信息,其相應的AE(Alarm Enable)位為邏輯0,然后將這些信息將與當前的分、時、日和平日進行比較。當所有啟用的比較第一個匹配的,位AF(Alarm Flag)置位。
???????AF保持置位,直到通過軟件清除。一旦AF被清0,它只會被重新設置時間增量,以符合再次報警條件。若報警寄存器AE置1,則該報警寄存器被忽略。

LKOUT頻率寄存器

計數控制寄存器

???????8位二進制減計數器有效與否是由計數控制寄存器的TE位控制,計數器的時鐘源也是由計數控制寄存器選擇.計數器中斷的產生與控制有狀態控制寄存器2控制。為了準確讀出計數器的值,I2C總線的SCL時鐘至少應為計數器時鐘的2倍。

EXT_CLK測試模式

???????測試模式允許進行在線測試,在測試環境下可以設置測試的條件并控制芯片的RTC.
???????通過設置控制狀態寄存器1(Control/Status 1)的位TEST1進入測試環境,CLKOUT管腳轉換為輸入管腳。測試模式下,CLKOUT管腳的輸入信號取代了芯片內部的64Hz的信號,CLKOUT管腳信號每64個上升沿產生1S增量。
???????CLKOUT管腳提供的信號的最小脈沖帶寬為300ns,最小周期為1000ns。內部64Hz時鐘,或者外部信號源被內部預分頻器分為1Hz,使用STOP預分頻器可設置成已知狀態,當位STOP置位,預分頻器復位為0。在預分頻器再次工作前,STOP位必須先清0.從STOP狀態,第一個1S的占用CLKOUT信號32個上升沿,之后每1S的增量占用64個上升沿。
???????備注:進入EXT_CLK測試模式內部64 Hz的時鐘不同步,進入測試模式時,可以假設沒有預分頻器的狀態。

  • 進入EXT_CLK測試模式,設置Control/Status 1寄存器的7位TEST1=1;
  • 設置Control/Status 1寄存器的5位STOP=1;
  • 清除Control/Status 1寄存器的5位STOP=0;
  • 設置時間寄存器(Seconds,Minutes,Hours,Days,Weekdays,Months/Century,Years)期望值;
  • 向CLOCKOUT提供32個時鐘脈沖;
  • 讀取時間寄存器,看第一次變化;
  • 向CLOCKOUT提供64個時鐘脈沖;
  • 讀取時間寄存器,看Second寄存器變化;
  • 重復第7,8步驟,看額外的變量;
  • 上電復位(POR)override模式

    ???????POR的持續時間和晶體振蕩器的啟動時間直接相關。由于長期啟動這些類型的電路所需要的時間,一個禁用POR和加強硬板設備測試機制已建成。這種模式的設置要求,I2C總線引腳,SDA和SCL,如圖5所示,在一個特定的順序切換。所有的時間值是最低要求。
    ???????一旦已進入override模式,芯片立即停止復位和正常運行,開始進入EXT_CLK測試模式,即通過I2C總線訪問。位TESTC寫邏輯0,停止override模式。只有位TESTC被設置為邏輯1,才能再次進入override模式。正常運行期間位TESTC設置邏輯0無效,只是為了防止進入POR override模式。

    串行接口

    ???????PCF8563的串行接口是I2C總線。

    PCF8563 I2C協議

    尋址:在12C總線上傳輸的任何數據之前,首先處理設備應該響應。尋址總是進行傳輸啟動程序后的第一個字節。
    ???????PCF8563是一個從接收器或從發送器。因此時鐘信號SCL只是一個輸入信號,但數據信號SDA是雙向線。
    PCF8563的從地址

    時鐘/日歷的讀/寫周期:在圖11,12和13所示為不同的PCF8563的I2C總線配置讀寫周期。
    WORD地址是一個4位的值,定義下一步要訪問寄存器。WORD地址的高4位未使用。

    驅動程序

    ???????來源:51單片機入門經驗分享8-關于IIC通信詳解及PCF8563芯片顯示時間 —— dabing89
    ???????stdint.h見【51單片機快速入門指南】1:基礎知識和工程創建
    ???????軟件I2C程序見【51單片機快速入門指南】4: 軟件 I2C

    PCF8563.c

    /******************************************************************************* * 文件名:PCF8563.c * 描 述:工程c模塊文件 * 功 能:底層模塊文件 * 作者:MADE BY DA HE TAO * 版本號:1.0.4(2015.03.02) *******************************************************************************/ #include "PCF8563.h" #include "./Soft_I2C/Soft_I2C.h"/******************************************************************************* * 文件名:變量定義 * 描 述: * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.05.23) *******************************************************************************/ uint8_t buffer[7];//數據存儲緩存 sTime CurTime;/******************************************************************************* * 文件名:static uint8_t RTC_BinToBcd2(uint8_t BINValue) * 描 述: 將BIN轉換為BCD * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ static uint8_t RTC_BinToBcd2(uint8_t BINValue) {uint8_t bcdhigh = 0;while (BINValue >= 10){bcdhigh++;BINValue -= 10;}return ((uint8_t)(bcdhigh << 4) | BINValue); }/******************************************************************************* * 文件名:static uint8_t RTC_Bcd2ToBin(uint8_t BCDValue) * 描 述: 將BCD轉換為BIN * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ static uint8_t RTC_Bcd2ToBin(uint8_t BCDValue) {uint8_t tmp = 0;tmp = ((uint8_t)(BCDValue & (uint8_t)0xF0) >> (uint8_t)0x04) * 10;return (tmp + (BCDValue & (uint8_t)0x0F)); }/******************************************************************************* * 文件名:void PCF8563_Write_Byte(uint8_t REG_ADD, uint8_t dat) * 描 述: PCF8563某寄存器寫入一個字節數據 * 功 能:REG_ADD:要操作寄存器地址 dat: 要寫入的數據 * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ void PCF8563_Write_Byte(uint8_t REG_ADD, uint8_t dat) {i2c_mem_write(PCF8563_ADDR, REG_ADD, &dat, 1); }/******************************************************************************* * 文件名:uint8_t PCF8563_Read_Byte(uint8_t REG_ADD) * 描 述: PCF8563某寄存器讀取一個字節數據 * 功 能:REG_ADD:要操作寄存器地址 讀取得到的寄存器的值 * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ uint8_t PCF8563_Read_Byte(uint8_t REG_ADD) {uint8_t ReData;i2c_mem_read(PCF8563_ADDR, REG_ADD, &ReData, 1);return ReData; }/******************************************************************************* * 文件名:void PCF8563_Write_nByte(uint8_t REG_ADD, uint8_t num, uint8_t *pBuff) * 描 述: PCF8563寫入多組數據 * 功 能:REG_ADD:要操作寄存器起始地址 num: 寫入數據數量 *WBuff: 寫入數據緩存 * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ void PCF8563_Write_nByte(uint8_t REG_ADD, uint8_t num, uint8_t *pBuff) {i2c_mem_write(PCF8563_ADDR, REG_ADD, pBuff, num); } /******************************************************************************* * 文件名:void PCF8563_Read_nByte(uint8_t REG_ADD, uint8_t num, uint8_t *pBuff) * 描 述: PCF8563讀取多組數據 * 功 能:REG_ADD:要操作寄存器起始地址 num: 寫入數據數量 *WBuff: 讀取數據緩存 * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ void PCF8563_Read_nByte(uint8_t REG_ADD, uint8_t num, uint8_t *pBuff) {i2c_mem_read(PCF8563_ADDR, REG_ADD, pBuff, num); }/******************************************************************************* * 文件名:void SetRealTime(sTime* time) * 描 述: PCF8563設置時間信息 * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ void SetRealTime(sTime* time) {////拷貝數據time->mon &= ~PCF_Century_SetBitC;buffer[0] = time->sec;buffer[1] = time->min;buffer[2] = time->hour;buffer[3] = time->day;buffer[4] = time->week;buffer[5] = time->mon;buffer[6] = time->year;//寫入數據到寄存器//PCF8563_Write_nByte(PCF8563_Address_Seconds, 7, buffer); }/******************************************************************************* * 文件名:void GetRealTime(sTime* time) * 描 述: PCF8563讀取時間信息 * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.03.03) *******************************************************************************/ void GetRealTime(sTime* time) {PCF8563_Read_nByte(PCF8563_Address_Seconds, 7, buffer); //讀取寄存器數值buffer[0] &= PCF8563_Shield_Seconds; //屏蔽無效位buffer[1] &= PCF8563_Shield_Minutes;buffer[2] &= PCF8563_Shield_Hours;buffer[3] &= PCF8563_Shield_Days;buffer[4] &= PCF8563_Shield_WeekDays;buffer[5] &= PCF8563_Shield_Months_Century;buffer[6] &= PCF8563_Shield_Years;time->year = buffer[6];time->mon = buffer[5];time->week = buffer[4];time->day = buffer[3];time->hour = buffer[2];time->min = buffer[1];time->sec = buffer[0];}/******************************************************************************* * 文件名: void PCF8563Init(void) * 描 述: PCF8563初始化時間 * 功 能: * 作 者:大核桃 * 版本號:1.0.1(2017.05.23) *******************************************************************************/ void PCF8563Init(void) {sTime InitTime = {0x22, 0x01, 0x10, 0x12,0x00,0x00,0x01}; //22年1月10日12時00分00秒星期一SetRealTime(&InitTime);PCF8563_Write_Byte(PCF8563_Address_Control_Status_1, 0x00); PCF8563_Write_Byte(PCF8563_Address_Control_Status_2, 0x00); }

    PCF8563.h

    /******************************************************************************* * 文件名:PCF8563.h * 描 述:工程模塊頭文件 * 作者:MADE BY DA HE TAO * 版本號:1.0.1(2014.11.29) *******************************************************************************/ #ifndef _PCF8563_H #define _PCF8563_H#include <stdint.h>/*********************************************/ //數據類型定義部分 //定義結構體變量等 /********************************************/typedef struct {uint16_t year;uint8_t mon;uint8_t day;uint8_t hour;uint8_t min;uint8_t sec;uint8_t week; }sTime;/*********************************************/ //預編譯部分 /********************************************//* 此處定義全局變量及函數 */ extern sTime CurTime;/*********************************************/ //子函數引用聲明部分 /********************************************/#define PCF8563_Check_Data (uint8_t)0x55 //檢測用,可用其他數值#define PCF8563_ADDR (uint8_t)0x51 //7位地址 #define PCF8563_Write (uint8_t)0xa2 //寫命令 #define PCF8563_Read (uint8_t)0xa3 //讀命令,或者用(PCF8563_Write + 1)// //電源復位功能 // #define PCF8563_PowerResetEnable (uint8_t)0x08 #define PCF8563_PowerResetDisable (uint8_t)0x09// //世紀位操作定義 // #define PCF_Century_SetBitC (uint8_t)0x80#define PCF_Century_19xx (uint8_t)0x03 #define PCF_Century_20xx (uint8_t)0x04// //數據格式 // #define PCF_Format_BIN (uint8_t)0x01 #define PCF_Format_BCD (uint8_t)0x02// //設置PCF8563模式用 // #define PCF_Mode_Normal (uint8_t)0x05/******************************************************************************參數寄存器地址宏定義 ******************************************************************************/#define PCF8563_Address_Control_Status_1 (uint8_t)0x00 //控制/狀態寄存器1 #define PCF8563_Address_Control_Status_2 (uint8_t)0x01 //控制/狀態寄存器2/******************************************************************************參數屏蔽宏定義 ******************************************************************************/#define PCF8563_Shield_Control_Status_1 (uint8_t)0xa8 #define PCF8563_Shield_Control_Status_2 (uint8_t)0x1f#define PCF8563_Shield_Seconds (uint8_t)0x7f #define PCF8563_Shield_Minutes (uint8_t)0x7f #define PCF8563_Shield_Hours (uint8_t)0x3f#define PCF8563_Shield_Days (uint8_t)0x3f #define PCF8563_Shield_WeekDays (uint8_t)0x07 #define PCF8563_Shield_Months_Century (uint8_t)0x1f #define PCF8563_Shield_Years (uint8_t)0xff/******************************************************************************參數宏定義 ******************************************************************************/ #define PCF8563_Address_Years (uint8_t)0x08 //年 #define PCF8563_Address_Months (uint8_t)0x07 //月 #define PCF8563_Address_Days (uint8_t)0x05 //日 #define PCF8563_Address_WeekDays (uint8_t)0x06 //星期 #define PCF8563_Address_Hours (uint8_t)0x04 //小時 #define PCF8563_Address_Minutes (uint8_t)0x03 //分鐘 #define PCF8563_Address_Seconds (uint8_t)0x02 //秒 //控制/狀態寄存器1 --> 0x00 // #define PCF_Control_Status_NormalMode (uint8_t)(~(1<<7)) //普通模式 #define PCF_Control_Status_EXT_CLKMode (uint8_t)(1<<7) //EXT_CLK測試模式 #define PCF_Control_ChipRuns (uint8_t)(~(1<<5)) //芯片運行 #define PCF_Control_ChipStop (uint8_t)(1<<5) //芯片停止運行,所有芯片分頻器異步置邏輯0 #define PCF_Control_TestcClose (uint8_t)(~(1<<3)) //電源復位功能失效(普通模式時置邏輯0) #define PCF_Control_TestcOpen (uint8_t)(1<<3) //電源復位功能有效 //秒寄存器 --> 0x02 // #define PCF_Accuracy_ClockNo (uint8_t)(1<<7) //不保證準確的時鐘/日歷數據 #define PCF_Accuracy_ClockYes (uint8_t)(~(1<<7)) //保證準確的時鐘/日歷數據/******************************************************************************外部功能函數 ******************************************************************************/void PCF8563_Write_Byte (uint8_t REG_ADD, uint8_t dat); //PCF8563某寄存器寫入一個字節數據 uint8_t PCF8563_Read_Byte (uint8_t REG_ADD); //PCF8563某寄存器讀取一個字節數據 void PCF8563_Write_nByte (uint8_t REG_ADD, uint8_t num, uint8_t *pBuff); //PCF8563寫入多組數據 void PCF8563_Read_nByte (uint8_t REG_ADD, uint8_t num, uint8_t *pBuff); //PCF8563讀取多組數據void SetRealTime(sTime *time); //PCF8563寫入時間信息 void GetRealTime(sTime *time); //PCF8563讀取時間信息 void PCF8563Init(void);#endif/******************* (C) COPYRIGHT 2016 青藍電子科技 *****END OF FILE****/

    測試程序

    main.c

    #include "./Drivers/config.h" #include "./Drivers/delay.h"#include "./Drivers/GPIO.h" #include "./Drivers/soft_uart.h" #include <stdio.h>char putchar(char Char) {TxSend(Char);return Char; }#include "PCF8563.h"void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //結構定義GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的輸入或輸出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); }void main(void) {GPIO_config();PCF8563Init();while(1){GetRealTime(&CurTime);//讀取時間printf("%x %x %x %x %x %x %x\r\n", (int)CurTime.year, (int)CurTime.mon, (int)CurTime.day, (int)CurTime.hour, (int)CurTime.min, (int)CurTime.sec, (int)CurTime.week);delay_ms(500);} }

    實驗現象

    ???????打開串口調試助手,可見能成功讀取時鐘值。

    總結

    以上是生活随笔為你收集整理的【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。