久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 12212|回復: 14
打印 上一主題 下一主題
收起左側

小白菜的EEPROM學習之路

  [復制鏈接]
跳轉到指定樓層
樓主
ID:70650 發表于 2014-12-20 18:49 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
零:接上回http://www.zg4o1577.cn/bbs/dpj-29235-1.html
上回書說到了標準IIC的編寫,函數參數是指針和字節數,并非是以IIC地址和寄存器地址作參數,何故?小白菜考慮著,要想真正的適應大部分IIC器件的IIC操作而不必寫兩個功能相同的函數,用指針和字節數作參數是最好的選擇。大蝦們可能覺得這是為了統一而統一,這點必須承認。在參數傳遞效率上,確實比直接傳遞數據要低,但是小白菜接觸到的IIC器件,沒有一個是需要時時寫入的(這里的時時是指MCU空閑下來就讀取或寫入IIC器件數據)。用的最多的是EEPROM、還有xxx7290(鍵盤數碼管掃描芯片)、鐵電存儲器,測溫芯片。這些器件沒有一個是需要實時操作的,也就是說小白菜接觸的IIC器件對實時性要求不高。于是,小白菜可以忽略參數傳遞效率的問題。當然“為了統一而統一”這個目的是去不掉的。
一:為了那“可愛”的目的。
還是2011年,小白菜空閑時,覺得以前用的AT24Cxx系列EEPROM的驅動不能相互兼容,你用24C02和用24C64,就得換驅動,從工程中去掉原來,然后添加上新的,相當的麻煩。于是小白菜便想,都是同一系列的產器,為什么不能用同一個驅動?
于是,小白菜得到了他的目的:
1編寫一個能適應AT24Cxx全系列的驅動函數,對外只有兩個函數,寫EEPROM函數和讀EEPROM函數;
2移植時(包括更換不同容量的芯片)只需要改變很少的宏定義選項就能完成。
二:發現共性(操作過程的比較與抽象)
1為了實現這兩個目的,小白菜開始看手冊,并寫記錄下AT24Cxx系列EEPROM的一些參數,見表1和表2。




表1:AT24Cxx比較
型號
容量(字節)
最大級聯數
頁字節數
地址字節數
寫入時間
AT24C01
128 = 0x0080
8
8
2

  
5ms
  
(最大)
AT24C02
256 = 0x0100
8
8
2
AT24C04
512 = 0x0200
4
16
2
AT24C08
1024 = 0x0400
2
16
2
AT24C16
2048 = 0x0800
1
16
2
AT24C32
4096 = 0x1000
8
32
3
AT24C64
8192 = 0x2000
8
32
3
AT24C128
16384 = 0x4000
8
64
3
AT24C256
32768 = 0x8000
8
64
3


表2:AT24Cxx的IIC操作地址比較(二進制)
  
A2、A1、A0指的是芯片引腳,a14—a0指的是字節地址
型號
1個字節
  
MSB----LSB
2個字節
  
MSB----LSB
3字節
  
MSB----LSB
AT24C01
1     0     1    0
  
A2   A1   A0    R/W
0   a6   a5   a4
  
a3  a2   a1   a0
不發送
AT24C02
1     0     1    0
  
A2   A1   A0    R/W
a7  a6   a5   a4
  
a3  a2   a1   a0
不發送
AT24C04
1     0     1    0
  
A2   A1   a8   R/W
a7  a6   a5   a4
  
a3  a2   a1   a0
不發送
AT24C08
1     0     1    0
  
A2   a9    a8    R/W
a7  a6   a5   a4
  
a3  a2   a1   a0
不發送
AT24C16
1     0     1    0
  
a10  a9    a8    R/W
a7  a6   a5   a4
  
a3  a2   a1   a0
不發送
AT24C32
1     0     1    0
  
A2   A1   A0    R/W
0    0    0    0
  
a11  a10   a9   a8
a7  a6   a5   a4
  
a3  a2   a1   a0
AT24C64
1     0     1    0
  
A2   A1   A0    R/W
0    0     0     a12
  
a11  a10   a9   a8
a7  a6   a5   a4
  
a3  a2   a1   a0
AT24C128
1     0     1    0
  
A2   A1   A0    R/W
0    0    a13    a12
  
a11  a10   a9   a8
a7  a6   a5   a4
  
a3  a2   a1   a0
AT24C256
1     0     1    0
  
A2   A1   A0    R/W
0    a14   a13   a12
  
a11  a10   a9   a8
a7  a6   a5   a4
  
a3  a2   a1   a0
由表1和表2,小白菜開始想,不同容量的需要進行地址處理和頁處理。小白菜還設想,在應用中,不大可能不同容量的EEPROM一起使用;有可能訪問的數量大于芯片容量,所以要有溢出檢測……小白菜想了很多,并整理了一個大體的思路。
讀寫函數 → 先要進行參數檢查 → 進行溢出檢測 → 地址處理 → 讀寫數據( →  寫數據時寫入等待) → 返回操作狀態。
三 代碼編寫
小白菜用上面的流程,開始了代碼的編寫。寫代碼時,地址處理部分需要使用條件編譯來實現不同芯片的操作;寫入等待函數需要有超時機制……寫啊寫,寫啊寫,小白菜終于寫出來了。列位看官,請繼續向下看。
四 使用說明
4.1 移植修改  移植修改在H文件中的“移植修改”部分。這里有5處需要修改。
//----------------------------------------------------------------------------//
// 編號:1
// 名稱:
// 功能:單片機寄存器頭文件,例如reg51.h
//----------------------------------------------------------------------------//
#include "ATT703x.H"
4.1.1  請您把使用的單片機的頭文件包含進來。大蝦們用過MCU 多了,知道不同的MCU,其寄存器定義是不一樣滴,不是所有的51 單片機都用Reg51.H 或Reg52.H 頭文件。
//--------------------------------------------------------------------------//
// 編號 :2
// 名稱 :AT24Cxx
// 功能 :選擇您所使用的EEPROM芯片型號。只能啟用一條宏。
//      :不支持一條總線上掛不同的EEPROM,支持同類型的多個EEPROM掛在總線上。
//--------------------------------------------------------------------------//
//  #defineAT24C01         // 使用AT24C01,則啟用本句并屏蔽其它語句。
//  #defineAT24C02         // 使用AT24C02,則啟用本句并屏蔽其它語句。
    #defineAT24C04         // 使用AT24C04,則啟用本句并屏蔽其它語句。
//  #defineAT24C08         // 使用AT24C08,則啟用本句并屏蔽其它語句。
//  #defineAT24C16         // 使用AT24C16,則啟用本句并屏蔽其它語句。
//  #defineAT24C32         // 使用AT24C32,則啟用本句并屏蔽其它語句。
//  #defineAT24C64         // 使用AT24C64,則啟用本句并屏蔽其它語句。
//  #defineAT24C128        //使用AT24C128,則啟用本句并屏蔽其它語句。
//  #defineAT24C256        //使用AT24C256,則啟用本句并屏蔽其它語句。
4.1.2 這里啟用您所用的芯片。不支持不同容量的芯片掛接在同一總線上。
//--------------------------------------------------------------------------//
// 編號 :3
// 名稱 :AT24CXX_WP_ENABLE
// 功能 :啟用AT24Cxx的寫保護功能。為1時啟用寫保護。為0時不使用寫保護。
//      :當WP引腳接地時,請禁用寫保護功能。否則會浪費系統資源。
//--------------------------------------------------------------------------//
#define  AT24CXX_WP_ENABLE   (0)
//--------------------------------------------------------------------------//
// 編號 :4
// 名稱 :AT24Cxx_WP
// 功能 :寫保護引腳所用的口線。啟用寫保護時,才需要設置本參數
//--------------------------------------------------------------------------//
#if (1 == AT24CXX_WP_ENABLE)
    sbit   AT24Cxx_WP = P1^2;
#endif
4.1.3 這里是關于WP的操作,您可能并不使用寫保護并把WP接地。如果AT24CXX_WP_ENABLE為0,即不使用寫保護時,寫入允許和禁止函數不編譯。如果您為了減少改動,也可以把這兩個函數體進行條件編譯,而只留下一個“空函數”。
//--------------------------------------------------------------------------//
// 編號 :5
// 名稱 :AT24Cxx_Delay_1ms()
// 功能 :精確的1毫秒延時函數。這里請使用您系統中的微秒延時函數。
//      :例如,您的延時函數是Delay_1us(),那么您可以使用下句
//      :#defineMK_Delay_1us()  Delay_1us()
//      :來實現延時。
//--------------------------------------------------------------------------//
#include "Delay.H"      // 您系統所用延時函數聲明所在的頭文件。
#define AT24Cxx_Delay_1ms()   Delay_MS(1)
4.1.4 這里的軟件1ms延時函數用于寫入等待。延時必須在1ms左右。
4.2 函數說明  
4.2.1 從AT24Cxx中讀取數據函數
//----------------------------------------------------------------------------//
//                    從AT24Cxx中讀取多字節數據函數(對外接口)
//函數名稱:AT24Cxx_Read_Str
//函數功能:從Addr指定的地址開始讀取AT24Cxx,一共讀取Num個字節,數據讀出后存
//         放在PDat數組中。
//入口參數:
//         A2A1A0:對應芯片A2 A1 A0引腳,低3位有效(高位被忽略).
//         Addr:對24Cxx進行讀操作的起始地址。
//        *PDat:數據讀取后存放的首地址
//         Num :要讀取的字節數
//出口參數:0 = 成功,1 = 失敗。
//重要說明:1.讀取的第一個字節放在PDat[0]中,第二個放在PDat[1]中,以此類推。
//       :2.若EEPROM剩余空間不足,函數報錯。
//----------------------------------------------------------------------------//
extern uint8 AT24Cxx_Read_Str(uint8 A2A1A0, uint16 Addr, uint8*PDat, uint16 Num)
第一個參數A2A1A0的低三位分別對應A2、A1、A0,并且不能對該參數進行檢查,所以一定要設置正確。
應用示例:
    芯片的A2、A1、A0接地,并且從0x10地址開始讀取,讀取的字節數50,數據讀取后存放在unsigned char Buf[100]數組中。
解析:由于A2、A1、A0接地,所以第一個參數為0,函數調用是
AT24Cxx_Read_Str(0, 0x10,  Buf,  50)
Buf中存放的EEPROM中(0x10 + i)單元的內容,
4.2.2 向AT24Cxx中寫入數據函數
//-------------------------------------------------------------------------------//
//                    向AT24Cxx寫入多字節數據函數(對外接口)
//函數名稱:AT24Cxx_Write_Str
//函數功能:向AT24Cxx中寫入多字節。寫入的起始地址由Addr確定,數據存放的首
//         地址在PDat中存放,寫入的字節數是Num(16位無符號數)。
//入口參數:
//         A2A1A0:對應芯片A2 A1 A0引腳,低3位有效(高位被忽略).
//         Addr:對24Cxx進行寫操作的起始地址。
//        *PDat:發送的數據存放的首地址
//         Num :發送的字節數
//出口參數:0 = 成功,1 = 失敗。
//重要說明:1.先發送PDat[0],再發送PDat[1],以此類推。
//       :2.若EEPROM剩余空間不足,函數報錯。
//       :3.若啟用了寫保護功能,必須先使寫保護失效,否則無法進行寫入。
//-------------------------------------------------------------------------------//
extern uint8 AT24Cxx_Write_Str(uint8 A2A1A0, uint16 Addr, uint8*PDat, uint16 Num)
第一個參數A2A1A0的說明見4.2.1。
若啟用了寫保護功能,在調用本函數必須調用寫入允許函數,否則函數寫入出錯。
應用示例:
    芯片的A2、A1、A0接地,并且從0x10地址開始寫入,寫入的字節數50,寫入數據存放在unsigned char Buf[100]數組中。Buf寫入EEPROM中(0x10 + i)單元。
解析:A2、A1、A0接地,所以第一個參數為0,函數調用是
AT24Cxx_ Write _Str(0, 0x10,  Buf,  50)
4.2.3  AT24Cxx定義允許禁止函數
extern voidAT24Cxx_Write_Enable(void);     // 允許寫入。
extern voidAT24Cxx_Write_Disable(void);    // 禁止寫入。
這兩個函數是寫入允許和禁止函數,實際是操作WP引腳。您也可以改為宏定義,這里小白菜就不弄啦。這兩個函數受AT24CXX_WP_ENABLE的控制。AT24CXX_WP_ENABLE為1時,即打開寫保護,當寫入時,必須先調用AT24Cxx_Write_Enable()函數,以使能寫入。
這對函數應成對的調用哦(就像進入和退出臨界區函數一樣),要不然寫保護有沒有意義了。
五 最后的有用的話
這套驅動,小白菜只測試過AT24C64和AT24C04,其他并沒有測試過。所以要慎用哦。歡迎各位童鞋進行拍磚!要是有Bug,小白菜也非常希望大家能給小白菜說一聲哦~
非常感謝~
AT24Cxx.rar (194.63 KB, 下載次數: 82)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:70650 發表于 2014-12-20 18:49 | 只看該作者
主程序文件:
  1. /*
  2. ********************************************************************************
  3. *                                    
  4. *                             
  5. *
  6. *     地址:
  7. *                  (c) Copyright 2012,   All Rights Reserved
  8. *                                
  9. * 開發環境  : Keil3
  10. * 文件名    : BusIIC.C
  11. * 程序員    : 3htech
  12. * 開發時間  : 2011
  13. * 描述      : IIC總線抽象。使用51單片機IO口線來模擬IIC總線。
  14. * 生存條件  : 類型重定義,微秒級精確延時函數Delay1US(),Delay2US(),Delay5US();
  15. *-------------------------------------------------------------------------------
  16. * 修 改    :
  17. * 日 期    :
  18. * 描  述    :
  19. *-------------------------------------------------------------------------------
  20. ********************************************************************************
  21. */
  22. //------------------------------    程序開關    ------------------------------//
  23. //----------------------------------------------------------------------------//
  24. // 開關名 :IIC_IO_ENABLE
  25. //  功能  :使能H文件中的SDA和SCL信號線。使其僅在本文件中可見。
  26. //----------------------------------------------------------------------------//
  27. #define IIC_IO_ENABLE



  28. //------------------------------ 系統頭文件包含 ------------------------------//
  29. // 無

  30. //----------------------------- 自定義頭文件包含 -----------------------------//
  31. #include"BusIIC.H"



  32. //------------------------------  全局變量定義  ------------------------------//

  33. //----------------------------------------------------------------------------//
  34. //變量名稱:IICBuf
  35. //變量功能:僅用于IIC_MCU_Send_SDA_Byte()和IIC_MCU_Rcv_SDA_Byte()函數中。
  36. //        :用來輔助IIC發送和接收過程。(僅限本文件使用)。IICBuf可位尋址。
  37. //作用域  :僅限本文件、對外完全不可見
  38. //重要說明:無
  39. //----------------------------------------------------------------------------//
  40. static uint8 bdata IICBuf;

  41. sbit IICBufBit7 = IICBuf^7;    // IICBuf的第7位,用于IIC發送
  42. sbit IICBufBit0 = IICBuf^0;    // IICBuf的第0位,用于IIC接收



  43. //-------------------------------   宏定義   ---------------------------------//
  44. //----------------------------------------------------------------------------//
  45. //宏名    :IIC_ACK、IIC_N_ACK
  46. //功能    :IIC應答信號類型。
  47. //重要說明:僅用于IIC_MCU_Rcv_ACK()和IICMCUSendACK()函數的相關操作。
  48. //----------------------------------------------------------------------------//
  49. #define IIC_ACK    0    //應答信號   
  50. #define IIC_N_ACK  1    //非應答信號或無應答



  51. ////////////////////////////////////////////////////////////////////////////////
  52. //                            本文件專用函數定義                              //
  53. ////////////////////////////////////////////////////////////////////////////////

  54. ////////////////////////////////////////////////////////////////////////////////
  55. //                            本文件專用函數定義                              //
  56. ////////////////////////////////////////////////////////////////////////////////


  57. //----------------------------------------------------------------------------//
  58. //                             微秒級延時函數函數(僅限本文件使用)
  59. //函數名稱:IIC_Delay_nUS()
  60. //函數功能:啟動IIC總線,即發送IIC起始條件。
  61. //入口參數:無
  62. //出口參數:無
  63. //重要說明:無
  64. //----------------------------------------------------------------------------//
  65. #define IIC_Delay_2US()   IIC_Delay_1US();IIC_Delay_1US()
  66. #define IIC_Delay_5US()   IIC_Delay_2US();IIC_Delay_2US();IIC_Delay_1US()


  67. //----------------------------------------------------------------------------//
  68. //                             IIC總線起動函數(僅限本文件使用)
  69. //函數名稱:IIC_Start  
  70. //函數功能:啟動IIC總線,即發送IIC起始條件。
  71. //入口參數:無
  72. //出口參數:無
  73. //重要說明:無
  74. //----------------------------------------------------------------------------//
  75. static void IIC_Start(void)
  76. {
  77.     SDA = 1;            // 發送起始條件的數據信號
  78.     IIC_Delay_1US();    // 延時1us

  79.     SCL = 1;            // 起始條件建立時間大于4.7us
  80.     IIC_Delay_5US();    // 延時5us
  81.       
  82.     SDA = 0;            // 發送起始信號,起始條件鎖定時間大于4.7us
  83.     IIC_Delay_5US();    // 延時5us

  84.     SCL = 0;            // 鉗住I2C總線,準備發送或接收數據
  85.     IIC_Delay_5US();
  86. }
  87. //-------------------------------------------------------------------------------//
  88. //                      IIC總線結束函數(僅限本文件使用)
  89. //函數名稱:IIC_Stop  
  90. //函數功能:結束I2C總線,即發送I2C結束條件。
  91. //入口參數:無
  92. //出口參數:無
  93. //重要說明:無
  94. //-------------------------------------------------------------------------------//
  95. static void IIC_Stop(void)
  96. {
  97.     SDA = 0;            // 發送結束條件的數據信號
  98.     IIC_Delay_1US();    // 延時1us

  99.     SCL = 1;            // 結束條件建立時間大于4us
  100.     IIC_Delay_5US();    // 延時5us

  101.     SDA = 1;            // 發送I2C總線結束信號,時間大于4us
  102.     IIC_Delay_5US();    // 延時5us
  103. }

  104. //-------------------------------------------------------------------------------//
  105. //                     MCU發送一字節數據到SDA函數(僅限本文件使用)
  106. //函數名稱:IIC_MCU_Send_SDA_Byte
  107. //函數功能:單片機發送1字節數據到SDA上。   
  108. //入口參數:DataValue,要發送的一字節數據
  109. //出口參數:無
  110. //重要說明:本函數與ACK信號無任何關聯。
  111. //          使用本函數后應立即調用MCU接收ACK信號函數IICMCURcvACK()以判斷傳輸是否成功。
  112. //-------------------------------------------------------------------------------//
  113. static void IIC_MCU_Send_SDA_Byte(uint8 DataValue)
  114. {
  115.     uint8 i = 0;

  116.     // 把要發送的數據送入IIC數據緩沖區IICBuf中。(該變量定義在文件開頭)
  117.     IICBuf = DataValue;

  118.     // 開始發送數據,數據從高位開始發送
  119.     for(i = 0; i < 8; i++)
  120.     {
  121.         // 時鐘線拉低,總時間大于4.7us
  122.         SCL = 0;

  123.         // 高位數據放到總線上
  124.         SDA = IICBufBit7;

  125.         // 時鐘低電平時間大于4.7us  
  126.         IIC_Delay_5US();

  127.         // 數據保持時間大于4us。(即時鐘線高電平寬度大于4us)
  128.         SCL = 1;   
  129.         IIC_Delay_5US();

  130.         // IICBuf左移一位,為發送下一位做準備
  131.         IICBuf <<= 1;
  132.     }

  133.     // 鉗住I2C總線,準備接收ACK信號
  134.     SCL = 0;
  135.     IIC_Delay_5US();
  136. }


  137. //-------------------------------------------------------------------------------//
  138. //                 MCU從SDA上接收一字節數據函數(僅限本文件使用)
  139. //函數名稱:IIC_MCU_Rcv_SDA_Byte
  140. //函數功能:單片機從SDA線上接收1字節數據。
  141. //入口參數:無
  142. //出口參數:接收到的一字節數據。
  143. //重要說明:本函數與ACK信號無任何關聯。
  144. //          使用本函數后應立即調用MCU發送ACK信號函數IICMCUSendACK()來進行應答或非應答。
  145. //-------------------------------------------------------------------------------//
  146. static uint8 IIC_MCU_Rcv_SDA_Byte(void)
  147. {
  148.     uint8  i = 0;

  149.     // 此時IICBuf用作接收緩沖器,所以先清0
  150.     IICBuf = 0;

  151.     // 置數據線為輸入方式
  152.     SDA = 1;      


  153.     // 開始接收數據
  154.     for(i = 0; i < 8; i++)
  155.     {
  156.         // 時鐘為低,使器件輸出數據到SDA線上           
  157.         SCL = 0;
  158.         IIC_Delay_5US();    // 時鐘低電平周期大于4.7us

  159.         // 時鐘為高,使數據線上數據有效。
  160.         SCL = 1;
  161.         IIC_Delay_5US();    // 時鐘高電平周期大于4.7us

  162.         // 接收數據         
  163.         IICBuf <<= 1;       // 先左移一位
  164.         IICBufBit0 = SDA;   // 讀取SDA并放入IICBuf的最低位中
  165.     }

  166.     // 鉗住I2C總線,準備發送應答或非應答信號
  167.     SCL = 0;
  168.     IIC_Delay_5US();

  169.     // 返回接收到的數據
  170.     return(IICBuf);
  171. }


  172. //-------------------------------------------------------------------------------//
  173. //                     MCU發送ACK信號函數(僅限本文件使用)
  174. //函數名稱:IIC_MCU_Send_ACK
  175. //函數功能:主控器進行應答信號(可以是應答或非應答信號)
  176. //入口參數:應答信號類型,僅以宏 IIC_ACK表示ACK應答信號,IIC_N_ACK表示非應答信號。
  177. //出口參數:無
  178. //重要說明:在調用完IIC_MCU_Rcv_SDA_Byte()函數后,應立即調用本函數進行應答或非應應答。
  179. //        :這里不檢查參數的合法性。為保證參數不出錯,請您一定只使用宏
  180. //        :IIC_ACK 和 IIC_N_ACK 來做參數。
  181. //-------------------------------------------------------------------------------//
  182. static void IIC_MCU_Send_ACK(bit ACK_Tpye)
  183. {
  184.     // 在SDA建立數據之前,SCL是低電平,因為本函數只能跟在IICMCURcvSDAByte()函數之后。
  185.     if(IIC_N_ACK == ACK_Tpye)
  186.     {
  187.         SDA = 1;    // 發出非應答信號
  188.     }
  189.     else
  190.     {
  191.         SDA = 0;    // 發出應答信號
  192.     }

  193.     // 時鐘低電平時間大于4.7us
  194.     IIC_Delay_5US();

  195.     // 時鐘高電平周期大于4us
  196.     SCL=1;
  197.     IIC_Delay_5US();

  198.     // 清時鐘線,鉗住IIC總線以便繼續接收或停止
  199.     SCL=0;   
  200.     IIC_Delay_2US();   
  201. }


  202. //-------------------------------------------------------------------------------//
  203. //                      MCU接收ACK信號函數(僅限本文件使用)
  204. //函數名稱:IIC_MCU_Rcv_ACK  
  205. //函數功能:MCU接收IIC從器件發送的ACK信號.
  206. //入口參數:無
  207. //出口參數:IIC_N_ACK = 表示未收到ACK應答信號,說明傳輸未成功。
  208. //          IIC_ACK   = 表示收到ACK應答信號,說明傳輸成功。
  209. //重要說明:此函數應在使用完字節發送函數IIC_MCU_Send_SDA_Byte后立即使用以判斷傳輸是否成功。
  210. //-------------------------------------------------------------------------------//
  211. static uint8 IIC_MCU_Rcv_ACK(void)
  212. {
  213.     bit ACK_Type = 0;  // 作用:暫時存儲ACK信號

  214.     // 釋放數據線,準備接收應答
  215.     SDA = 1;

  216.     IIC_Delay_5US();

  217.     // 應答信號寬度大于4us
  218.     SCL = 1;   
  219.     IIC_Delay_5US();      

  220.     // 檢查是否收到了應答信號
  221.     if(1 == SDA)      
  222.     {
  223.         ACK_Type = IIC_N_ACK;   // 未收到應答信號,ACKtmp賦值為非應答標志IIC_N_ACK
  224.     }
  225.     else                 
  226.     {
  227.         ACK_Type = IIC_ACK;     // 收到應答信號,ACKtmp賦值為應答標志IIC_ACK
  228.     }

  229.     // 鉗住I2C總線,準備發送新數據或停止發送
  230.     SCL = 0;
  231.     IIC_Delay_5US();

  232.     // 返回接收到的ACK信號類型。
  233.     return ACK_Type;
  234. }


  235. ////////////////////////////////////////////////////////////////////////////////
  236. //                          本文件專用函數定義結束                            //
  237. ////////////////////////////////////////////////////////////////////////////////







  238. ////////////////////////////////////////////////////////////////////////////////
  239. //                             對外服務函數定義                               //
  240. ////////////////////////////////////////////////////////////////////////////////



  241. //----------------------------------------------------------------------------//
  242. //                    MCU向IIC器件發送多字節數據函數(對外提供服務)
  243. //函數名稱:IIC_MCU_Send_Str
  244. //函數功能:MCU向IIC從器件發送多字節數據。本函數是寫IIC從器件的抽象函數。
  245. //入口參數:
  246. //          *PAddr:    IIC地址以及子地址。PAddr[0]中存放IIC地址,后面的存放子地址。
  247. //          AddrNum :  IIC以及子地址的字節數。不可為0.
  248. //
  249. //          *PDataAddr:第2批發送的數據的首地址。這部分是發送的數據。
  250. //          DataNum :  第2批要發送的字節數(最大為65536個字節)。為0時不發送這一部分。
  251. //出口參數:0 = 操作成功,1 = 操作出錯。
  252. //重要說明:這是一個從啟動IIC總線到發送數據再到最后結束總線為止的完整的發送過程。
  253. //          數據發送的順序是先發送PAddr[0],最后發送PAddr[AddrNum - 1],然后發送
  254. //          PDataAddr[0],最后發送PDataAddr[DataNum - 1]。
  255. //          一般地,PAddr用于發送器件IIC地址和子地址,PDataAddr用于發送數據。
  256. //          本函數對有無子地址的IIC器件都適用。
  257. //----------------------------------------------------------------------------//
  258. extern uint8 IIC_MCU_Send_Str(uint8 *PAddr, uint8 AddrNum, uint8 *PDataAddr, uint16 DataNum)
  259. {
  260.     uint8 ErrFlg;       // 0 = 傳輸正確。1 = 傳輸出錯。

  261.     // 初始化局部變量。
  262.     ErrFlg = 0;

  263.     // 參數檢查
  264.     if(0 == AddrNum)
  265.     {
  266.         ErrFlg = 1;
  267.     }

  268.     //啟動總線
  269.     if(0 == ErrFlg)
  270.     {
  271.         IIC_Start();
  272.     }

  273.     // 開始發送IIC地址(以及子地址)數據
  274.     for( ; AddrNum > 0;  AddrNum--)
  275.     {
  276.         if(1 == ErrFlg)               // 如果傳輸過程中出錯,則立即終止傳輸。
  277.         {
  278.             break;
  279.         }

  280.         IIC_MCU_Send_SDA_Byte(*PAddr);      // 發送數據

  281.         if(IIC_N_ACK == IIC_MCU_Rcv_ACK())
  282.         {
  283.             ErrFlg = 1;               // 未收到從器件的應答信號,說明傳輸出錯。
  284.         }

  285.         PAddr++;                            // 為發送下一個數據作準備
  286.     }

  287.     // 開始發送數據
  288.     for( ; DataNum > 0;  DataNum--)
  289.     {
  290.         if(1 == ErrFlg)               // 如果傳輸過程中出錯,則立即終止傳輸。
  291.         {
  292.             break;
  293.         }
  294.       
  295.         IIC_MCU_Send_SDA_Byte(*PDataAddr);  // 發送數據

  296.         if(IIC_N_ACK == IIC_MCU_Rcv_ACK())  // 未收到從器件的應答信號,說明傳輸出錯。
  297.         {
  298.             ErrFlg = 1;
  299.         }

  300.         PDataAddr++;                        // 為發送下一個數據作準備
  301.     }

  302.     // 結束總線。不論傳輸是否出錯,都要關閉總線。
  303.     IIC_Stop();

  304.     // 返回出錯信息。
  305.     return ErrFlg;
  306. }


  307. //----------------------------------------------------------------------------//
  308. //                  MCU從有子地址的IIC器件中接收多字節函數(對外接口)
  309. //函數名稱:IICMCURcvStr
  310. //函數功能:本函數用于有子地址的IIC器件的讀操作。
  311. //入口參數:
  312. //          *PAddr:    IIC地址以及子地址。PAddr[0]中存放IIC地址,后面的存放子地址。
  313. //          AddrNum :  IIC以及子地址的字節數。為0時出錯.
  314. //
  315. //        *PDataAddr:存放所接收數據的首地址
  316. //         DataNum :  要接收的字節數。合法值1-65535。為0時出錯。
  317. //
  318. //出口參數:0 = 操作成功,1 = 操作出錯。
  319. //重要說明:
  320. //有子地址的IIC器件的讀操作是:
  321. //  MCU先啟動總線,然后發送器件的IIC地址和需要操作的子地址
  322. //(這一部分就是*PAddr),之后重新啟動總線,再次發送器件的IIC地址且最低位置1以表明是讀
  323. // 操作,等待應答后便開始接收數據(這一部分是*PDataAddr),最后關閉總線。
  324. //----------------------------------------------------------------------------//
  325. extern uint8 IIC_MCU_Rcv_Str(uint8 *PAddr, uint8 AddrNum,  uint8 *PDataAddr, uint16 DataNum)
  326. {
  327.     uint8 IICAddr;     
  328.     uint8 ErrFlg;           // 0 = 傳輸正確。1 = 傳輸出錯。

  329.     // 初始化局部變量。
  330.     ErrFlg   = 0;
  331.     IICAddr  = PAddr[0];    // IIC地址放在PAddr[0]中。

  332.     // 參數檢查
  333.     if((0 == AddrNum) || (0 == DataNum))
  334.     {
  335.         ErrFlg = 1;         // 參數出錯。
  336.     }

  337.     //啟動總線
  338.     if(0 == ErrFlg)
  339.     {
  340.         IIC_Start();
  341.     }

  342.     // 開始發送IIC地址和子地址。
  343.     for(  ; AddrNum > 0; AddrNum--)
  344.     {
  345.         if(1 == ErrFlg)               // 如果傳輸過程中出錯,則立即終止傳輸。
  346.         {
  347.             break;
  348.         }

  349.         IIC_MCU_Send_SDA_Byte(*PAddr);      // 發送數據
  350.    
  351.         if(IIC_N_ACK == IIC_MCU_Rcv_ACK())  // 檢測是否收到從器件的應答信號
  352.         {
  353.             ErrFlg = 1;               // 未收到從器件的應答信號,傳輸出錯。
  354.         }

  355.         PAddr++;                            // 為發送下一個數據作準備
  356.     }

  357.     //重新啟動總線。
  358.     if(0 == ErrFlg)
  359.     {
  360.         IIC_Start();

  361.     // 開始發送IIC地址,此時bit[0]要為1以表明是要讀。
  362.         IIC_MCU_Send_SDA_Byte(IICAddr | 0x01);

  363.         if(IIC_N_ACK == IIC_MCU_Rcv_ACK())  // 檢測是否收到從器件的應答信號
  364.         {
  365.             ErrFlg = 1;               // 未收到從器件的應答信號,傳輸出錯。
  366.         }
  367.     }

  368.     // 接收數據。
  369.     if(0 == ErrFlg)
  370.     {
  371.         // MCU接收IIC器件發送前(DataNum-1個數據)的數據
  372.         for(  ;  DataNum > 1; DataNum--)
  373.         {

  374.             *PDataAddr = IIC_MCU_Rcv_SDA_Byte();// 接收數據

  375.             IIC_MCU_Send_ACK(IIC_ACK);          // 發送ACK應答信號

  376.             PDataAddr++;                        // 為接收下一個數據作準備
  377.         }

  378.         // 接收最后一字節數據
  379.         *PDataAddr = IIC_MCU_Rcv_SDA_Byte();

  380.         IIC_MCU_Send_ACK(IIC_N_ACK);            // 發送非應答信號
  381.     }

  382.     // 結束總線。不論傳輸是否出錯,都要關閉總線。
  383.     IIC_Stop();

  384.     // 返回出錯信息。
  385.     return ErrFlg;
  386. }

  387. //----------------------------------------------------------------------------//
  388. //                  MCU從IIC總線接收多字節函數(對外接口) (未測試)
  389. //函數名稱:IIC_MCU_Rcv_NoReg_Str
  390. //函數功能:本函數用于無子地址的IIC器件的讀操作。
  391. //入口參數:
  392. //         IICAddr:IIC地址。
  393. //        *PRcvDat:存放所接收數據的首地址
  394. //         RcvNum :要接收的字節數。不可為0.
  395. //出口參數:0 = 操作成功,1 = 操作出錯。
  396. //重要說明:

  397. //無子地址的IIC器件的讀操作是:
  398. //  MCU先啟動總線,然后發送器件的IIC地址且最低位置1以表明是讀操作(這一部分是IICAddr),
  399. //  等待應答后便開始接收數據(這一部分是*PRcvDat),最后關閉總線。
  400. //----------------------------------------------------------------------------//
  401. /*extern uint8 IIC_MCU_Rcv_NoReg_Str(uint8 IICAddr, uint8 *PRcvDat, uint16 RcvNum)
  402. {
  403.     uint8 ErrFlg;           // 0 = 傳輸正確。1 = 傳輸出錯。

  404.     // 初始化局部變量。
  405.     ErrFlg   = 0;

  406.     // 若需要接收的數據量為0,則直接返回。您不應該使RcvNum為0.
  407.     if(0 == RcvNum)
  408.     {
  409.         ErrFlg =  1;
  410.     }

  411.     // 啟動總線。
  412.     if(0 == ErrFlg)
  413.     {
  414.         IIC_Start();
  415.     }

  416.     // 開始IIC地址。
  417.     if(0 == ErrFlg)
  418.     {
  419.         IIC_MCU_Send_SDA_Byte(IICAddr|0x01);

  420.         if(IIC_N_ACK == IIC_MCU_Rcv_ACK())  // 檢測是否收到從器件的應答信號
  421.         {
  422.             ErrFlg = 1;                       // 未收到從器件的應答信號,說明傳輸出錯,返回IIC出錯信息。
  423.         }
  424.     }

  425.     // 接收前(RcvNum-1)個字節數據
  426.     if(0 == ErrFlg)
  427.     {
  428.         for(  ; RcvNum > 1; RcvNum--)
  429.         {
  430.             *PRcvDat = IIC_MCU_Rcv_SDA_Byte();  // 接收數據

  431.             IIC_MCU_Send_ACK(IIC_ACK);          // 發送ACK應答信號

  432.             PRcvDat++;                          // 指針加1,為接收下一個數據作準備
  433.         }

  434.         // 接收最后一字節數據
  435.         *PRcvDat = IIC_MCU_Rcv_SDA_Byte();

  436.         IIC_MCU_Send_ACK(IIC_N_ACK);    // 發送非應答信號
  437.     }

  438.     // 結束總線
  439.     IIC_Stop();           

  440.     // 返回出錯信息。
  441.     return ErrFlg;
  442. }*/
  443. ////////////////////////////////////////////////////////////////////////////////
  444. //                           對外服務函數定義結束                             //
  445. ////////////////////////////////////////////////////////////////////////////////
復制代碼
回復

使用道具 舉報

板凳
ID:70650 發表于 2014-12-20 18:51 | 只看該作者
BusIIC.H文件:
  1. /*
  2. ********************************************************************************
  3. *                                    
  4. *                             
  5. *
  6. *     地址:
  7. *                  (c) Copyright 2012,   All Rights Reserved
  8. *                                
  9. * 開發環境  : Keil3
  10. * 文件名    : BusIIC.H
  11. * 程序員    : 3htech
  12. * 開發時間  : 2011
  13. * 描述      : IIC總線抽象。使用51單片機IO口線來模擬IIC總線。
  14. * 生存條件  : 類型重定義,微秒級精確延時函數Delay1US(),Delay2US(),Delay5US();
  15. *-------------------------------------------------------------------------------
  16. * 修 改    :
  17. * 日 期    :
  18. * 描  述    :
  19. *-------------------------------------------------------------------------------
  20. ********************************************************************************
  21. */

  22. //------------------------------    文件開關    ------------------------------//
  23. // 防止文件包含時多次編本文件,與本文件結尾處的endif對應。
  24. #ifndef         _BUSIIC_H_
  25.     #define     _BUSIIC_H_
  26. //----------------------------------------------------------------------------//



  27. //------------------------------ 系統頭文件包含 ------------------------------//
  28. #include<intrins.h>            // 為了使用_nop_()函數

  29. //----------------------------- 自定義頭文件包含 -----------------------------//
  30. #include"TypeRedefine.H"



  31. ////////////////////////////////////////////////////////////////////////////////
  32. //                                移植修改(3處)                               //
  33. ////////////////////////////////////////////////////////////////////////////////
  34. //----------------------------------------------------------------------------//
  35. // 編號 :1
  36. // 名稱 :
  37. // 功能 :單片機寄存器頭文件,例如reg51.h
  38. //----------------------------------------------------------------------------//
  39. #include "ATT703x.H"

  40. //----------------------------------------------------------------------------//
  41. // 編號 :2
  42. // 名稱 :SDA, SCL
  43. // 功能 :模擬I2C數據傳送位
  44. //----------------------------------------------------------------------------//
  45. #if defined(IIC_IO_ENABLE)

  46.     sbit SDA = P0^0;    // 模擬I2C數據傳送位。
  47.     sbit SCL = P2^6;    // 模擬I2C時鐘控制位。

  48. #endif

  49. //----------------------------------------------------------------------------//
  50. // 編號 :3
  51. // 名稱 :IIC_Delay_1US()
  52. // 功能 :精確的1微秒延時函數。請根據您所用的單片機來正確設置。
  53. //      :如果您的系統中有精確的微妙級延時函數,那么您可以直接使用。
  54. //      :例如,您的延時函數是Delay_1us(),那么您可以使用下句
  55. //      :#define IIC_Delay_1us()  Delay_1us()
  56. //      :來實現延時。
  57. //----------------------------------------------------------------------------//
  58. #define IIC_Delay_500ns() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  59. #define IIC_Delay_1US()   IIC_Delay_500ns();IIC_Delay_500ns();

  60. ////////////////////////////////////////////////////////////////////////////////
  61. //                               移植修改結束                                 //
  62. ////////////////////////////////////////////////////////////////////////////////



  63. //------------------------------  全局變量聲明  ------------------------------//
  64. // NULL


  65. //-------------------------------   宏定義   ---------------------------------//




  66. ////////////////////////////////////////////////////////////////////////////////
  67. //                                 函數聲明                                   //
  68. ////////////////////////////////////////////////////////////////////////////////
  69. extern uint8 IIC_MCU_Send_Str(uint8 *PAddr, uint8 AddrNum, uint8 *PDataAddr, uint16 DataNum);

  70. extern uint8 IIC_MCU_Rcv_Str(uint8 *PAddr, uint8 AddrNum,  uint8 *PDataAddr, uint16 DataNum);


  71. //extern uint8 IIC_MCU_Rcv_NoReg_Str(uint8 IICAddr, uint8 *PRcvDat, uint16 RcvNum);



  72. ////////////////////////////////////////////////////////////////////////////////
  73. //                               函數聲明結束                                 //
  74. ////////////////////////////////////////////////////////////////////////////////

  75. //------------------------------    文件開關    ------------------------------//
  76. // 防止文件包含時多次編本文件,與本文件開頭處的 #ifndef 對應。
  77. #endif
  78. //----------------------------------------------------------------------------//




復制代碼
回復

使用道具 舉報

地板
ID:70650 發表于 2014-12-20 18:52 | 只看該作者
ChipAT24Cxx.C文件:
  1. /*
  2. ********************************************************************************
  3. *                                    
  4. *                             
  5. *
  6. *     
  7. *                  (c) Copyright 2012,   All Rights Reserved
  8. *                                
  9. * 開發環境  : Keil4
  10. * 文件名    : ChipAT24Cxx.C
  11. * 程序員    : 3htech
  12. * 開發時間  : 20110907--20110907
  13. * 描述      : EEPROM芯片AT24Cxx驅動。   其他與AT24C比完全兼容的EEPROM芯片也可使用本驅動。
  14. *           :不支持不同容量的EEPROM混用,同容量的EEPROM可以一起使用。
  15. * 生存條件  : 類型重定義,還需要一個毫秒級精確延時函數Delay_MS();
  16. *-------------------------------------------------------------------------------
  17. * 修 改    :
  18. * 日 期    :
  19. * 描  述    :
  20. *-------------------------------------------------------------------------------
  21. ********************************************************************************
  22. */
  23. //------------------------------    程序開關    ------------------------------//
  24. // 無

  25. //------------------------------ 系統頭文件包含 ------------------------------//
  26. // 無

  27. //----------------------------- 自定義頭文件包含 -----------------------------//
  28. #include"ChipAT24Cxx.H"



  29. //------------------------------  全局變量定義  ------------------------------//
  30. // NULL

  31. //-------------------------------   宏定義   ---------------------------------//
  32. //----------------------------------------------------------------------------//
  33. //宏名    :IIC_ADDR_AT24CXX
  34. //功能    :AT24Cxx的IIC地址。僅限本文件使用。
  35. //重要說明:AT24Cxx的IIC地址只有高4位有效。
  36. //----------------------------------------------------------------------------//
  37. #define IIC_ADDR_AT24CXX  0xA0


  38. //----------------------------------------------------------------------------//
  39. //宏名    :AT24CXX_MAX_SIZE
  40. //功能    :AT24Cxx的容量,以字節數為單位。僅限本文件使用。
  41. //重要說明:該宏受.H文件中“移植修改”部分的控制。這里請不要改動。
  42. //----------------------------------------------------------------------------//
  43. #if   defined(AT24C01)
  44.     #define AT24CXX_MAX_SIZE  0x0080    // AT24C01含有1K/8即128個字節

  45. #elif defined(AT24C02)
  46.     #define AT24CXX_MAX_SIZE  0x0100    // AT24C02含有2K/8即256個字節

  47. #elif defined(AT24C04)
  48.     #define AT24CXX_MAX_SIZE  0x0200    // AT24C04含有4K/8即512個字節

  49. #elif defined(AT24C08)
  50.     #define AT24CXX_MAX_SIZE  0x0400    // AT24C08含有8K/8即1K個字節

  51. #elif defined(AT24C16)
  52.     #define AT24CXX_MAX_SIZE  0x0800    // AT24C16含有16K/8即2K個字節

  53. #elif defined(AT24C32)
  54.     #define AT24CXX_MAX_SIZE  0x1000    // AT24C32含有32K/8即4K個字節

  55. #elif defined(AT24C64)
  56.     #define AT24CXX_MAX_SIZE  0x2000    // AT24C64含有64K/8即8K個字節

  57. #elif defined(AT24C128)
  58.     #define AT24CXX_MAX_SIZE  0x4000    // AT24C128含有128K/8即16K個字節

  59. #elif defined(AT24C256)
  60.     #define AT24CXX_MAX_SIZE  0x8000    // AT24C256含有256K/8即32K個字節

  61. #endif



  62. //----------------------------------------------------------------------------//
  63. //宏名    :AT24CXX_PAGEBUF_SIZE
  64. //功能    :AT24Cxx頁寫緩沖器大小。僅限本文件使用。
  65. //重要說明:該宏受H中移植修改”部分的控制。這里請不要改動。
  66. //----------------------------------------------------------------------------//
  67. #if   defined(AT24C01)
  68.     #define AT24CXX_PAGEBUF_SIZE   8    // AT24C01頁寫緩沖器大小為8B

  69. #elif defined(AT24C02)
  70.     #define AT24CXX_PAGEBUF_SIZE   8    // AT24C02頁寫緩沖器大小為8B

  71. #elif defined(AT24C04)
  72.     #define AT24CXX_PAGEBUF_SIZE  16    // AT24C04頁寫緩沖器大小為16B

  73. #elif defined(AT24C08)
  74.     #define AT24CXX_PAGEBUF_SIZE  16    // AT24C08頁寫緩沖器大小為16B

  75. #elif defined(AT24C16)
  76.     #define AT24CXX_PAGEBUF_SIZE  16    // AT24C16頁寫緩沖器大小為16B

  77. #elif defined(AT24C32)
  78.     #define AT24CXX_PAGEBUF_SIZE  32    // AT24C32頁寫緩沖器大小為32B

  79. #elif defined(AT24C64)
  80.     #define AT24CXX_PAGEBUF_SIZE  32    // AT24C64頁寫緩沖器大小為32B

  81. #elif defined(AT24C128)
  82.     #define AT24CXX_PAGEBUF_SIZE  64    // AT24C128頁寫緩沖器大小為64B

  83. #elif defined(AT24C256)
  84.     #define AT24CXX_PAGEBUF_SIZE  64    // AT24C256頁寫緩沖器大小為64B

  85. #endif

  86. ////////////////////////////////////////////////////////////////////////////////
  87. //                            本文件專用函數定義                              //
  88. ////////////////////////////////////////////////////////////////////////////////

  89. //----------------------------------------------------------------------------//
  90. //                檢測AT24Cxx內部頁寫(擦寫)是否完成函數(僅限本文件使用)
  91. //函數名稱:AT24Cxx_Finish_PageWrite
  92. //函數功能:檢測AT24Cxx內部是否頁寫(擦寫)完畢。一個頁寫的內部擦寫時間小于10ms。
  93. //入口參數:無。
  94. //出口參數:0,擦寫完畢;1,所用時間超過一頁最大擦寫時間,無應答(芯片或已損壞)。
  95. //重要說明:本函數只供寫操作函數AT24CxxWrStr()調用。
  96. //          用于在頁寫后對AT24Cxx進行檢測,以判斷其內部是否擦寫完畢。
  97. //----------------------------------------------------------------------------//
  98. static uint8 AT24Cxx_Finish_PageWrite(void)
  99. {
  100.     uint8 TimeFlow;         // 時間計數器
  101.     uint8 TmpAddr;
  102.     uint8 ErrFlg;           // 0 = 正確,1 = 出錯。

  103.     // 初始化局部變量。
  104.     TmpAddr = IIC_ADDR_AT24CXX; // EEPROM的IIC地址。
  105.     ErrFlg  = 0;

  106.     // 一個頁寫的內部擦寫時間小于10ms,這里檢查20次延時已經到了20ms。若還沒寫完,
  107.     // 則說可能寫入失敗。
  108.     ErrFlg = 1;

  109.     for(TimeFlow = 0; TimeFlow < 20; TimeFlow++)
  110.     {
  111.                             // 向IIC總線只發送其IIC地址(一字節),并判斷是否有回應
  112.         if(0 == IIC_MCU_Send_Str(&TmpAddr,1, &TmpAddr, 0))
  113.         {
  114.             ErrFlg = 0;     // 有回應說明擦寫已經完成。
  115.             break;
  116.         }

  117.         AT24Cxx_Delay_1ms();    // 延時1ms
  118.     }

  119.     // 返回出錯信息。0 = 擦寫完成,1 = 失敗。
  120.     return ErrFlg;
  121. }


  122. //----------------------------------------------------------------------------//
  123. //                      AT24Cxx溢出檢測函數(僅限本文件使用)
  124. //函數名稱:AT24Cxx_OverFlow_Check
  125. //函數功能:檢測AT24Cxx是否會發生地址溢出(或翻轉)。
  126. //          通過檢測EEPROM從當前地址開始的剩余字節數(AT24CXX_MAX_SIZE-Addr)和
  127. //          數據字節數DatSize的大小,來判斷是否會發生溢出。當(AT24CXX_MAX_SIZE-Addr)
  128. //          小于DatSize時,溢出、返回1;否則不溢出,返回0。
  129. //入口參數:Addr,AT24Cxx需要操作的起始字節地址。與A2 A1 A0無關。
  130. //          DatSize,需要操作數據的字節數
  131. //出口參數:1,會發生溢出;0,不會發生溢出。
  132. //重要說明:本函數只用于AT24Cxx發送和接收函數,用于在實際操作前進行溢出檢測。
  133. //----------------------------------------------------------------------------//

  134. static uint8 AT24Cxx_OverFlow_Check(uint16 Addr, uint16 DatSize)
  135. {
  136.     uint8 ErrFlg;           // 0 = 正確,1 = 出錯。

  137.     // 初始化局部變量。
  138.     ErrFlg  = 0;

  139.     // 當前地址已經大于了EEPROM的容量,會發生溢出。
  140.     if(Addr > AT24CXX_MAX_SIZE)
  141.     {
  142.         ErrFlg = 1;
  143.     }
  144.     // EEPROM剩余字節數比需要操作的字節數小,會發生溢出
  145.     else if((AT24CXX_MAX_SIZE - Addr) < DatSize)
  146.     {
  147.         ErrFlg = 1;
  148.     }

  149.     // 返回出錯信息。
  150.     return ErrFlg;
  151. }

  152. //-------------------------------------------------------------------------------//
  153. //                      AT24Cxx地址整理函數(僅限本文件使用)
  154. //函數名稱:AT24Cxx_Make_Addr
  155. //函數功能:把A2 A1 A0以及字節地址整理成發送格式,然后存放到PAddrBuf數組中。
  156. //          PAddrBuf數組需要3個字節的長度。
  157. //入口參數:
  158. //          A2A1A0:對應芯片A2 A1 A0引腳,低3位有效(高位被忽略)。
  159. //          Addr  :對24Cxx進行操作的起始地址。
  160. //          *PAddrBuf:處理后數據存放的地址。

  161. //出口參數:PAddrBuf數組中有效的字節數。即進行讀寫前發送的字節數。其中第1個字節是
  162. //          IIC地址和A2 A1 A0(或是a_n)的組合,第2個字節是字節地址,第3個字節(若是
  163. //          有的話)是字節地址。

  164. //重要說明:本函數不支持不同類型的IIC器件一起使用。
  165. //-------------------------------------------------------------------------------//
  166. static uint8 AT24Cxx_Make_Addr(uint8 A2A1A0, uint16 Addr, uint8 *PAddrBuf)
  167. {
  168.     uint8 AvailableLength = 0;

  169. #if   defined(AT24C01)      // 可級聯8個器件,7位字節地址,2字節發送。

  170.     // PAddrBuf[0]中存放的是(二進制表示)1  0   1  0    A2  A1  A0  0。
  171.     // PAddrBuf[1]中存放的是(二進制表示)0  a6 a5  a4   a3  a2  a1 a0。

  172.     // 操作數分別是  1 0 1 0        A2  A1  A0  0
  173.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  174.     PAddrBuf[1] = (uint8)(Addr & 0x7F);

  175.     AvailableLength = 2;

  176. #elif defined(AT24C02)      // 可級聯8個器件,8位字節地址,2字節發送。

  177.     // PAddrBuf[0]中存放的是(二進制表示)1  0  1  0    A2  A1  A0  0。
  178.     // PAddrBuf[1]中存放的是(二進制表示)a7 a6 a5 a4   a3  a2  a1 a0。

  179.     // 操作數分別是  1 0 1 0           A2  A1  A0  0
  180.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  181.     PAddrBuf[1] = (uint8)(Addr & 0xFF);

  182.     AvailableLength = 2;

  183. #elif defined(AT24C04)      // 可級聯4個器件,9位字節地址,2字節發送。

  184.     // PAddrBuf[0]中存放的是(二進制表示)1   0  1   0   A1  A0  a8  0。
  185.     // PAddrBuf[1]中存放的是(二進制表示)a7 a6  a5  a4  a3  a2  a1  a0。

  186.     // 操作數分別是  1 0 1 0            A1 A0                        a8    0
  187.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 2) & 0x0C) | (uint8)((Addr >> 7) & 0x02);
  188.     PAddrBuf[1] = (uint8)(Addr & 0xFF);

  189.     AvailableLength = 2;

  190. #elif defined(AT24C08)      // 可級聯2個器件,10位字節地址,2字節發送。

  191.     // PAddrBuf[0]中存放的是(二進制表示)1   0   1  0   A0  a9  a8  0。
  192.     // PAddrBuf[1]中存放的是(二進制表示)a7 a6  a5  a4  a3  a2  a1 a0。

  193.     // 操作數分別是  1 0 1 0                A0                     a9   a8   0  
  194.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 3) & 0x08) | (uint8)((Addr >> 7) & 0x06);
  195.     PAddrBuf[1] = (uint8)(Addr & 0xFF);

  196.     AvailableLength = 2;

  197. #elif defined(AT24C16)      // 不可級聯,11位字節地址,2字節發送。

  198.     // PAddrBuf[0]中存放的是(二進制表示)1   0   1  0  a10  a9  a8  0。
  199.     // PAddrBuf[1]中存放的是(二進制表示)a7 a6  a5  a4  a3  a2  a1 a0。

  200.     // 操作數分別是  1 0 1 0              a10   a9   a8   0  
  201.     PAddrBuf[0] = IIC_ADDR_AT24Cxx | (uint8)((Addr >> 7) & 0x0E);
  202.     PAddrBuf[1] = (uint8)(Addr & 0xFF);

  203.     A2A1A0 = 0;    // 故意使用A2A1A0一次,以避免Keil的警告信息

  204.     AvailableLength = 2;

  205. #elif defined(AT24C32)      // 可級聯8個器件,12位字節地址,3字節發送。

  206.     // PAddrBuf[0]中存放的是(二進制表示)1    0     1    0    A2   A1   A0   0。
  207.     // PAddrBuf[1]中存放的是(二進制表示)0    0     0    0   a11  a10   a9  a8。
  208.     // PAddrBuf[2]中存放的是(二進制表示)a7   a6   a5   a4    a3   a2   a1  a0。

  209.     // 操作數分別是  1 0 1 0        A2  A1  A0  0
  210.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  211.     PAddrBuf[1] = (uint8)((Addr >> 8) & 0x0F);
  212.     PAddrBuf[2] = (uint8)(Addr & 0xFF);

  213.     AvailableLength = 3;

  214. #elif defined(AT24C64)      // 可級聯8個器件,13位字節地址,3字節發送。

  215.     // PAddrBuf[0]中存放的是(二進制表示)1    0     1    0    A2   A1   A0   0。
  216.     // PAddrBuf[1]中存放的是(二進制表示)0    0     0   a12  a11  a10   a9  a8。
  217.     // PAddrBuf[2]中存放的是(二進制表示)a7   a6   a5   a4    a3   a2   a1  a0。

  218.     // 操作數分別是  1 0 1 0        A2  A1  A0  0
  219.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  220.     PAddrBuf[1] = (uint8)((Addr >> 8) & 0x1F);
  221.     PAddrBuf[2] = (uint8)(Addr & 0xFF);

  222.     AvailableLength = 3;

  223. #elif defined(AT24C128)     // 可級聯8個器件,14位字節地址,3字節發送。

  224.     // PAddrBuf[0]中存放的是(二進制表示)1    0     1    0      A2   A1   A0   0。
  225.     // PAddrBuf[1]中存放的是(二進制表示)0    0    a13  a12    a11  a10   a9  a8。
  226.     // PAddrBuf[2]中存放的是(二進制表示)a7   a6   a5   a4      a3   a2   a1  a0。

  227.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  228.     PAddrBuf[1] = (uint8)((Addr >> 8) & 0x3F);
  229.     PAddrBuf[2] = (uint8)(Addr & 0xFF);
  230.     A2A1A0 = 0;    // 故意使用A2A1A0一次,以避免Keil的警告信息

  231.     AvailableLength = 3;

  232. #elif defined(AT24C256) //可級聯8個器件,15位字節地址,3字節發送。

  233.     // PAddrBuf[0]中存放的是(二進制表示)1    0     1    0      A2   A1   A0   0。
  234.     // PAddrBuf[1]中存放的是(二進制表示)0   a14   a13  a12    a11  a10   a9  a8。
  235.     // PAddrBuf[2]中存放的是(二進制表示)a7   a6   a5   a4      a3   a2   a1  a0。

  236.     // 操作數分別是  1 0 1 0        0  A1  A0  0
  237.     PAddrBuf[0] = IIC_ADDR_AT24CXX | ((A2A1A0 << 1) & 0x0E);
  238.     PAddrBuf[1] = (uint8)((Addr >> 8) & 0x7F);
  239.     PAddrBuf[2] = (uint8)(Addr & 0xFF);

  240.     AvailableLength = 3;

  241. #endif


  242.     //返回PAddrBuf數組中的有效字節數
  243.     return AvailableLength;
  244. }

  245. ////////////////////////////////////////////////////////////////////////////////
  246. //                          本文件專用函數定義結束                            //
  247. ////////////////////////////////////////////////////////////////////////////////







  248. ////////////////////////////////////////////////////////////////////////////////
  249. //                             對外服務函數定義                               //
  250. ////////////////////////////////////////////////////////////////////////////////
  251. //----------------------------------------------------------------------------//
  252. //                    允許寫入和禁止寫入函數(對外接口)
  253. //函數名稱:
  254. //函數功能:允許寫入和禁止寫入。
  255. //入口參數:無
  256. //出口參數:無
  257. //重要說明:沒有啟用寫保護功能時,本函數不會進行編譯。
  258. //----------------------------------------------------------------------------//
  259. #if (1 == AT24CXX_WP_ENABLE)

  260. extern void AT24Cxx_Write_Enable(void)      // 允許寫入。
  261. {
  262.     AT24Cxx_WP = 0;
  263. }

  264. extern void AT24Cxx_Write_Disable(void)     // 禁止寫入。
  265. {
  266.     AT24Cxx_WP = 1;
  267. }

  268. #endif

  269. //----------------------------------------------------------------------------//
  270. //                    從AT24Cxx中讀取多字節數據函數(對外接口)
  271. //函數名稱:AT24Cxx_Read_Str
  272. //函數功能:從Addr指定的地址開始讀取AT24Cxx,一共讀取Num個字節,數據讀出后存放在
  273. //          PDat數組中。
  274. //入口參數:
  275. //          A2A1A0:對應芯片A2 A1 A0引腳,低3位有效(高位被忽略).
  276. //          Addr:對24Cxx進行讀操作的起始地址。
  277. //         *PDat:數據讀取后存放的首地址
  278. //          Num :要讀取的字節數
  279. //出口參數:0 = 成功,1 = 失敗。
  280. //重要說明:1.讀取的第一個字節放在PDat[0]中,第二個放在PDat[1]中,以此類推。
  281. //        :2.若EEPROM剩余空間不足,函數報錯。
  282. //----------------------------------------------------------------------------//
  283. extern uint8 AT24Cxx_Read_Str(uint8 A2A1A0, uint16 Addr, uint8 *PDat, uint16 Num)
  284. {
  285.     uint8 ErrFlg;               // 0 = 正確,1 = 錯誤。
  286.     uint8 AddrBuf[3];           // 該數組用于接收AT24CxxDivideAddr()函數分解后的地址信息。
  287.     uint8 AddrLength;           // 該變量用于指示AddrBuf數組中有效的字節數。

  288.     // 局部變量初始化。
  289.     ErrFlg = 0;

  290.     // 忽略A2A1A0的高位。
  291.     A2A1A0 &= 0x07;

  292.     // 溢出檢測
  293.     ErrFlg = AT24Cxx_OverFlow_Check(Addr, Num);

  294.     // 把地址整理成發送格式。并獲取地址字節數。
  295.     AddrLength = AT24Cxx_Make_Addr(A2A1A0, Addr, AddrBuf);

  296.     // 讀取數據。
  297.     if(0 == ErrFlg)
  298.     {
  299.         ErrFlg = IIC_MCU_Rcv_Str(AddrBuf, AddrLength, PDat, Num);
  300.     }

  301.     // 返回出錯信息。
  302.     return ErrFlg;
  303. }


  304. //-------------------------------------------------------------------------------//
  305. //                    向AT24Cxx寫入多字節數據函數(對外接口)
  306. //函數名稱:AT24Cxx_Write_Str
  307. //函數功能:向AT24Cxx中寫入多字節。寫入的起始地址由Addr確定,數據存放的首地址在PDat中存
  308. //          放,寫入的字節數是Num(16位無符號數)。
  309. //入口參數:
  310. //          A2A1A0:對應芯片A2 A1 A0引腳,低3位有效(高位被忽略).
  311. //          Addr:對24Cxx進行寫操作的起始地址。
  312. //         *PDat:發送的數據存放的首地址
  313. //          Num :發送的字節數
  314. //出口參數:0 = 成功,1 = 失敗。
  315. //重要說明:1.先發送PDat[0],再發送PDat[1],以此類推。
  316. //        :2.若EEPROM剩余空間不足,函數報錯。
  317. //        :3.若啟用了寫保護功能,必須先使寫保護失效,否則無法進行寫入。
  318. //-------------------------------------------------------------------------------//
  319. extern uint8 AT24Cxx_Write_Str(uint8 A2A1A0, uint16 Addr, uint8 *PDat, uint16 Num)
  320. {
  321.     uint8 ErrFlg;           // 0 = 正確,1 = 錯誤。

  322.     uint8 AddrBuf[3];       // 該數組用于接收AT24CxxDivideAddr()函數分解后的地址信息。
  323.     uint8 AddrLength;       // 該變量用于指示AddrBuf數組中有效的字節數。
  324.     uint8 PageRemainSize;   // 該變量用于指示當前頁剩余字節數據

  325.     // 局部變量初始化。
  326.     ErrFlg = 0;
  327.     PageRemainSize = 0;

  328.     // 忽略A2A1A0的高位。
  329.     A2A1A0 &= 0x07;

  330.     // 溢出檢測
  331.     ErrFlg = AT24Cxx_OverFlow_Check(Addr, Num);

  332.     // 當前頁剩余字節數賦給該PageRemainSize變量
  333.     PageRemainSize = AT24CXX_PAGEBUF_SIZE - Addr % AT24CXX_PAGEBUF_SIZE;

  334.     // 如果當前EEPROM寫保護,則返回錯誤。
  335.     #if (1 == AT24CXX_WP_ENABLE)
  336.     if(  1== AT24Cxx_WP)
  337.     {
  338.         ErrFlg = 1;
  339.     }
  340.     #endif

  341.     // -------------寫入的字節小于等于當前頁的剩余字節------------------
  342.     if(Num <= PageRemainSize)
  343.     {
  344.         if(0 == ErrFlg)
  345.         {
  346.             // 把地址整理成發送格式。并獲取地址字節數。
  347.             AddrLength = AT24Cxx_Make_Addr(A2A1A0, Addr, AddrBuf);

  348.             // 發送數據。一次寫入所有字節,即Num個字節
  349.             ErrFlg |= IIC_MCU_Send_Str(AddrBuf, AddrLength, PDat, Num);

  350.             // 等待AT24Cxx擦寫完畢
  351.             ErrFlg |= AT24Cxx_Finish_PageWrite();
  352.         }
  353.     }
  354.     // --------------寫入的字節數大于當前頁的剩余字節數-----------------
  355.     else
  356.     {
  357.         ////// 先寫當前頁 //////
  358.         if(0 == ErrFlg)
  359.         {
  360.             // 把地址整理成發送格式。并獲取地址字節數。
  361.             AddrLength = AT24Cxx_Make_Addr(A2A1A0, Addr, AddrBuf);

  362.             // 寫當前頁剩余字節。
  363.             ErrFlg |= IIC_MCU_Send_Str(AddrBuf, AddrLength, PDat, PageRemainSize);

  364.             // 等待AT24Cxx擦寫完畢
  365.             ErrFlg |= AT24Cxx_Finish_PageWrite();

  366.             // 改變相應的變量的值,為下次發送做準備
  367.             Addr += PageRemainSize;           // AT24Cxx寫入地址增加
  368.             PDat += PageRemainSize;           // 存放數據的地址增加
  369.             Num  -= PageRemainSize;           // 需要寫入的字節數減少
  370.         }// if(0 == ErrFlg)

  371.         ////// 寫當前頁完畢 //////

  372.         //////  寫中間整頁  //////
  373.         while(Num > AT24CXX_PAGEBUF_SIZE)   // 這里不可使用>=號,否則會死循環。
  374.         {
  375.             // 寫入時出錯,立即中止寫入操作。
  376.             if(1 == ErrFlg)
  377.             {
  378.                 break;
  379.             }

  380.             // 把地址整理成發送格式。并獲取地址字節數。
  381.             AddrLength = AT24Cxx_Make_Addr(A2A1A0, Addr, AddrBuf);

  382.             // 發送數據。整頁寫,即一次寫AT24CXX_PAGEBUF_SIZE個字節。
  383.             ErrFlg |= IIC_MCU_Send_Str(AddrBuf, AddrLength, PDat, AT24CXX_PAGEBUF_SIZE);

  384.             // 等待AT24Cxx擦寫完畢
  385.             ErrFlg |= AT24Cxx_Finish_PageWrite();

  386.             // 改變相應的變量的值,為下次發送做準備
  387.             Addr += AT24CXX_PAGEBUF_SIZE;       // AT24Cxx寫入地址增加
  388.             PDat += AT24CXX_PAGEBUF_SIZE;       // 存放數據的地址增加
  389.             Num  -= AT24CXX_PAGEBUF_SIZE;       // 需要寫入的字節數減少

  390.         }// while(Num > AT24CXX_PAGEBUF_SIZE)
  391.         //////寫中間整頁完畢//////

  392.         //////  寫最后一頁  //////
  393.         if(0 == ErrFlg)
  394.         {
  395.             // 把地址整理成發送格式。并獲取地址字節數。
  396.             AddrLength = AT24Cxx_Make_Addr(A2A1A0, Addr, AddrBuf);

  397.             // 寫當最后一頁剩余字節。
  398.             ErrFlg |= IIC_MCU_Send_Str(AddrBuf, AddrLength, PDat, Num);

  399.             // 等待AT24Cxx擦寫完畢
  400.             ErrFlg |= AT24Cxx_Finish_PageWrite();

  401.         }// if(0 == ErrFlg)

  402.         //////寫最后一頁完畢//////

  403.     }// if(Num <= PageRemainSize)


  404.     // 返回出錯信息。
  405.     return ErrFlg;
  406. }

  407. ////////////////////////////////////////////////////////////////////////////////
  408. //                           對外服務函數定義結束                             //
  409. ////////////////////////////////////////////////////////////////////////////////



  410. //------------------------------    文件結束    ------------------------------//
復制代碼
回復

使用道具 舉報

5#
ID:70650 發表于 2014-12-20 18:52 | 只看該作者
ChipAT24Cxx.H文件:
  1. /*
  2. ********************************************************************************
  3. *                                    
  4. *                             
  5. *
  6. *     
  7. *                  (c) Copyright 2012,   All Rights Reserved
  8. *                                
  9. * 開發環境  : Keil4
  10. * 文件名    : ChipAT24Cxx.H
  11. * 程序員    : 3htech
  12. * 開發時間  : 20110907--20110907
  13. * 描述      : EEPROM芯片AT24Cxx驅動。   其他與AT24C比完全兼容的EEPROM芯片也可使用本驅動。
  14. *           :不支持不同容量的EEPROM混用,同容量的EEPROM可以一起使用。
  15. * 生存條件  : 類型重定義,還需要一個毫秒級精確延時函數Delay_MS();
  16. *-------------------------------------------------------------------------------
  17. * 修 改    :
  18. * 日 期    :
  19. * 描  述    :
  20. *-------------------------------------------------------------------------------
  21. ********************************************************************************
  22. */
  23. //------------------------------    文件開關    ------------------------------//
  24. // 防止文件包含時多次編本文件,與本文件結尾處的endif對應。
  25. #ifndef         _ChIPAT24CXX_H_
  26.     #define     _ChIPAT24CXX_H_
  27. //----------------------------------------------------------------------------//



  28. //------------------------------ 系統頭文件包含 ------------------------------//
  29. // 無

  30. //----------------------------- 自定義頭文件包含 -----------------------------//
  31. #include"BusIIC_ATT703x.H"
  32. #include"TypeRedefine.H"

  33. ////////////////////////////////////////////////////////////////////////////////
  34. //                              移植修改(5處)                                 //
  35. ////////////////////////////////////////////////////////////////////////////////
  36. //----------------------------------------------------------------------------//
  37. // 編號 :1
  38. // 名稱 :
  39. // 功能 :單片機寄存器頭文件,例如reg51.h
  40. //----------------------------------------------------------------------------//
  41. #include "ATT703x.H"

  42. //----------------------------------------------------------------------------//
  43. // 編號 :2
  44. // 名稱 :AT24Cxx
  45. // 功能 :選擇您所使用的EEPROM芯片型號。只能啟用一條宏。
  46. //      :不支持一條總線上掛不同的EEPROM,支持同類型的多個EEPROM掛在總線上。
  47. //----------------------------------------------------------------------------//
  48. //  #define AT24C01         // 使用AT24C01,則啟用本句并屏蔽其它語句。
  49. //  #define AT24C02         // 使用AT24C02,則啟用本句并屏蔽其它語句。
  50.     #define AT24C04         // 使用AT24C04,則啟用本句并屏蔽其它語句。
  51. //  #define AT24C08         // 使用AT24C08,則啟用本句并屏蔽其它語句。
  52. //  #define AT24C16         // 使用AT24C16,則啟用本句并屏蔽其它語句。
  53. //  #define AT24C32         // 使用AT24C32,則啟用本句并屏蔽其它語句。
  54. //  #define AT24C64         // 使用AT24C64,則啟用本句并屏蔽其它語句。
  55. //  #define AT24C128        //使用AT24C128,則啟用本句并屏蔽其它語句。
  56. //  #define AT24C256        //使用AT24C256,則啟用本句并屏蔽其它語句。


  57. //----------------------------------------------------------------------------//
  58. // 編號 :3
  59. // 名稱 :AT24CXX_WP_ENABLE
  60. // 功能 :啟用AT24Cxx的寫保護功能。為1時啟用寫保護。為0時不使用寫保護。
  61. //      :當WP引腳接地時,請禁用寫保護功能。否則會浪費系統資源。
  62. //----------------------------------------------------------------------------//
  63. #define   AT24CXX_WP_ENABLE   (0)


  64. //----------------------------------------------------------------------------//
  65. // 編號 :4
  66. // 名稱 :AT24Cxx_WP
  67. // 功能 :寫保護引腳所用的口線。啟用寫保護時,才需要設置本參數
  68. //----------------------------------------------------------------------------//
  69. #if (1 == AT24CXX_WP_ENABLE)
  70.     sbit   AT24Cxx_WP = P1^2;
  71. #endif

  72. //----------------------------------------------------------------------------//
  73. // 編號 :5
  74. // 名稱 :AT24Cxx_Delay_1ms()
  75. // 功能 :精確的1毫秒延時函數。這里請使用您系統中的微秒延時函數。
  76. //      :例如,您的延時函數是Delay_1us(),那么您可以使用下句
  77. //      :#define AT24Cxx_Delay_1us()  Delay_1us()
  78. //      :來實現延時。
  79. //----------------------------------------------------------------------------//
  80. #include "Delay.H"      // 您系統所用延時函數聲明所在的頭文件。
  81. #define AT24Cxx_Delay_1ms()   Delay_MS(1)
  82. ////////////////////////////////////////////////////////////////////////////////
  83. //                               移植修改結束                                 //
  84. ////////////////////////////////////////////////////////////////////////////////



  85. //------------------------------  全局變量聲明  ------------------------------//

  86. //----------------------------------------------------------------------------//
  87. //變量名稱:
  88. //變量功能:
  89. //作用域  :全局變量、僅限本文件、對外完全不可見;(對外完全可見)
  90. //重要說明:無
  91. //----------------------------------------------------------------------------//




  92. //-------------------------------   宏定義   ---------------------------------//
  93. //----------------------------------------------------------------------------//
  94. //宏名    :
  95. //功能    :
  96. //重要說明:無
  97. //----------------------------------------------------------------------------//






  98. ////////////////////////////////////////////////////////////////////////////////
  99. //                                 函數聲明                                   //
  100. ////////////////////////////////////////////////////////////////////////////////

  101. #if (1 == AT24CXX_WP_ENABLE)

  102. extern void AT24Cxx_Write_Enable(void);     // 允許寫入。
  103. extern void AT24Cxx_Write_Disable(void);    // 禁止寫入。

  104. #endif


  105. extern uint8 AT24Cxx_Read_Str (uint8 A2A1A0, uint16 Addr, uint8 *PDat, uint16 Num);
  106. extern uint8 AT24Cxx_Write_Str(uint8 A2A1A0, uint16 Addr, uint8 *PDat, uint16 Num);

  107. ////////////////////////////////////////////////////////////////////////////////
  108. //                               函數聲明結束                                 //
  109. ////////////////////////////////////////////////////////////////////////////////

  110. //------------------------------    文件開關    ------------------------------//
  111. // 防止文件包含時多次編本文件,與本文件開頭處的 #ifndef 對應。
  112. #endif
  113. //----------------------------------------------------------------------------//

  114. //------------------------------    文件結束    ------------------------------//
復制代碼
回復

使用道具 舉報

6#
ID:70650 發表于 2014-12-20 18:53 | 只看該作者
TypeRedefine.H文件:
  1. /*
  2. ********************************************************************************
  3. *                                    
  4. *                             
  5. *
  6. *     地址:
  7. *                  (c) Copyright 2012,   All Rights Reserved
  8. *                                
  9. * 開發環境  : Keil4
  10. * 文件名    : TypeRedefine.H
  11. * 程序員    : 3htech
  12. * 開發時間  : 2012-06-04
  13. * 描述      : 類型重新定義。
  14. * 生存條件  : 自由存在。
  15. *-------------------------------------------------------------------------------
  16. * 修 改    :
  17. * 日 期    :
  18. * 描  述    :
  19. *-------------------------------------------------------------------------------
  20. ********************************************************************************
  21. */


  22. //------------------------------    文件開關    ------------------------------//
  23. // 防止文件包含時多次編本文件,與本文件結尾處的endif對應。
  24. #ifndef     _TYPEREDEFINE_H_
  25.     #define _TYPEREDEFINE_H_
  26. //----------------------------------------------------------------------------//




  27. //------------------------------ 系統頭文件包含 ------------------------------//
  28. #include<stdio.H>       // 為了使用NULL的定義。

  29. //----------------------------- 自定義頭文件包含 -----------------------------//
  30. //無
  31. //--------------------------------  類型聲明  --------------------------------//
  32. //----------------------------------------------------------------------------//
  33. //類型名稱:
  34. //類型功能:
  35. //成員詳解:
  36. //重要說明:
  37. //----------------------------------------------------------------------------//


  38. //------------------------------  全局變量定義  ------------------------------//
  39. //無


  40. //--------------------------------------------------------------//
  41. //                     類型重新定義
  42. //名稱:類型重新定義
  43. //功能:
  44. //      51系列單片機應用下的類型重新定義。
  45. //      使用的是8位單片機,因此char是8位,int為16位,long為32位
  46. //--------------------------------------------------------------//

  47. typedef  bit  bdata   uint1;    //  無符號1 位整型變量需要加前綴u1

  48. typedef unsigned char uint8;    // 無符號8 位整型,前綴u8
  49. typedef   signed char  int8;    // 有符號8 位整型,前綴i8

  50. typedef unsigned int  uint16;   // 無符號16位整型,前綴u16
  51. typedef   signed int   int16;   // 有符號16位整型,前綴i16

  52. typedef unsigned long uint32;   // 無符號32位整型,前綴u32
  53. typedef   signed long  int32;   // 有符號32位整型,前綴i32

  54. typedef  float         flt32;   // 單精度浮點數(32位長度),前綴f32



  55. //-------------------------------   宏定義   ---------------------------------//
  56. //----------------------------------------------------------------------------//
  57. //宏名    :TURE, FALSE
  58. //功能    :錯誤標志或操作完成標志。
  59. //重要說明:無
  60. //----------------------------------------------------------------------------//
  61. #ifndef TRUE
  62.     #define TRUE  0
  63. #endif

  64. #ifndef FALSE
  65.     #define FALSE 1
  66. #endif
  67. //------------------------------    文件開關    ------------------------------//
  68. // 防止文件包含時多次編本文件,與本文件開頭處的 #ifndef 對應。
  69. #endif
  70. //----------------------------------------------------------------------------//


  71. //------------------------------    文件結束    ------------------------------//
復制代碼
回復

使用道具 舉報

7#
ID:11942 發表于 2015-1-7 13:57 | 只看該作者
學習學習
回復

使用道具 舉報

8#
ID:96187 發表于 2015-11-18 09:32 | 只看該作者
拜讀了,受益匪淺
回復

使用道具 舉報

9#
ID:79544 發表于 2016-9-8 20:04 | 只看該作者
感覺好亂啊,怎么沒頭緒
回復

使用道具 舉報

10#
ID:235719 發表于 2018-12-14 09:05 | 只看該作者
寫得規范啊
回復

使用道具 舉報

11#
ID:235719 發表于 2018-12-14 09:33 | 只看該作者
十分規范,就是有些地方可以優化精簡,畢竟如果51用代碼占太多空間了。
回復

使用道具 舉報

12#
ID:147215 發表于 2020-5-14 09:46 | 只看該作者
謝謝分享!,,,,
回復

使用道具 舉報

13#
ID:704585 發表于 2020-6-3 14:08 | 只看該作者
感謝樓主分享
回復

使用道具 舉報

14#
ID:684771 發表于 2020-6-3 16:43 | 只看該作者
感謝分享
回復

使用道具 舉報

15#
ID:128463 發表于 2020-6-5 08:40 | 只看該作者

感謝樓主分享!!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九久久这里只有精品 | 国产目拍亚洲精品99久久精品 | 伊人网在线播放 | 国产黄色在线 | 一区二区三区四区免费在线观看 | 一级爱爱片 | 国产精品日韩一区 | 中文字幕第一页在线 | 天天曰天天干 | 午夜激情在线视频 | 成人精品 | 99久久婷婷国产亚洲终合精品 | 91大神新作在线观看 | 色999日韩| 久久久久久久成人 | 国产精品二区三区 | 国产日韩欧美中文 | 成年人黄色免费视频 | 国产久 | 伊人成人免费视频 | 国产欧美日韩视频 | 欧美精品一区二区三区在线播放 | 久久在线免费 | 亚洲精品久久久久久宅男 | 人人九九精 | 国产精品视频久久久久久 | 免费国产视频在线观看 | 久久一区二区av | 精品无码三级在线观看视频 | 亚洲第一在线 | 日韩av免费在线电影 | 国内91在线 | 黄a网站| 国产精品久久久久不卡 | 男女一区二区三区 | 中文字幕在线不卡 | 91久久精品国产 | 日韩在线中文字幕 | 国产成人精品一区二区三区视频 | 久久久www成人免费精品张筱雨 | 日韩一区二区在线观看 |