股票

PIC16F873A下的IIC通信及初始化

直接上代码了,测试通过的

iic.h

  1. #ifndef _I2C_H_
  2. #define _I2C_H_
  3. #include & lt; pic.h & gt;
  4. #include “define.h”
  5. /* I2c pin */
  6. #define I2C_SDA     (PORTCbits.RC4)
  7. #define I2C_SCL     (PORTCbits.RC3)
  8. #define I2C_SDA_DIR (TRISCbits.TRISC4)
  9. #define I2C_SCL_DIR (TRISCbits.TRISC3)
  10. /* I2C clock delay time */
  11. #define I2C_DELAY_VALUE 35
  12. /* wait time between two I2C transport */
  13. #define I2C_STOP_WAIT_VALUE 350
  14. /* I2C init */
  15. void I2C_Init();
  16. /* I2C sent data */
  17. uchar I2C_Puts
  18. (
  19.     unsigned char SlaveAddr,
  20.     unsigned int SubAddr,
  21.     unsigned char SubMod,
  22.     uchar *dat,
  23.     unsigned int Size
  24. );
  25. /* I2C receive data */
  26. uchar I2C_Gets
  27. (
  28.     unsigned char SlaveAddr,
  29.     unsigned int SubAddr,
  30.     unsigned char SubMod,
  31.     uchar *dat,
  32.     unsigned int Size
  33. );
  34. #endif /* _I2C_H_ */

引脚是RC3和RC4,时间间隔修改I2C_DELAY_VALUE的数值即可。

iic.c

  1. #include “I2C.h”  
  2.   
  3. /* variable for delay time */  
  4. uchar I2C_Delay_t;  
  5.   
  6. /* delay time function */  
  7. #define I2C_Delay() \  
  8.     { \  
  9.         I2C_Delay_t = (I2C_DELAY_VALUE); \  
  10.         while ( –I2C_Delay_t != 0 ) ; \  
  11.     }  
  12.   
  13.   
  14. /* 
  15.  * Name: I2C_Init() 
  16.  * Function: initiate I2C bus 
  17.  * Description: 
  18.  */  
  19. void I2C_Init()  
  20. {  
  21.     I2C_SCL_DIR = 0;  
  22.     I2C_SCL     = 1;  
  23.     I2C_Delay();  
  24.     I2C_SDA_DIR = 0;  
  25.     I2C_SDA     = 1;  
  26.     I2C_Delay();  
  27. }  
  28.   
  29.   
  30. /* 
  31.  * Name: I2C_Start() 
  32.  * Function: start I2C 
  33.  * Description: SDA changes from high to low while SCL stay high. I2C bus stay busy after the function. 
  34.  */  
  35. void I2C_Start()  
  36. {  
  37.     I2C_SDA = 1;  
  38.     I2C_Delay();  
  39.     I2C_SCL = 1;  
  40.     I2C_Delay();  
  41.     I2C_SDA = 0;  
  42.     I2C_Delay();  
  43.     I2C_SCL = 0;  
  44.     I2C_Delay();  
  45. }  
  46.   
  47.   
  48. /* 
  49.  * Name: I2C_Write(char dat) 
  50.  * Function: sent a byte to the bus 
  51.  * Parameter: dat, the data sent to the bus 
  52.  */  
  53. void I2C_Write( uchar dat )  
  54. {  
  55.     unsigned char t = 8;  
  56.     do  
  57.     {  
  58. /* I2C_SCL = 0; */  
  59.         if ( dat & amp; 0x80 )  
  60.             I2C_SDA = 1;  
  61.         else  
  62.             I2C_SDA = 0;  
  63. /* I2C_SDA = (dat&0x80); */  
  64.         dat < < = 1;  
  65. /* I2C_Delay(); */  
  66.         I2C_SCL = 1;  
  67.         I2C_Delay();  
  68.         I2C_SCL = 0;  
  69.         I2C_Delay();  
  70.     }  
  71.     while ( –t != 0 );  
  72. }  
  73.   
  74.   
  75. /* 
  76.  * Name: I2C_Read() 
  77.  * Function: read a byte form the slave 
  78.  * Return: a byte data 
  79.  */  
  80. uchar I2C_Read()  
  81. {  
  82.     uchar   dat = 0;  
  83.     uchar   t   = 8;  
  84. /* I2C_SDA = 1; // set SDA high before read */  
  85.     I2C_SDA_DIR = 1; /* set SDA pin input */  
  86.     do  
  87.     {  
  88.         I2C_SCL = 1;  
  89.         I2C_Delay();  
  90.         dat < < = 1;  
  91.         if ( I2C_SDA )  
  92.             dat |= 0x01;  
  93.         I2C_SCL = 0;  
  94.         I2C_Delay();  
  95.     }  
  96.     while ( –t != 0 );  
  97. /* I2C_SCL = 0; */  
  98.     I2C_SDA_DIR = 0; /* set SDA pin output */  
  99.     return(dat);  
  100. }  
  101.   
  102.   
  103. /* 
  104.  * Name: I2C_GetAck() 
  105.  * Function: check ack form the slave 
  106.  * Return: 0, get ack 
  107.  * 1, ack error 
  108.  * Description: the slave sent an ACK after every byte. The slave sent an noACK after the last byte. 
  109.  */  
  110. uchar I2C_GetAck()  
  111. {  
  112.     uchar ack;  
  113.     I2C_SDA     = 1;  
  114.     I2C_SDA_DIR = 1; /* set SDA pin input */  
  115.     I2C_Delay();  
  116.     I2C_SCL = 1;  
  117.     I2C_Delay();  
  118.   
  119.   
  120. /* 
  121.  * for(ack=0; ack<255; ack++) 
  122.  * { // waiting for SDA get down 
  123.  * if(I2C_SDA) 
  124.  * continue; 
  125.  * }*/  
  126.     ack = I2C_SDA;  
  127. /* I2C_Delay(); */  
  128.     I2C_SCL     = 0;  
  129.     I2C_SDA_DIR = 0; /* set SDA pin output */  
  130.     I2C_Delay();  
  131.   
  132.   
  133. /* 
  134.  * if(255 == ack) 
  135.  * return 1; 
  136.  */  
  137.     return(ack);  
  138. }  
  139.   
  140.   
  141. /* 
  142.  * Name: I2C_PutAck() 
  143.  * Function: sent ack or noack to the slave 
  144.  * Return: 0, get ack 
  145.  * 1, ack error 
  146.  * Description: the slave sent an ACK after every byte. The slave sent an noACK after the last byte. 
  147.  */  
  148. void I2C_PutAck( uchar ack )  
  149. {  
  150.     I2C_SDA = ack;  
  151.     I2C_Delay();  
  152.     I2C_SCL = 1;  
  153.     I2C_Delay();  
  154.     I2C_SCL = 0;  
  155.     I2C_Delay();  
  156. }  
  157.   
  158.   
  159. /* 
  160.  * Name: I2C_Stop() 
  161.  * Function: stop the bus 
  162.  * Description: SDA changes from low to high while SCL stays high will stop the bus. 
  163.  */  
  164. void I2C_Stop()  
  165. {  
  166.     unsigned int t = I2C_STOP_WAIT_VALUE;  
  167.     I2C_SDA = 0;  
  168.     I2C_Delay();  
  169.     I2C_SCL = 1;  
  170.     I2C_Delay();  
  171.     I2C_SDA = 1;  
  172.     I2C_Delay();  
  173.     while ( –t != 0 )  
  174.         ;  /* need delay between stop and next start */  
  175. }  
  176.   
  177.   
  178. /* 
  179.  * Name: I2C_Puts() 
  180.  * Function: sent serial dates to the slave 
  181.  * Parameter: SlaveAddr, address of the slave (no R/W bit) 
  182.  * SubAddr: child address of the slave 
  183.  * SubMod: mode of child address.0-no child address, 1-a byte child address, 2-two bytes child address. 
  184.  * *dat: the data to sent 
  185.  * Size: the length of datas 
  186.  * Return: 0, sent successfully 
  187.  * 1, error 
  188.  * Description: SubAddr can be any number if the slave has no child address while SubMod should be zero. 
  189.  */  
  190. uchar I2C_Puts(  
  191.     unsigned char SlaveAddr,  
  192.     unsigned int SubAddr,  
  193.     unsigned char SubMod,  
  194.     uchar *dat,  
  195.     unsigned int Size  
  196.     )  
  197. {  
  198.     unsigned char   i;  
  199.     uchar       a[3];  
  200. /* check size */  
  201.     if ( 0 == Size )  
  202.         return(0);  
  203. /* address for the slave */  
  204.     a[0] = (SlaveAddr & lt; < 1);  
  205. /* check the mode of child address */  
  206.     if ( SubMod & gt; 2 )  
  207.         SubMod = 2;  
  208. /* check the child address */  
  209.     switch ( SubMod )  
  210.     {  
  211.     case 0:  
  212.         break;  
  213.     case 1:  
  214.         a[1] = (char) (SubAddr);  
  215.         break;  
  216.     case 2:  
  217.         a[1]    = (char) (SubAddr & gt; > 8);  
  218.         a[2]    = (char) (SubAddr);  
  219.         break;  
  220.   
  221.     default:  
  222.         break;  
  223.     }  
  224. /* sent address of the slave. */  
  225.     SubMod++;  
  226.     I2C_Start();  
  227.     for ( i = 0; i < SubMod; i++ )  
  228.     {  
  229.         I2C_Write( a[i] );  
  230.         if ( I2C_GetAck() )  
  231.         {  
  232.             I2C_Stop();  
  233. /* PORTBbits.RB6 = 1; */  
  234.             return(1);  
  235.         }  
  236.     }  
  237. /* sent datas */  
  238.     do  
  239.     {  
  240.         I2C_Write( *dat++ );  
  241.         if ( I2C_GetAck() )  
  242.             break;  
  243.     }  
  244.     while ( –Size != 0 );  
  245. /* stop the bus after sent all datas */  
  246.     I2C_Stop();  
  247.     if ( Size == 0 )  
  248.     {  
  249.         return(0);  
  250.     }else  {  
  251.         return(1);  
  252.     }  
  253. }  
  254.   
  255.   
  256. /* 
  257.  * Name: I2C_Gets() 
  258.  * Function: receive datas from the slave 
  259.  * Parameters: SlaveAddr, address of the slave (no R/W bit) 
  260.  * SbuAddr, child address of the slave 
  261.  * SubMod, the mode of the child address. 0-no child address, 1-one byte child address, 2-double bytes child address 
  262.  * *dat, the datas received 
  263.  * Size, the length of datas 
  264.  * Return: 0, receive successful 
  265.  * 1, error 
  266.  * Description: SubAddr can be any number if the slave has no child address while SubMod should be zero. 
  267.  */  
  268. uchar I2C_Gets(  
  269.     unsigned char SlaveAddr,  
  270.     unsigned int SubAddr,  
  271.     unsigned char SubMod,  
  272.     uchar *dat,  
  273.     unsigned int Size  
  274.     )  
  275. {  
  276.     uchar   i;  
  277.     uchar   a[3];  
  278. /* check the length */  
  279.     if ( 0 == Size )  
  280.         return(0);  
  281. /* get address of the slave */  
  282.     a[0] = (SlaveAddr & lt; < 1);  
  283. /* check the mode of child address */  
  284.     if ( SubMod & gt; 2 )  
  285.         SubMod = 2;  
  286.   
  287. /* sent address of the slave and child address if the slave has child address */  
  288.     if ( SubMod != 0 )  
  289.     {  
  290. /* check child address */  
  291.         if ( 1 == SubMod )  
  292.         {  
  293.             a[1] = (uchar) (SubAddr);  
  294.         }else  {  
  295.             a[1]    = (uchar) (SubAddr & gt; > 8);  
  296.             a[2]    = (uchar) (SubAddr);  
  297.         }  
  298. /* sent address of the slave first, then sent child address */  
  299.         SubMod++;  
  300.         I2C_Start();  
  301.         for ( i = 0; i < SubMod; i++ )  
  302.         {  
  303.             I2C_Write( a[i] );  
  304.             if ( I2C_GetAck() )  
  305.             {  
  306.                 I2C_Stop();  
  307. /* PORTBbits.RB6 = 1; */  
  308.                 return(1);  
  309.             }  
  310.         }  
  311.     }  
  312. /* start the bus, whatever the slave has child address */  
  313.     I2C_Start();  
  314.     I2C_Write( a[0] + 1 );  
  315.     if ( I2C_GetAck() )  
  316.     {  
  317.         I2C_Stop();  
  318.         return(1);  
  319.     }  
  320. /* receive datas */  
  321.     for (;; )  
  322.     {  
  323.         *dat++ = I2C_Read();  
  324.         if ( –Size == 0 )  
  325.         {  
  326.             I2C_PutAck( 1 );  
  327.             break;  
  328.         }  
  329.         I2C_PutAck( 0 );  
  330.     }  
  331. /* receive over, stop the bus */  
  332.     I2C_Stop();  
  333.     return(0);  
  334. }  
打赏
原文链接:,转发请注明来源!

发表评论