STM32下模拟I2C的C语言实现

来源:互联网 发布:美国对外投资数据 编辑:程序博客网 时间:2024/06/06 11:01
  1. #include "stm32f10x_lib.h"  
  2.   
  3. //条件编译 1:使用软件模拟I2C  
  4. //#define PIN_SCL   GPIO_Pin_6  
  5. //#define PIN_SDA   GPIO_Pin_7  
  6.   
  7.   
  8. static __inline void TWI_SCL_0(void)        { GPIOB->BRR=PIN_SCL; }  
  9. static __inline void TWI_SCL_1(void)        { GPIOB->BSRR=PIN_SCL;}  
  10. static __inline void TWI_SDA_0(void)        { GPIOB->BRR=PIN_SDA; }  
  11. static __inline void TWI_SDA_1(void)        { GPIOB->BSRR=PIN_SDA;}  
  12. static __inline u8   TWI_SDA_STATE(void)        { return (GPIOB->IDR & PIN_SDA) != 0; }  
  13. //static __inline void TWI_NOP(void)        {  TWI_Delay(); }  
  14.   
  15. static const u8 TWI_ACK     =0;  
  16. static const u8 TWI_READY   =0;  
  17. static const u8 TWI_NACK    =1;  
  18. static const u8 TWI_BUS_BUSY    =2;  
  19. static const u8 TWI_BUS_ERROR   =3;  
  20.   
  21. static const u8  TWI_RETRY_COUNT = 3; //重试次数  
  22.   
  23. extern void Delay_mS(u32 n);  
  24.   
  25. static void TWI_Initialize(void);  
  26. static u8 TWI_START(void);  
  27. static u8 TWI_START_SHT(void);  
  28. static void TWI_STOP(void);  
  29. static u8  TWI_SendByte(u8 Data);  
  30. static u8 TWI_ReceiveByte(void);  
  31. static void TWI_SendACK(void);  
  32. static void TWI_SendNACK(void);  
  33.   
  34.   
  35. /******************************************************************************* 
  36.  * 函数名称:TWI_Delay                                                                      
  37.  * 描    述:延时函数                                                                      
  38.  *                                                                                
  39.  * 输    入:无                                                                      
  40.  * 输    出:无                                                                      
  41.  * 返    回:无                                                                      
  42.  * 作    者:                                                                      
  43.  * 修改日期:2010年6月8日                                                                     
  44.  *******************************************************************************/  
  45. static void TWI_NOP(void)  
  46. {  
  47.  vu32 i, j;  
  48.  vu32 sum = 0;  
  49.  i = 20;  
  50.  while(i--)  
  51.  {  
  52.      for (j = 0; j < 10; j++)  
  53.      sum += i;   
  54.  }  
  55.  sum = i;  
  56. }  
  57.   
  58. /******************************************************************************* 
  59.  * 函数名称:TWI_Initialize                                                                      
  60.  * 描    述:I2C初始化函数                                                                      
  61.  *                                                                                
  62.  * 输    入:无                                                                      
  63.  * 输    出:无                                                                      
  64.  * 返    回:无                                                                      
  65.  * 作    者:                                                                      
  66.  * 修改日期:2010年6月8日                                                                     
  67.  *******************************************************************************/  
  68. static void TWI_Initialize(void)  
  69. {  
  70.   GPIO_InitTypeDef GPIO_InitStructure;  
  71.   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  
  72.   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;  
  73.   
  74.   GPIO_InitStructure.GPIO_Pin = PIN_SDA;  
  75.   GPIO_Init(GPIOB, &GPIO_InitStructure);  
  76.   
  77.   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  
  78.   GPIO_InitStructure.GPIO_Pin = PIN_SCL;  
  79.   GPIO_Init(GPIOB, &GPIO_InitStructure);  
  80.     
  81.   TWI_SDA_1();  
  82.   TWI_SCL_0();   
  83.     
  84.   //////DebugPrint("Software TWI Initializing...\n");   
  85. }  
  86.   
  87. /******************************************************************************* 
  88.  * 函数名称:TWI_START                                                                      
  89.  * 描    述:发送启动                                                                      
  90.  *                                                                                
  91.  * 输    入:无                                                                      
  92.  * 输    出:无                                                                      
  93.  * 返    回:无                                                                      
  94.  * 作    者:                                                                      
  95.  * 修改日期:2010年6月8日                                                                     
  96.  *******************************************************************************/  
  97. static u8 TWI_START(void)  
  98. {   
  99.  TWI_SDA_1();   
  100.  TWI_NOP();  
  101.      
  102.  TWI_SCL_1();   
  103.  TWI_NOP();      
  104.   
  105.  if(!TWI_SDA_STATE())  
  106.  {  
  107.   ////DebugPrint("TWI_START:BUSY\n");  
  108.   return TWI_BUS_BUSY;  
  109.  }  
  110.  TWI_SDA_0();  
  111.  TWI_NOP();  
  112.     
  113.  TWI_SCL_0();    
  114.  TWI_NOP();   
  115.   
  116.  if(TWI_SDA_STATE())  
  117.  {  
  118.   ////DebugPrint("TWI_START:BUS ERROR\n");  
  119.   return TWI_BUS_ERROR;  
  120.  }   
  121.    
  122.  return TWI_READY;  
  123. }  
  124.   
  125. /* --------------------------------------------------------------------------*/  
  126. /**  
  127.  * @Brief:  TWI_START_SHT  
  128.  *  
  129.  * @Returns:    
  130.  */  
  131. /* --------------------------------------------------------------------------*/  
  132. static u8 TWI_START_SHT(void)  
  133. {  
  134.     TWI_SDA_1();  
  135.     TWI_SCL_0();  
  136.     TWI_NOP();  
  137.   
  138.     TWI_SDA_1();   
  139.     TWI_SCL_1();   
  140.     TWI_NOP();  
  141.   
  142.     if(!TWI_SDA_STATE())  
  143.     {  
  144.         return TWI_BUS_BUSY;  
  145.     }  
  146.     TWI_SDA_0();  
  147.     TWI_NOP();  
  148.   
  149.     TWI_SCL_0();    
  150.     TWI_NOP();   
  151.   
  152.     TWI_SCL_1();  
  153.     TWI_NOP();  
  154.   
  155.     TWI_SDA_1();  
  156.     TWI_NOP();  
  157.   
  158.     TWI_SCL_0();  
  159.     TWI_NOP();  
  160.   
  161.     return TWI_READY;  
  162. }  
  163.   
  164. /* --------------------------------------------------------------------------*/  
  165. /**  
  166.  * @Brief:  TWI_STOP  
  167.  */  
  168. /* --------------------------------------------------------------------------*/  
  169. static void TWI_STOP(void)  
  170. {  
  171.  TWI_SDA_0();   
  172.  TWI_NOP();  
  173.      
  174.  TWI_SCL_1();   
  175.  TWI_NOP();      
  176.   
  177.  TWI_SDA_1();  
  178.  TWI_NOP();  
  179.     
  180.  //////DebugPrint("TWI_STOP\n");     
  181. }  
  182.   
  183. /* --------------------------------------------------------------------------*/  
  184. /**  
  185.  * @Brief:  TWI_SendACK  
  186.  */  
  187. /* --------------------------------------------------------------------------*/  
  188. static void TWI_SendACK(void)  
  189. {  
  190.  TWI_SDA_0();  
  191.  TWI_NOP();  
  192.  TWI_SCL_1();  
  193.  TWI_NOP();  
  194.  TWI_SCL_0();   
  195.  TWI_NOP();   
  196.  TWI_SDA_1();  
  197.  //////DebugPrint("TWI_SendACK\n");     
  198. }  
  199.   
  200. /* --------------------------------------------------------------------------*/  
  201. /**  
  202.  * @Brief:  TWI_SendNACK  
  203.  */  
  204. /* --------------------------------------------------------------------------*/  
  205. static void TWI_SendNACK(void)  
  206. {  
  207.  TWI_SDA_1();  
  208.  TWI_NOP();  
  209.  TWI_SCL_1();  
  210.  TWI_NOP();  
  211.  TWI_SCL_0();   
  212.  TWI_NOP();  
  213.  //////DebugPrint("TWI_SendNACK\n");      
  214. }  
  215.   
  216. /* --------------------------------------------------------------------------*/  
  217. /**  
  218.  * @Brief:  TWI_SendByte  
  219.  *  
  220.  * @Param: Data 
  221.  *  
  222.  * @Returns:    
  223.  */  
  224. /* --------------------------------------------------------------------------*/  
  225. static u8 TWI_SendByte(u8 Data)  
  226. {  
  227.  u8 i;  
  228.  TWI_SCL_0();  
  229.  for(i=0;i<8;i++)  
  230.  {    
  231.   //---------数据建立----------  
  232.   if(Data&0x80)  
  233.   {  
  234.    TWI_SDA_1();  
  235.   }  
  236.   else  
  237.   {  
  238.    TWI_SDA_0();  
  239.   }   
  240.   Data<<=1;  
  241.   TWI_NOP();  
  242.   //---数据建立保持一定延时----  
  243.     
  244.   //----产生一个上升沿[正脉冲]   
  245.   TWI_SCL_1();  
  246.   TWI_NOP();  
  247.   TWI_SCL_0();  
  248.   TWI_NOP();//延时,防止SCL还没变成低时改变SDA,从而产生START/STOP信号  
  249.   //---------------------------     
  250.  }  
  251.  //接收从机的应答   
  252.  TWI_SDA_1();   
  253.  TWI_NOP();  
  254.  TWI_SCL_1();  
  255.  TWI_NOP();     
  256.  if(TWI_SDA_STATE())  
  257.  {  
  258.   TWI_SCL_0();  
  259.   TWI_SDA_1();  
  260.   //////DebugPrint("TWI_NACK!\n");  
  261.   return TWI_NACK;  
  262.  }  
  263.  else  
  264.  {  
  265.   TWI_SCL_0();  
  266.   TWI_SDA_1();  
  267.   //////DebugPrint("TWI_ACK!\n");  
  268.   return TWI_ACK;    
  269.  }      
  270. }  
  271.   
  272. /* --------------------------------------------------------------------------*/  
  273. /**  
  274.  * @Brief:  TWI_ReceiveByte  
  275.  *  
  276.  * @Returns:    
  277.  */  
  278. /* --------------------------------------------------------------------------*/  
  279. static u8 TWI_ReceiveByte(void)  
  280. {  
  281.  u8 i,Dat;  
  282.  TWI_SDA_1();  
  283.  TWI_SCL_0();   
  284.  Dat=0;  
  285.  for(i=0;i<8;i++)  
  286.  {  
  287.   TWI_SCL_1();//产生时钟上升沿[正脉冲],让从机准备好数据   
  288.   TWI_NOP();   
  289.   Dat<<=1;  
  290.   if(TWI_SDA_STATE()) //读引脚状态  
  291.   {  
  292.    Dat|=0x01;   
  293.   }     
  294.   TWI_SCL_0();//准备好再次接收数据    
  295.   TWI_NOP();//等待数据准备好           
  296.  }  
  297.  //////DebugPrint("TWI_Dat:%x\n",Dat);  
  298.  return Dat;  
  299. }  


0 0