wwwxxx国产_337p日本欧洲亚洲大胆张筱雨_免费在线看成人av_日本黄色不卡视频_国产精品成熟老女人_99视频一区_亚洲精品97久久中文字幕_免费精品视频在线_亚洲色图欧美视频_欧美一区二三区

標題: 51單片機入門經驗分享8-關于IIC通信詳解及PCF8563芯片顯示時間 [打印本頁]

作者: dabing89    時間: 2018-10-13 11:20
標題: 51單片機入門經驗分享8-關于IIC通信詳解及PCF8563芯片顯示時間
                                    關于IIC通信詳解及PCF8563芯片顯示時間數據


    這一節,我們的程序代碼主要是將PCF8563芯片采集到的時間數據顯示在數碼管上,但是在完成這個任務之前,我們先來看下IIC協議,了解這個協議很重要,沒辦法,IIC確實讓人稀里糊涂的,先把PCF8563部分的代碼貼出來,然后我們對照PCF8563的數據手冊來看IIC的底層讀寫是怎么實現的。代碼如下:解釋看下面文字,我們的重點不是PCF8563這個芯片,而是IIC協議,這個代碼也是我整理網上的,先把數據手冊上傳 PCF8563數據手冊.pdf (630.02 KB, 下載次數: 233)


  1. /*******************************************************************************
  2. * 文件名:PCF8563.c
  3. * 描  述:工程c模塊文件
  4. * 功 能:底層模塊文件
  5. * 作者:MADE BY DA HE TAO
  6. * 版本號:1.0.4(2015.03.02)
  7. *******************************************************************************/
  8. #define _PCF8563_C
  9. #include "main.h"



  10. /*******************************************************************************
  11. * 文件名:變量定義
  12. * 描  述:   
  13. * 功  能:
  14. * 作  者:大核桃
  15. * 版本號:1.0.1(2017.05.23)
  16. *******************************************************************************/
  17. uint8 buffer[7];//數據存儲緩存
  18. sTime CurTime;

  19. /*******************************************************************************
  20. * 文件名:void IIC_Delay()
  21. * 描  述:
  22. * 功  能:
  23. * 作  者:大核桃
  24. * 版本號:1.0.1(2017.03.03)
  25. *******************************************************************************/
  26. void IIC_Delay()
  27. {
  28.         _nop_();
  29.         _nop_();
  30.         _nop_();
  31.         _nop_();
  32.         _nop_();
  33.         _nop_();
  34. }

  35. /*******************************************************************************
  36. * 文件名:void IIC_Start(void)
  37. * 描  述: IIC啟動
  38. * 功  能:
  39. * 作  者:大核桃
  40. * 版本號:1.0.1(2017.03.03)
  41. *******************************************************************************/
  42. void IIC_Start(void)
  43. {
  44.         IIC_SDA = 1;        //為SDA下降啟動做準備
  45.         IIC_SCL = 1;        //在SCL高電平時,SDA為下降沿時候總線啟動

  46.         IIC_Delay();
  47.         IIC_SDA = 0;        //突變,總線啟動
  48.         IIC_Delay();
  49.         IIC_SCL = 0;
  50.         IIC_Delay();
  51. }

  52. /*******************************************************************************
  53. * 文件名:void IIC_Stop(void)
  54. * 描  述: IIC停止
  55. * 功  能:
  56. * 作  者:大核桃
  57. * 版本號:1.0.1(2017.03.03)
  58. *******************************************************************************/
  59. void IIC_Stop(void)
  60. {
  61.         IIC_SDA = 0;        //為SDA上升做準備

  62.         IIC_Delay();
  63.         IIC_SCL = 1;        //在SCL高電平時,SDA為上升沿時候總線停止
  64.         IIC_Delay();
  65.         IIC_SDA = 1;        //突變,總線停止
  66.         IIC_Delay();
  67. }
  68. /*******************************************************************************
  69. * 文件名:void IIC_Ack(u8 a)
  70. * 描  述: 主機向從機發送應答信號
  71. * 功  能:0:應答信號 1:非應答信號
  72. * 作  者:大核桃
  73. * 版本號:1.0.1(2017.03.03)
  74. *******************************************************************************/
  75. void IIC_Ack(bit a)
  76. {                        
  77.         if(a)        IIC_SDA = 1;        //放上應答信號電平
  78.         else        IIC_SDA = 0;

  79.         IIC_Delay();
  80.         IIC_SCL = 1;        //為SCL下降做準備
  81.         IIC_Delay();
  82.         IIC_SCL = 0;        //突變,將應答信號發送過去
  83.         IIC_Delay();
  84. }

  85. /*******************************************************************************
  86. * 文件名:u8 IIC_Write_Byte(u8 dat)
  87. * 描  述: 向IIC總線發送一個字節數據
  88. * 功  能:dat:要發送的數據          ack:返回應答信號
  89. * 作  者:大核桃
  90. * 版本號:1.0.1(2017.03.03)
  91. *******************************************************************************/
  92. uint8 IIC_Write_Byte(uint8 dat)
  93. {
  94.         uint8 iic_ack=0;        //iic應答標志
  95.         uint8 mask = 0;

  96. //        for(i = 0;i < 8;i++)
  97. //        {
  98. //                if(dat & 0x80)        IIC_SDA = 1;        //判斷發送位,先發送高位
  99. //                else        IIC_SDA = 0;
  100. //                IIC_Delay();
  101. //                IIC_SCL = 1;        //為SCL下降做準備
  102. //                IIC_Delay();
  103. //                IIC_SCL = 0;        //突變,將數據位發送過去
  104. //                dat<<=1;        //數據左移一位
  105. //        }        //字節發送完成,開始接收應答信號

  106.         for(mask = 0x80; mask!= 0x00; mask >>= 1)
  107.         {
  108.                 if(mask & dat)
  109.                 {
  110.                   IIC_SDA = 1;        
  111.                 }
  112.                 else
  113.                 {
  114.                         IIC_SDA = 0;
  115.                 }

  116.                 IIC_Delay();
  117.                 IIC_SCL = 1;        //為SCL下降做準備
  118.                 IIC_Delay();
  119.                 IIC_SCL = 0;        //突變,將數據位發送過去


  120.         }

  121.         IIC_SDA = 1;        //釋放數據線
  122.         IIC_Delay();
  123.         IIC_SCL = 1;        //為SCL下降做準備
  124.         IIC_Delay();
  125.         //字節發送完成,開始接收應答信號
  126.         
  127.         iic_ack |= IIC_SDA;        //讀入應答位
  128.         IIC_SCL = 0;
  129.         return iic_ack;        //返回應答信號
  130. }
  131. /*******************************************************************************
  132. * 文件名:u8 IIC_Read_Byte(void)
  133. * 描  述: 從IIC總線上讀取一個字節數據
  134. * 功  能:x:讀取到的數據
  135. * 作  者:大核桃
  136. * 版本號:1.0.1(2017.03.03)
  137. *******************************************************************************/
  138. uint8 IIC_Read_Byte(void)
  139. {
  140.         uint8 x=0;
  141.         uint8 mask;

  142.         IIC_SDA = 1;        //首先置數據線為高電平

  143. //        for(i = 0;i < 8;i++)
  144. //        {
  145. //                x <<= 1;        //讀入數據,高位在前
  146. //                IIC_Delay();
  147. //                IIC_SCL = 1;        //突變
  148. //                IIC_Delay();
  149. //               
  150. //                if(IIC_SDA)        
  151. //                x |= 0x01;        //收到高電平
  152. //
  153. //                IIC_SCL = 0;
  154. //                IIC_Delay();
  155. //        }        //數據接收完成

  156.         for(mask = 0x80; mask != 0x00; mask >>= 1)
  157.         {
  158.                 IIC_Delay();
  159.                 IIC_SCL = 1;        //突變
  160.                 IIC_Delay();

  161.                 if(IIC_SDA)
  162.                 {
  163.                         x |= mask;        
  164.                 }
  165.                 else
  166.                 {
  167.                         x &= ~mask;//
  168.                 }

  169.                 IIC_SCL = 0;
  170.                 IIC_Delay();
  171.         }

  172.         IIC_SCL = 0;

  173.         return x;        //返回讀取到的數據
  174. }

  175. /*******************************************************************************
  176. * 文件名:static unsigned char RTC_BinToBcd2(unsigned char BINValue)
  177. * 描  述: 將BIN轉換為BCD
  178. * 功  能:
  179. * 作  者:大核桃
  180. * 版本號:1.0.1(2017.03.03)
  181. *******************************************************************************/
  182. static unsigned char RTC_BinToBcd2(unsigned char BINValue)
  183. {
  184.         unsigned char bcdhigh = 0;
  185.         
  186.         while (BINValue >= 10)
  187.         {
  188.                 bcdhigh++;
  189.                 BINValue -= 10;
  190.         }
  191.         
  192.         return ((unsigned char)(bcdhigh << 4) | BINValue);
  193. }

  194. /*******************************************************************************
  195. * 文件名:static unsigned char RTC_Bcd2ToBin(unsigned char BCDValue)
  196. * 描  述: 將BCD轉換為BIN
  197. * 功  能:
  198. * 作  者:大核桃
  199. * 版本號:1.0.1(2017.03.03)
  200. *******************************************************************************/
  201. static unsigned char RTC_Bcd2ToBin(unsigned char BCDValue)
  202. {
  203.         unsigned char tmp = 0;
  204.         
  205.         tmp = ((unsigned char)(BCDValue & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
  206.         return (tmp + (BCDValue & (unsigned char)0x0F));
  207. }

  208. /*******************************************************************************
  209. * 文件名:void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  210. * 描  述: PCF8563某寄存器寫入一個字節數據
  211. * 功  能:REG_ADD:要操作寄存器地址          dat:    要寫入的數據
  212. * 作  者:大核桃
  213. * 版本號:1.0.1(2017.03.03)
  214. *******************************************************************************/
  215. void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  216. {
  217.         IIC_Start();
  218.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  219.         {
  220.                 IIC_Write_Byte(REG_ADD);
  221.                 IIC_Write_Byte(dat);  //發送數據
  222.         }
  223.         IIC_Stop();
  224. }

  225. /*******************************************************************************
  226. * 文件名:unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  227. * 描  述: PCF8563某寄存器讀取一個字節數據
  228. * 功  能:REG_ADD:要操作寄存器地址          讀取得到的寄存器的值
  229. * 作  者:大核桃
  230. * 版本號:1.0.1(2017.03.03)
  231. *******************************************************************************/
  232. unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  233. {
  234.         unsigned char ReData;
  235.         
  236.         IIC_Start();
  237.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  238.         {
  239.                 IIC_Write_Byte(REG_ADD);  //確定要操作的寄存器
  240.                 IIC_Start();  //重啟總線
  241.                 IIC_Write_Byte(0xa3);  //發送讀取命令
  242.                 ReData = IIC_Read_Byte();  //讀取數據
  243.                 IIC_Ack(1);  //發送非應答信號結束數據傳送
  244.         }
  245.         IIC_Stop();
  246.         return ReData;
  247. }

  248. /*******************************************************************************
  249. * 文件名:void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  250. * 描  述: PCF8563寫入多組數據
  251. * 功  能:REG_ADD:要操作寄存器起始地址          num:    寫入數據數量           *WBuff: 寫入數據緩存
  252. * 作  者:大核桃
  253. * 版本號:1.0.1(2017.03.03)
  254. *******************************************************************************/
  255. void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  256. {
  257.         unsigned char i = 0;
  258.                         
  259.         IIC_Start();
  260.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  261.         {
  262.                 IIC_Write_Byte(REG_ADD);  //定位起始寄存器地址
  263.                 for(i = 0;i < num;i++)
  264.                 {
  265.                         IIC_Write_Byte(*pBuff);  //寫入數據
  266.                         pBuff++;
  267.                 }
  268.         }
  269.         IIC_Stop();
  270. }
  271. /*******************************************************************************
  272. * 文件名:void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  273. * 描  述: PCF8563讀取多組數據
  274. * 功  能:REG_ADD:要操作寄存器起始地址          num:    寫入數據數量           *WBuff: 讀取數據緩存
  275. * 作  者:大核桃
  276. * 版本號:1.0.1(2017.03.03)
  277. *******************************************************************************/
  278. void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  279. {
  280.         unsigned char i = 0;
  281.         
  282.         IIC_Start();
  283.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  284.         {
  285.                 IIC_Write_Byte(REG_ADD);  //定位起始寄存器地址
  286.                 IIC_Start();  //重啟總線
  287.                 IIC_Write_Byte(0xa3);  //發送讀取命令
  288.                 for(i = 0;i < num;i++)
  289.                 {
  290.                         *pBuff = IIC_Read_Byte();  //讀取數據
  291.                         if(i == (num - 1))        IIC_Ack(1);  //發送非應答信號
  292.                         else IIC_Ack(0);  //發送應答信號
  293.                         pBuff++;
  294.                 }
  295.         }
  296.         IIC_Stop();        
  297. }

  298. /*******************************************************************************
  299. * 文件名:void SetRealTime(sTime* time)
  300. * 描  述: PCF8563設置時間信息
  301. * 功  能:
  302. * 作  者:大核桃
  303. * 版本號:1.0.1(2017.03.03)
  304. *******************************************************************************/
  305. void SetRealTime(sTime* time)
  306. {
  307.         //
  308.         //拷貝數據
  309.         time->mon &= ~PCF_Century_SetBitC;

  310.         buffer[0] = time->sec;
  311.         buffer[1] = time->min;
  312.         buffer[2] = time->hour;
  313.         buffer[3] = time->day;
  314.         buffer[4] = time->week;
  315.         buffer[5] = time->mon;
  316.         buffer[6] = time->year;
  317.         //寫入數據到寄存器
  318.         //
  319.         PCF8563_Write_nByte(PCF8563_Address_Seconds, 7, buffer);
  320. }

  321. /*******************************************************************************
  322. * 文件名:void GetRealTime(sTime* time)
  323. * 描  述: PCF8563讀取時間信息
  324. * 功  能:
  325. * 作  者:大核桃
  326. * 版本號:1.0.1(2017.03.03)
  327. *******************************************************************************/
  328. void GetRealTime(sTime* time)
  329. {
  330.         PCF8563_Read_nByte(PCF8563_Address_Seconds, 7, buffer);        //讀取寄存器數值
  331.         buffer[0] &= PCF8563_Shield_Seconds;         //屏蔽無效位
  332.         buffer[1] &= PCF8563_Shield_Minutes;
  333.         buffer[2] &= PCF8563_Shield_Hours;
  334.         buffer[3] &= PCF8563_Shield_Days;
  335.         buffer[4] &= PCF8563_Shield_WeekDays;
  336.         buffer[5] &= PCF8563_Shield_Months_Century;
  337.         buffer[6] &= PCF8563_Shield_Years;
  338.         
  339.         time->year  = buffer[6];
  340.         time->mon   = buffer[5];
  341.         time->week = buffer[4];
  342.         time->day   = buffer[3];
  343.         time->hour  = buffer[2];
  344.         time->min = buffer[1];
  345.         time->sec = buffer[0];

  346. }

  347. /*******************************************************************************
  348. * 文件名: void PCF8563Init(void)
  349. * 描  述:  PCF8563初始化時間   
  350. * 功  能:
  351. * 作  者:大核桃
  352. * 版本號:1.0.1(2017.05.23)
  353. *******************************************************************************/
  354. void PCF8563Init(void)
  355. {        
  356.         sTime code InitTime[] = {0x17,0x06,0x21, 0x22,0x11,0x00,0x03}; //年月日時分秒星期
  357.         SetRealTime(&InitTime);
  358. }
復制代碼
打開器件的數據手冊


關于IIC的起始信號和停止信號的定義



從上圖可以看出,在SCL高電平的時候,SDA由高電平到低電平的跳變作為START信號
/*******************************************************************************
  1. * 文件名:void IIC_Start(void)
  2. * 描  述: IIC啟動
  3. * 功  能:
  4. * 作  者:大核桃
  5. * 版本號:1.0.1(2017.03.03)
  6. *******************************************************************************/
  7. void IIC_Start(void)
  8. {
  9.         IIC_SDA = 1;        //為SDA下降啟動做準備
  10.         IIC_SCL = 1;        //在SCL高電平時,SDA為下降沿時候總線啟動

  11.         IIC_Delay();
  12.         IIC_SDA = 0;        //突變,總線啟動
  13.         IIC_Delay();
  14.         IIC_SCL = 0;
  15.         IIC_Delay();
  16. }
復制代碼
再來看停止信號的定義



在SCL為高電平的時候,SDA由低電平到高電平的跳變作為停止信號
  1. /*******************************************************************************
  2. * 文件名:void IIC_Stop(void)
  3. * 描  述:     IIC停止
  4. * 功  能:
  5. * 作  者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. void IIC_Stop(void)
  9. {
  10.         IIC_SDA = 0;        //為SDA上升做準備

  11.         IIC_Delay();
  12.         IIC_SCL = 1;        //在SCL高電平時,SDA為上升沿時候總線停止
  13.         IIC_Delay();
  14.         IIC_SDA = 1;        //突變,總線停止
  15.         IIC_Delay();
  16. }
復制代碼
看著時序圖很容易就能夠理解的。

接下來我們看下位傳輸的示意圖


從上圖可以看出,SCL為高電平的時候,SDA上的數據被認為是有效的,是可以被讀取或者寫入的,SCL為低電平的時候,SDA的數據是不穩定的,可以任意變化。


關于應答信號和非應答信號


IIC規定應答信號是0,非應答信號是1,如下圖所示這樣,相關程序如下:
  1. /*******************************************************************************
  2. * 文件名:void IIC_Ack(u8 a)
  3. * 描 述: 主機向從機發送應答信號
  4. * 功 能:0:應答信號 1:非應答信號
  5. * 作 者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. void IIC_Ack(bit a)
  9. {        
  10. if(a)        IIC_SDA = 1;        //放上應答信號電平
  11. else        IIC_SDA = 0;

  12. IIC_Delay();
  13. IIC_SCL = 1;        //為SCL下降做準備
  14. IIC_Delay();
  15. IIC_SCL = 0;        //突變,將應答信號發送過去
  16. IIC_Delay();
  17. }
復制代碼


請注意這個子函數不是用來寫字節使用的,是單片機讀數據專用的,啥意思呢?單片機寫字節的時候,是從機返回的應答位,是PCF8563主動返回的,這里的主動相當于是一個按鍵信號,這里的IO是作為按鍵輸入了,不再是輸出信號,這也解釋了為什么很多人寫代碼,總要加一個拉高等于釋放的解釋,什么是釋放?從51單片機IO的結構上判斷,如下圖所示,內部總線寫一個0,在寫鎖存器的幫助下,Q會輸出一個0,Q~輸出一個1,MOS管導通,拉低到低電位,如果內部總線寫一個1,MOS不導通,那么IO會被上拉電阻拉到高電平。這就是IO的輸出0或者1的過程。我們再來看一下輸入信號,


如果你輸出一個0,那么單片機還能夠讀取外部信號嗎?不可能的,因為一直都是0的,就算你按下按鍵也是百搭的,所以必須要拉高,釋放掉,這樣按鍵按下的時候才會在單片機讀引腳信號的幫助下被寫入內部總線上。這下應該明白了吧?
剛才我們說了寫字節要返回的應答位,那么上面這個子函數是讀字節的,誰來讀?當然是單片機來讀啊,也就是說單片機每讀取一個字節,都要向PCF8563發送一個應答位,表示我還要讀你的數據,PCF8563這邊的地址都是自動累加的,不需要管,等到單片機不想讀了,發送一個非應答信號1,結束通信,這就是應答和非應答的由來。





接下來我們再來看下IIC總線讀寫字節函數,這個很有參考意義,因為不管是啥協議,不是從高位開始讀寫就是從低位開始讀寫,具體的時序可能不一樣,但是這個實現的過程是比較有參考意義的,先來看IIC總線寫字節函數,代碼如下
  1. /*******************************************************************************
  2. * 文件名:u8 IIC_Write_Byte(u8 dat)
  3. * 描  述: 向IIC總線發送一個字節數據
  4. * 功  能:dat:要發送的數據          ack:返回應答信號
  5. * 作  者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. uint8 IIC_Write_Byte(uint8 dat)
  9. {
  10.         uint8 iic_ack=0;        //iic應答標志
  11.         uint8 mask = 0;

  12. //        for(i = 0;i < 8;i++)
  13. //        {
  14. //                if(dat & 0x80)        IIC_SDA = 1;        //判斷發送位,先發送高位
  15. //                else        IIC_SDA = 0;
  16. //                IIC_Delay();
  17. //                IIC_SCL = 1;        //為SCL下降做準備
  18. //                IIC_Delay();
  19. //                IIC_SCL = 0;        //突變,將數據位發送過去
  20. //                dat<<=1;        //數據左移一位
  21. //        }        //字節發送完成,開始接收應答信號

  22.         for(mask = 0x80; mask!= 0x00; mask >>= 1)
  23.         {
  24.                 if(mask & dat)
  25.                 {
  26.                   IIC_SDA = 1;        
  27.                 }
  28.                 else
  29.                 {
  30.                         IIC_SDA = 0;
  31.                 }

  32.                 IIC_Delay();
  33.                 IIC_SCL = 1;        //為SCL下降做準備
  34.                 IIC_Delay();
  35.                 IIC_SCL = 0;        //突變,將數據位發送過去


  36.         }

  37.         IIC_SDA = 1;        //釋放數據線
  38.         IIC_Delay();
  39.         IIC_SCL = 1;        //為SCL下降做準備
  40.         IIC_Delay();
  41.         //字節發送完成,開始接收應答信號
  42.         
  43.         iic_ack |= IIC_SDA;        //讀入應答位
  44.         IIC_SCL = 0;
  45.         return iic_ack;        //返回應答信號
  46. }
復制代碼
看到被注釋掉的那部分了嗎?和沒有被注釋掉的那部分的作用是一樣一樣的,這個我們先不管他,對于寫單個字節,IIC是這么規定的,先從高位開始讀寫,每寫入一個字節,從機要返回一個應答位,這里的主機指的是單片機,這里的從機指的是采用IIC接口的器件,比如AT24C02,PCF8563等等,也就是說單片機寫入PCF8563某寄存器一個字節后,PCF8563要主動返回一個應答位,這個應答位是0來表示,非應答位用1來表示,實現過程看前邊關于IO的解釋。上面這2種寫字節是一樣的,先來看第一種,我們要讀一個字節,總共8位數據,那么,新建一個循環,先從高位開始發,那么,就這樣寫,如果data數據的最高位是1,那么IIC_SDA就是1,否則IIC_SDA就是0,然后就是拉高IIC_SCL讓數據保持穩定,讓總線來接收這個信號,結束完之后,數據左移就可以了,直到把8位數據發送完畢,就是這樣。

再來看下面這種寫法
  1.         for(mask = 0x80; mask!= 0x00; mask >>= 1)
  2.         {
  3.                 if(mask & dat)
  4.                 {
  5.                   IIC_SDA = 1;        
  6.                 }
  7.                 else
  8.                 {
  9.                         IIC_SDA = 0;
  10.                 }

  11.                 IIC_Delay();
  12.                 IIC_SCL = 1;        //為SCL下降做準備
  13.                 IIC_Delay();
  14.                 IIC_SCL = 0;        //突變,將數據位發送過去


  15.         }
復制代碼
這種寫法是移位,先讀高位,讓位移動,而不是讓數據移動,正好移動8次,這個寫法很好,推薦給大家,很容易讓人理解,寫完8個循環之后,拉高SDA,準備讀取SDA輸入的信號,就是這樣。同樣的讀字節函數,請自我分析完成,一樣的道理。

  1.         IIC_SDA = 1;        //釋放數據線
  2.         IIC_Delay();
  3.         IIC_SCL = 1;        //為SCL下降做準備
  4.         IIC_Delay();
  5.         //字節發送完成,開始接收應答信號
  6.         
  7.         iic_ack |= IIC_SDA;        //讀入應答位
  8.         IIC_SCL = 0;
  9.         return iic_ack;        //返回應答信號
復制代碼
再來看下要操作PCF8563這個芯片,要遵循下面這個時序,先來看代碼

  1. /*******************************************************************************
  2. * 文件名:void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  3. * 描  述: PCF8563某寄存器寫入一個字節數據
  4. * 功  能:REG_ADD:要操作寄存器地址          dat:    要寫入的數據
  5. * 作  者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. void PCF8563_Write_Byte(unsigned char REG_ADD, unsigned char dat)
  9. {
  10.         IIC_Start();
  11.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  12.         {
  13.                 IIC_Write_Byte(REG_ADD);
  14.                 IIC_Write_Byte(dat);  //發送數據
  15.         }
  16.         IIC_Stop();
  17. }
復制代碼






從上圖可以看出一個完整的寫模式包括 起始信號+設備地址+應答信號+數據地址+應答信號+數據+應答信號+停止信號 組成,每寫入一個字節,PCF8563都要返回一個應答信號0,表示我正確的接收了,相當于一個回執。PCF8563的寫設備地址固定是0XA2,通過程序,可以很容易的理解上面的代碼了。


再來看下PCF8563讀單個字節函數
  1. /*******************************************************************************
  2. * 文件名:unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  3. * 描  述: PCF8563某寄存器讀取一個字節數據
  4. * 功  能:REG_ADD:要操作寄存器地址          讀取得到的寄存器的值
  5. * 作  者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. unsigned char PCF8563_Read_Byte(unsigned char REG_ADD)
  9. {
  10.         unsigned char ReData;
  11.         
  12.         IIC_Start();
  13.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  14.         {
  15.                 IIC_Write_Byte(REG_ADD);  //確定要操作的寄存器
  16.                 IIC_Start();  //重啟總線
  17.                 IIC_Write_Byte(0xa3);  //發送讀取命令
  18.                 ReData = IIC_Read_Byte();  //讀取數據
  19.                 IIC_Ack(1);  //發送非應答信號結束數據傳送
  20.         }
  21.         IIC_Stop();
  22.         return ReData;
  23. }
復制代碼
我們看下他的時序圖:


注意PCF8563讀寄存器字節的設備地址固定0XA3,按照時序圖,很容易就能夠理解這段代碼的。

寫多個字節和讀多個字節的函數也是比較容易的,唯一要注意的是時序圖中的解釋,ack from master 和ack from slave 這個一定要理解明白,寫字節對應的是slave,是主機寫,從機返回應答,from master 是讀字節,是主機發出應答或者非應答,從機響應。
  1. /*******************************************************************************
  2. * 文件名:void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  3. * 描  述: PCF8563寫入多組數據
  4. * 功  能:REG_ADD:要操作寄存器起始地址          num:    寫入數據數量           *WBuff: 寫入數據緩存
  5. * 作  者:大核桃
  6. * 版本號:1.0.1(2017.03.03)
  7. *******************************************************************************/
  8. void PCF8563_Write_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  9. {
  10.         unsigned char i = 0;
  11.                         
  12.         IIC_Start();
  13.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  14.         {
  15.                 IIC_Write_Byte(REG_ADD);  //定位起始寄存器地址
  16.                 for(i = 0;i < num;i++)
  17.                 {
  18.                         IIC_Write_Byte(*pBuff);  //寫入數據
  19.                         pBuff++;
  20.                 }
  21.         }
  22.         IIC_Stop();
  23. }
  24. /*******************************************************************************
  25. * 文件名:void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  26. * 描  述: PCF8563讀取多組數據
  27. * 功  能:REG_ADD:要操作寄存器起始地址          num:    寫入數據數量           *WBuff: 讀取數據緩存
  28. * 作  者:大核桃
  29. * 版本號:1.0.1(2017.03.03)
  30. *******************************************************************************/
  31. void PCF8563_Read_nByte(unsigned char REG_ADD, unsigned char num, unsigned char *pBuff)
  32. {
  33.         unsigned char i = 0;
  34.         
  35.         IIC_Start();
  36.         if(!(IIC_Write_Byte(0xa2)))  //發送寫命令并檢查應答位
  37.         {
  38.                 IIC_Write_Byte(REG_ADD);  //定位起始寄存器地址
  39.                 IIC_Start();  //重啟總線
  40.                 IIC_Write_Byte(0xa3);  //發送讀取命令
  41.                 for(i = 0;i < num;i++)
  42.                 {
  43.                         *pBuff = IIC_Read_Byte();  //讀取數據
  44.                         if(i == (num - 1))        IIC_Ack(1);  //發送非應答信號
  45.                         else IIC_Ack(0);  //發送應答信號
  46.                         pBuff++;
  47.                 }
  48.         }
  49.         IIC_Stop();        
  50. }
復制代碼
好了,就到這里吧,這個程序的結果是寫入PCF8563時間信息,PCF8563讀取到的時間信息顯示在數碼管上。



代碼上傳
011 PCF8563顯示時鐘.rar (201.48 KB, 下載次數: 300)





作者: 落葉無情。。    時間: 2018-10-23 07:51
正好這不懂,謝謝啦
作者: paulmark    時間: 2018-10-24 16:52
好詳細,很久沒有看到那么用心的人了
作者: kiki_1314    時間: 2018-10-26 14:44
學到了,Thanks♪(・ω・)ノ
作者: 嘿嘿!我愛51    時間: 2018-10-29 22:10
謝謝!
作者: 臺風天然粉    時間: 2018-10-30 12:21
帖子很好,詳細正好用到
作者: ZXCLH    時間: 2018-10-31 14:17
正好這不懂
作者: 964574562    時間: 2018-11-1 21:19
很給力
作者: lazyone    時間: 2018-11-4 11:24
新手看不懂啊=-=
作者: QBB11205    時間: 2018-11-7 12:23
感謝分享,學習了
作者: shangshukai    時間: 2018-11-7 22:38
帖子很好,詳細正好用到
作者: kisen    時間: 2018-11-11 01:39
學習了非常感謝!
作者: 32535604    時間: 2018-11-11 16:04
感謝樓主分享,謝謝
作者: red178    時間: 2018-11-18 19:28
完全看不懂呀
作者: 1943001098    時間: 2018-11-29 09:48
新手  這個資料正好
作者: dqm123    時間: 2018-12-11 22:27
學習到了,謝謝大佬
作者: 2019keil    時間: 2019-1-23 09:59

學習到了,謝謝大佬
作者: chenhejia    時間: 2019-4-23 10:16
看不懂,哈哈,感覺資料不錯
作者: bubulu    時間: 2019-4-24 08:34
謝謝樓主~
作者: f2717851    時間: 2019-4-24 09:35
帖子很好,詳細正好用到
作者: 大白于小丸子    時間: 2019-4-28 10:44
看不懂
作者: 高斌彬    時間: 2019-5-6 14:50
感謝大佬,學習了
作者: hfsdage    時間: 2019-10-15 15:35
感謝大佬,學習了
作者: 0394hkk    時間: 2019-11-23 22:13
不錯,要看了
作者: yangfeng2068    時間: 2020-2-21 20:08
謝謝分享,學習學習
作者: getnetdisc    時間: 2020-3-7 23:31
感謝干貨分享!
作者: tianqi911    時間: 2020-3-11 10:33
看來搜索還是有用處的。贊。
作者: aide51    時間: 2020-3-19 19:50
這是篇好的教程
作者: 小分子    時間: 2020-7-2 10:07
心細的男孩子。漂亮給力。
作者: fyljx888    時間: 2020-11-19 11:58
介紹的很詳細,謝謝了
作者: y434776771    時間: 2020-12-4 09:54
9呢 沒第9呢
作者: szqinyi    時間: 2021-10-25 08:10
講的非常詳細,感謝。正好要用到這個芯片。
作者: righthe    時間: 2021-11-4 09:58
好老師,細致又毫無保留。技術領域需要這樣的人!
作者: make_huang    時間: 2021-12-5 21:48
好老師講的非常詳細,感謝分享
作者: hegangyanyan    時間: 2022-2-21 10:02

好老師講的非常詳細,感謝分享
作者: hellohaitong    時間: 2022-7-30 15:49
正好需要這樣的資料
作者: wyl138    時間: 2022-10-31 19:11
用心的人,樂意分享的人值得大家尊重!
作者: jeffphoon    時間: 2023-7-12 12:13
謝謝分享!剛好要用到。




歡迎光臨 (http://www.izizhuan.cn/bbs/) Powered by Discuz! X3.1
天海翼一区二区三区免费| 狠狠做深爱婷婷综合一区| 欧美一级黄色带| 成人在线手机视频| 在线看视频不卡| 8x拔播拔播x8国产精品| 色94色欧美sute亚洲线路一久| 老司机免费视频一区二区| 日本一区二区乱| 国产精品一区二区婷婷| 精品国内一区二区三区免费视频 | 成人免费网站在线看| 欧美一区二区网站| 26uuu另类欧美亚洲曰本| 亚洲最新色图| 成人精品在线| 午夜在线视频| www浪潮av99com| 神马久久久久久久久久| 四虎永久免费地址| 国产aⅴ爽av久久久久| 亚洲成人自拍| 国产精品欧美激情在线播放| 日韩av网址在线| 亚洲成人免费视频| 成人动漫中文字幕| 亚洲影院一区| 欧美日韩综合久久| 亚洲福利在线观看视频| 精品国产无码在线| 国产精品国产亚洲伊人久久| 亚洲天堂av在线播放| 色综合网站在线| 日本一区二区三区免费乱视频 | 亚洲第一香蕉视频| 中文在线观看免费网站| 国产二级一片内射视频播放| 免费在线a视频| 日韩精品久久久| 91夜夜揉人人捏人人添红杏| 久久久久久91香蕉国产| 日韩av影片在线观看| 欧美中文字幕一二三区视频| 亚洲情趣在线观看| 久久免费视频色| 国产一区在线观看麻豆| 久久精品30| 中文字幕一区二区三区欧美日韩 | 青青在线免费观看| 日韩中文不卡| 国产精品推荐精品| 国产在线视频欧美| 日韩av大片免费看| 欧美国产精品va在线观看| 亚洲欧美一区二区三区在线| 日韩一区二区三区三四区视频在线观看| 亚洲欧美日韩国产手机在线| 国产色产综合产在线视频| 国产揄拍国内精品对白| 日本亚洲视频在线| 噜噜噜91成人网| 亚洲激情自拍| 合欧美一区二区三区| 欧美r级电影| 亚洲老女人视频免费| 久久久久97| 超碰97久久| 国产视频一区二区在线播放| 成人在线中文| 国产69精品久久| 成人四虎影院| 只有精品亚洲| 日本少妇精品亚洲第一区| 国产午夜在线观看| 在线免费国产视频| 色av男人的天堂免费在线| 黑料吃瓜在线观看| 在线观看黄色小视频| 91天堂在线| 黄页在线观看视频| 最新中文在线视频| 伪装者在线观看完整版免费| 极品白浆推特女神在线观看| 国模精品一区二区| 免费a级人成a大片在线观看| av在线影院| 男人添女人下部高潮视频在线观看 | 日韩视频不卡中文| 国内久久视频| 欧美国产美女| 中国成人一区| 午夜亚洲激情| 国产在线不卡视频| 不卡欧美aaaaa| 久久久精品一品道一区| 国产精品九色蝌蚪自拍| 亚洲精品一二三四区| 亚洲国产日韩a在线播放| 日韩欧美在线免费| 欧美一区二区在线不卡| 精品无人国产偷自产在线| 伊人青青综合网站| 久久久久久久一区二区| 国产精品xxx视频| 超碰97网站| 西游记1978| 欧美综合在线播放| 国产性生活一级片| 337人体粉嫩噜噜噜| 精品亚洲永久免费| 中文字幕欧美在线观看| 日韩一级中文字幕| 制服师生第一页| 老司机很黄的视频免费| 国产高清在线| 手机在线观看av| 538任你躁精品视频网免费| 日韩国产欧美一区二区| 午夜亚洲影视| 91色.com| 色综合视频一区二区三区高清| 欧美一区二区三区白人| 最好看的2019年中文视频| 97在线免费观看| 国产视频一区二区三区四区| 国产成人免费高清视频| 中文字幕在线综合| 懂色av蜜桃av| 一级黄色片免费| 四虎成人精品| 午夜影院观看视频免费| 一级毛片视频在线| 欧美在线一级| 91精品综合| 国产成人精品免费在线| 亚洲超碰精品一区二区| 日韩成人性视频| 欧美一级bbbbb性bbbb喷潮片| 国产亚洲情侣一区二区无| 日本在线xxx| 少妇真人直播免费视频| 羞羞色院91蜜桃| 国产情侣高潮对白| 日韩在线免费看| 无人区在线高清完整免费版 一区二 | 国产精品入口麻豆电影| 永久www成人看片| 2021天堂中文幕一二区在线观| 99久久免费精品国产72精品九九| 欧美天堂亚洲电影院在线观看| 在线最新版中文在线| 你懂的在线观看一区二区| 翔田千里一区二区| 国产精品久99| 日韩精品中文字幕在线| 国产一区二区色| 性欧美大战久久久久久久| 中文字幕免费视频| 午夜精品久久久久久久99老熟妇| 成看片vvv222| 欧美人与牲禽动交com| 久久亚洲道色| 精品亚洲国产成人av制服丝袜| 亚洲高清不卡在线观看| 中文字幕欧美视频在线| 国产嫩草一区二区三区在线观看| 亚洲第一狼人区| 日本少妇激情舌吻| 国产性色视频| 国产原创视频在线观看| 国产一区二区精品久| 国产精品99久久久久久久女警 | 91久久精品视频| 黄色高清无遮挡| 久久久久久免费观看| 国产农村一级特黄α**毛片| 乱人伦中文视频在线| 红桃成人av在线播放| 不卡的看片网站| 日韩一区二区三区视频| 成人黄色片网站| 国产极品美女高潮无套久久久| 久久精品免费av| 嫩草影院视频| 欧美在线极品| 亚洲综合另类| 欧美性猛交xxx| 国产精欧美一区二区三区| 人妻无码久久一区二区三区免费| www.99re7| 91国在线产| 国产极品人妖在线观看| 欧美精品偷拍| 夜夜夜精品看看| 国内精品久久影院| 99999精品视频| 看黄色一级大片| 亚色视频在线播放| 久久成人福利| 久久久久综合网| 中文字幕av一区| 老司机午夜网站| 国产亚洲第一页| xxxxxwwww免费视频| 四虎国产精品永久在线国在线| 国产一区二区三区不卡在线观看 | 一本一本a久久| 美国黄色小视频| 黄色xxxx| 日本免费一区二区三区视频| 成人av中文字幕| 在线观看日韩欧美| 97超碰国产精品| 国产成人无码专区| 色播色播色播色播色播在线| 国产二区精品| 欧美日韩亚洲精品内裤| 成人做爽爽免费视频| 男男一级淫片免费播放| 欧美黑人巨大xxxx猛交| 日韩国产激情| fc2成人免费人成在线观看播放| 亚洲欧美资源在线| 日本wwwcom| 亚洲特级黄色片| 国产乱子伦三级在线播放| 午夜日韩福利| 欧美日精品一区视频| 国产在线视频欧美一区二区三区| 国产在线免费av| 成人免费淫片在线费观看| 亚洲毛片免费看| 亚洲成av人影院| 成人午夜在线观看| 国产精品18在线| www.777色| 国产一卡不卡| 欧美亚洲自拍偷拍| 亚州欧美一区三区三区在线| √资源天堂中文在线| av在线电影观看| 六月丁香婷婷久久| 永久免费毛片在线播放不卡| 成人精品视频一区二区| 男女交配网站| 只有精品亚洲| 一区二区三区在线视频免费观看| 91精品视频播放| 国产免费无码一区二区视频| 午夜亚洲成人| 亚洲中字在线| 在线观看国产精品91| 日韩一级片播放| 欧美极度另类videos高清| 成人全视频在线观看在线播放高清 | 青青操在线播放| 免费在线看污| 午夜在线a亚洲v天堂网2018| 亚洲经典中文字幕| 天天夜碰日日摸日日澡性色av| 激情综合丝袜美女一区二区| 欧美黄色网络| 亚洲精品乱码久久久久久久久| 国产精品自拍首页| 中文字幕第15页| 福利在线视频网站| av影院午夜一区| 国产精品91在线观看| 在线观看亚洲网站| www.在线播放| 高清不卡一二三区| 57pao成人永久免费视频| 午夜av中文字幕| av电影免费在线| 伊人精品在线| 国产亚洲欧洲高清一区| 精品国产乱码久久久久久1区二区| 在线观看黄网站免费继续| 成人激情诱惑| 欧美三级韩国三级日本三斤| 美脚丝袜脚交一区二区| 欧美日韩一区二区三区视视频| 竹菊久久久久久久| 91精品国产欧美一区二区成人| 欧美精品99久久| 日本xxxwww免费视频| 中文字幕乱码亚洲无线精品一区 | 中文字幕在线视频不卡| 日韩高清不卡在线| 97av在线视频| 欧美日韩国产精品综合| 免费男女羞羞的视频网站在线观看| 国产亚洲一区字幕| 精品国产免费人成电影在线观...| 国产精品高潮呻吟AV无码| 欧美高清影院| 91搞黄在线观看| 欧美老熟妇喷水| 成人亚洲精品777777ww| 欧美国产专区| 久久综合色影院| 99热这里只有精品4| 91cn在线观看| 一区二区三区在线播| 日本丰满少妇黄大片在线观看| 日韩8x8x| 你懂的国产精品| 欧美大秀在线观看| 久久这里只有精品国产| 亚洲精品永久免费视频| 天天av天天翘天天综合网色鬼国产| 免费拍拍拍网站| 色综合97天天综合网| 国产麻豆精品在线观看| 91视频婷婷| 懂色av一区二区三区四区| 国产欧美日韩在线一区二区| 伊人久久精品视频| 日韩激情综合网| 久热在线观看视频| 在线观看免费一区| 日日干日日操日日射| 国产最新视频在线| 玉足女爽爽91| 97在线播放视频| 天堂在线视频| 国产精品久久久久7777按摩| 国产制服91一区二区三区制服| 免费看成年人视频| 国产伦精品一区二区三区在线观看| 超碰97在线资源| 黄色片视频免费| 奇米777国产一区国产二区| 亚洲一区999| 高h视频免费观看| 先锋影音一区二区| 亚洲精品小视频在线观看| 国产成人自拍网站| 日韩高清一区| 中文字幕日韩在线视频| 成人午夜视频精品一区| 欧美电影在线观看完整版| 欧美成人精品激情在线观看| 羞羞色院91蜜桃| 五月天久久久| 国产精品普通话| 四虎免费视频| 精品在线播放免费| 污视频在线免费观看一区二区三区| 毛片网站免费哦| 久久美女艺术照精彩视频福利播放| 亚洲啊啊啊啊啊| 天堂在线一二区| 日韩欧美福利视频| 中文字幕一区二区久久人妻网站 | 黄色一级视频在线播放| 深夜福利视频一区| 欧美日韩另类在线| 瑟瑟视频在线观看| 日本免费精品| 2020久久国产精品| 中文字幕人成高视频| 国产成人综合亚洲网站| 97超碰国产精品| 免费av不卡| 精品国产精品一区二区夜夜嗨| 国产亚洲欧美久久久久| h视频免费网站| 99久久国产综合精品色伊| 人妻av中文系列| 香港伦理在线| 精品日本一线二线三线不卡 | 奇米影视888狠狠狠777不卡| 欧美性xxxx在线播放| 免费成人深夜蜜桃视频| 在线看成人短视频| 成人久久精品视频| 成年女人毛片| 亚洲第一精品在线| 色欲狠狠躁天天躁无码中文字幕| 爱高潮www亚洲精品| 国产经典一区二区| 免费在线观看a| 亚洲色图一区二区三区| 亚洲第一香蕉网| 中文字幕亚洲影视| 国产伦精品一区二区三区免费视频 | 欧美一区二区三区爽爽爽| japanese国产精品| 国产精品播放| 最近中文字幕mv免费高清在线| 欧美性受xxxx黑人xyx性爽| 欧美日韩激情在线观看| 911久久香蕉国产线看观看| 久久99精品久久久久久久青青日本| 成人嫩草影院免费观看| 午夜精品成人在线视频| 国产欧美一区二区三区在线观看视频| 精品国产午夜肉伦伦影院| 国产精品永久免费观看|