找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2469|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)虛擬I2C總線匯編與C語言軟件包,很實(shí)用的

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:95059 發(fā)表于 2018-6-17 20:42 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
      該軟件包只用在100K或400K速度的I2C器件,如果用在低速一些的器件(如:ZLG7290)就需要調(diào)整運(yùn)行時(shí)間,如在通信過程中增加NOP指令等增加延時(shí)時(shí)間.


虛擬 I2C總線匯編程序軟件包概述
為了非常方便地對(duì) I2C 從器件進(jìn)行快速的 正確的讀寫操作,我們?yōu)榇硕O(shè)計(jì)出虛擬 I2C 總線操作平臺(tái)軟件包 本軟件包是主方式下的虛擬 I2C 總線軟件包,只要用戶給子程序提供幾個(gè)主要的參數(shù),即可輕松地完成任何I2C 總線外圍器件的應(yīng)用程序設(shè)計(jì)  

全部資料51hei下載地址:
I2C軟件包,很有用,移植性好.rar (67.11 KB, 下載次數(shù): 25)


單片機(jī)源程序如下:
  1. /********************************************************************
  2.                        VIIC_C51.C
  3.   此程序是I2C操作平臺(tái)(主方式的軟件平臺(tái))的底層的C子程序,如發(fā)送數(shù)據(jù)
  4. 及接收數(shù)據(jù),應(yīng)答位發(fā)送,并提供了幾個(gè)直接面對(duì)器件的操作函數(shù),它很方便的
  5. 與用戶程序連接并擴(kuò)展.....  
  6.   
  7.     注意:函數(shù)是采用軟件延時(shí)的方法產(chǎn)生SCL脈沖,固對(duì)高晶振頻率要作
  8. 一定的修改....(本例是1us機(jī)器周期,即晶振頻率要小于12MHZ)

  9. ********************************************************************/
  10.   
  11.   
  12.               
  13. #include <reg764.h>          /*頭文件的包含*/
  14. #include <intrins.h>

  15. #define  uchar unsigned char /*宏定義*/
  16. #define  uint  unsigned int

  17. #define  _Nop()  _nop_()        /*定義空指令*/

  18. /* 常,變量定義區(qū) */

  19.                                                  /*端口位定義*/
  20. sbit SDA=P1^3;            /*模擬I2C數(shù)據(jù)傳送位*/
  21. sbit SCL=P1^2;            /*模擬I2C時(shí)鐘控制位*/

  22.                                                  /*狀態(tài)標(biāo)志*/
  23. bit ack;                 /*應(yīng)答標(biāo)志位*/
  24.    





  25. /*******************************************************************
  26.                      起動(dòng)總線函數(shù)               
  27. 函數(shù)原型: void  Start_I2c();  
  28. 功能:       啟動(dòng)I2C總線,即發(fā)送I2C起始條件.
  29.   
  30. ********************************************************************/
  31. void Start_I2c()
  32. {
  33.   SDA=1;   /*發(fā)送起始條件的數(shù)據(jù)信號(hào)*/
  34.   _Nop();
  35.   SCL=1;
  36.   _Nop();    /*起始條件建立時(shí)間大于4.7us,延時(shí)*/
  37.   _Nop();
  38.   _Nop();
  39.   _Nop();
  40.   _Nop();   
  41.   SDA=0;   /*發(fā)送起始信號(hào)*/
  42.   _Nop();    /* 起始條件鎖定時(shí)間大于4μs*/
  43.   _Nop();
  44.   _Nop();
  45.   _Nop();
  46.   _Nop();      
  47.   SCL=0;   /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
  48.   _Nop();
  49.   _Nop();
  50. }




  51. /*******************************************************************
  52.                       結(jié)束總線函數(shù)               
  53. 函數(shù)原型: void  Stop_I2c();  
  54. 功能:       結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.
  55.   
  56. ********************************************************************/
  57. void Stop_I2c()
  58. {
  59.   SDA=0;  /*發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)*/
  60.   _Nop();   /*發(fā)送結(jié)束條件的時(shí)鐘信號(hào)*/
  61.   SCL=1;  /*結(jié)束條件建立時(shí)間大于4μs*/
  62.   _Nop();
  63.   _Nop();
  64.   _Nop();
  65.   _Nop();
  66.   _Nop();
  67.   SDA=1;  /*發(fā)送I2C總線結(jié)束信號(hào)*/
  68.   _Nop();
  69.   _Nop();
  70.   _Nop();
  71.   _Nop();
  72. }




  73. /*******************************************************************
  74.                  字節(jié)數(shù)據(jù)傳送函數(shù)               
  75. 函數(shù)原型: void  SendByte(uchar c);
  76. 功能:  將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對(duì)
  77.      此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0 假)     
  78.      發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應(yīng)答或損壞。
  79. ********************************************************************/
  80. void  SendByte(uchar c)
  81. {
  82. uchar BitCnt;

  83. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要傳送的數(shù)據(jù)長(zhǎng)度為8位*/
  84.     {
  85.      if((c<<BitCnt)&0x80)SDA=1;   /*判斷發(fā)送位*/
  86.        else  SDA=0;               
  87.      _Nop();
  88.      SCL=1;               /*置時(shí)鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
  89.       _Nop();
  90.       _Nop();               /*保證時(shí)鐘高電平周期大于4μs*/
  91.       _Nop();
  92.       _Nop();
  93.       _Nop();         
  94.      SCL=0;
  95.     }
  96.    
  97.     _Nop();
  98.     _Nop();
  99.     SDA=1;               /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
  100.     _Nop();
  101.     _Nop();   
  102.     SCL=1;
  103.     _Nop();
  104.     _Nop();
  105.     _Nop();
  106.     if(SDA==1)ack=0;     
  107.        else ack=1;        /*判斷是否接收到應(yīng)答信號(hào)*/
  108.     SCL=0;
  109.     _Nop();
  110.     _Nop();
  111. }






  112. /*******************************************************************
  113.                  字節(jié)數(shù)據(jù)傳送函數(shù)               
  114. 函數(shù)原型: uchar  RcvByte();
  115. 功能:  用來接收從器件傳來的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號(hào)),
  116.      發(fā)完后請(qǐng)用應(yīng)答函數(shù)。  
  117. ********************************************************************/       
  118. uchar  RcvByte()
  119. {
  120.   uchar retc;
  121.   uchar BitCnt;
  122.   
  123.   retc=0;
  124.   SDA=1;             /*置數(shù)據(jù)線為輸入方式*/
  125.   for(BitCnt=0;BitCnt<8;BitCnt++)
  126.       {
  127.         _Nop();           
  128.         SCL=0;       /*置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位*/
  129.         _Nop();
  130.         _Nop();         /*時(shí)鐘低電平周期大于4.7μs*/
  131.         _Nop();
  132.         _Nop();
  133.         _Nop();
  134.         SCL=1;       /*置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效*/
  135.         _Nop();
  136.         _Nop();
  137.         retc=retc<<1;
  138.         if(SDA==1)retc=retc+1; /*讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中 */
  139.         _Nop();
  140.         _Nop();
  141.       }
  142.   SCL=0;   
  143.   _Nop();
  144.   _Nop();
  145.   return(retc);
  146. }




  147. /********************************************************************
  148.                      應(yīng)答子函數(shù)
  149. 原型:  void Ack_I2c(bit a);

  150. 功能:主控器進(jìn)行應(yīng)答信號(hào),(可以是應(yīng)答或非應(yīng)答信號(hào))
  151. ********************************************************************/
  152. void Ack_I2c(bit a)
  153. {
  154.   
  155.   if(a==0)SDA=0;     /*在此發(fā)出應(yīng)答或非應(yīng)答信號(hào) */
  156.         else SDA=1;
  157.   _Nop();
  158.   _Nop();
  159.   _Nop();      
  160.   SCL=1;
  161.     _Nop();
  162.     _Nop();              /*時(shí)鐘低電平周期大于4μs*/
  163.     _Nop();
  164.     _Nop();
  165.     _Nop();  
  166. SCL=0;                /*清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收*/
  167.     _Nop();
  168.     _Nop();   
  169. }






  170. /*******************************************************************
  171.                     向無子地址器件發(fā)送字節(jié)數(shù)據(jù)函數(shù)               
  172. 函數(shù)原型: bit  ISendByte(uchar sla,ucahr c);  
  173. 功能:     從啟動(dòng)總線到發(fā)送地址,數(shù)據(jù),結(jié)束總線的全過程,從器件地址sla.
  174.            如果返回1表示操作成功,否則操作有誤。
  175. 注意:    使用前必須已結(jié)束總線。
  176. ********************************************************************/
  177. bit ISendByte(uchar sla,uchar c)
  178. {
  179.    Start_I2c();               /*啟動(dòng)總線*/
  180.    SendByte(sla);            /*發(fā)送器件地址*/
  181.      if(ack==0)return(0);
  182.    SendByte(c);               /*發(fā)送數(shù)據(jù)*/
  183.      if(ack==0)return(0);
  184.   Stop_I2c();                 /*結(jié)束總線*/
  185.   return(1);
  186. }




  187. /*******************************************************************
  188.                     向有子地址器件發(fā)送多字節(jié)數(shù)據(jù)函數(shù)               
  189. 函數(shù)原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
  190. 功能:     從啟動(dòng)總線到發(fā)送地址,子地址,數(shù)據(jù),結(jié)束總線的全過程,從器件
  191.           地址sla,子地址suba,發(fā)送內(nèi)容是s指向的內(nèi)容,發(fā)送no個(gè)字節(jié)。
  192.            如果返回1表示操作成功,否則操作有誤。
  193. 注意:    使用前必須已結(jié)束總線。
  194. ********************************************************************/
  195. bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
  196. {
  197.    uchar i;

  198.    Start_I2c();               /*啟動(dòng)總線*/
  199.    SendByte(sla);            /*發(fā)送器件地址*/
  200.      if(ack==0)return(0);
  201.    SendByte(suba);            /*發(fā)送器件子地址*/
  202.      if(ack==0)return(0);

  203.    for(i=0;i<no;i++)
  204.     {   
  205.      SendByte(*s);               /*發(fā)送數(shù)據(jù)*/
  206.        if(ack==0)return(0);
  207.      s++;
  208.     }
  209. Stop_I2c();                 /*結(jié)束總線*/
  210.   return(1);
  211. }






  212. /*******************************************************************
  213.                     向無子地址器件讀字節(jié)數(shù)據(jù)函數(shù)               
  214. 函數(shù)原型: bit  IRcvByte(uchar sla,ucahr *c);  
  215. 功能:     從啟動(dòng)總線到發(fā)送地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件地
  216.           址sla,返回值在c.
  217.            如果返回1表示操作成功,否則操作有誤。
  218. 注意:    使用前必須已結(jié)束總線。
  219. ********************************************************************/
  220. bit IRcvByte(uchar sla,uchar *c)
  221. {
  222.    Start_I2c();                /*啟動(dòng)總線*/
  223.    SendByte(sla+1);           /*發(fā)送器件地址*/
  224.      if(ack==0)return(0);
  225.    *c=RcvByte();               /*讀取數(shù)據(jù)*/
  226.      Ack_I2c(1);               /*發(fā)送非就答位*/
  227.   Stop_I2c();                  /*結(jié)束總線*/
  228.   return(1);
  229. }



  230. /*******************************************************************
  231.                     向有子地址器件讀取多字節(jié)數(shù)據(jù)函數(shù)               
  232. 函數(shù)原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
  233. 功能:     從啟動(dòng)總線到發(fā)送地址,子地址,讀數(shù)據(jù),結(jié)束總線的全過程,從器件
  234.           地址sla,子地址suba,讀出的內(nèi)容放入s指向的存儲(chǔ)區(qū),讀no個(gè)字節(jié)。
  235.            如果返回1表示操作成功,否則操作有誤。
  236. 注意:    使用前必須已結(jié)束總線。
  237. ********************************************************************/
  238. bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
  239. ……………………

  240. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:250287 發(fā)表于 2018-6-24 21:06 | 只看該作者
感謝!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表