你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

分析一个STM32模拟I2C的代码,亲测可用

[复制链接]
阿松松 发布时间:2015-1-5 14:17
I2C配置顺序引发的异常案例

基于stm32的I2C总线通讯简介及使用操作(附代码)

分享关于STM32f103 的硬件IIC I2C 调试心得


楼主前段时间苦调UV传感器,无奈硬件I2C怎么也用不起来,楼主水平还是太弱,无奈只好转入软件模拟I2C,不过话说模拟I2C的波形似乎要比硬件I2C的要好很多呢。调好的代码与大家分享下。。。源模板是哥们做好的读取E2的代码。
  1. #include "stm32f10x.h"
  2. //===============================================================================
  3. //GPIO 模拟I2C ,操作EP2ROM IC(AT24C02)
  4. #define  E2PROM_SDA  GPIO_Pin_7
  5. #define  E2PROM_SCL  GPIO_Pin_6
  6. #define  E2PROM_CMD_WRITE  0xa0
  7. #define  E2PROM_CMD_READ   0xa1
  8. #define        I2C_DELAY                    254                                                        //

  9. I2C延时

  10. static void
  11. DelayMs(uint8_t uc)
  12. {
  13.         uint8_t        i, j;

  14.         for (i=0; i<uc; i++) {
  15.                 for (j=0; j<I2C_DELAY; j++);
  16.         }
  17. }
  18. /*************************************************************
  19. *函数名称:I2CStart
  20. *函数功能:I2C开始信号
  21. *输入参数:
  22. *输出参数:
  23. *备           注:时钟线高时,数据线由高到低的跳变,表示I2C开始信号
  24. **************************************************************/
  25. void I2CStart( void )
  26. {
  27.   GPIO_SetBits( GPIOB, E2PROM_SDA );
  28.   DelayMs(1);
  29.   GPIO_SetBits( GPIOB, E2PROM_SCL );
  30.   DelayMs(1);
  31.   GPIO_ResetBits( GPIOB, E2PROM_SDA );
  32.   DelayMs(1);

  33.   GPIO_ResetBits( GPIOB, E2PROM_SCL );
  34. }

  35. /*************************************************************
  36. *函数名称:I2CStop
  37. *函数功能:I2C停止信号
  38. *输入参数:
  39. *输出参数:
  40. *备           注:时钟线高时,数据线由低到高的跳变,表示I2C停止信号
  41. **************************************************************/
  42. void I2CStop( void )
  43. {
  44.   GPIO_ResetBits( GPIOB, E2PROM_SDA );
  45.   DelayMs(1);
  46.   GPIO_SetBits( GPIOB, E2PROM_SCL );
  47.   DelayMs(1);
  48.   GPIO_SetBits( GPIOB, E2PROM_SDA );
  49.   DelayMs(1);

  50.   GPIO_ResetBits( GPIOB, E2PROM_SCL );
  51. }

  52. /*************************************************************
  53. *函数名称:I2CSlaveAck
  54. *函数功能:I2C从机设备应答查询
  55. *输入参数:
  56. *输出参数:
  57. *备           注:
  58. **************************************************************/
  59. unsigned char I2CSlaveAck( void )
  60. {
  61.   GPIO_InitTypeDef GPIO_InitStruct;
  62.   unsigned int TimeOut;
  63.   unsigned char RetValue;

  64.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  /*这里一定要设成输入上拉,否则不能读出数据*/
  65.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  66.   GPIO_InitStruct.GPIO_Pin = E2PROM_SDA;
  67.   GPIO_Init( GPIOB, &GPIO_InitStruct );

  68.   GPIO_SetBits( GPIOB, E2PROM_SCL );
  69.   TimeOut = 10000;
  70.   while( TimeOut-- > 0 )
  71.   {
  72.     if( SET == GPIO_ReadInputDataBit( GPIOB, E2PROM_SDA ) )
  73.     {
  74.       RetValue = RESET;
  75.       break;
  76.     }
  77.     else
  78.     {
  79.       RetValue = SET;
  80.     }
  81.   }
  82.   GPIO_ResetBits( GPIOB, E2PROM_SCL );
  83.    
  84.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  85.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  86.   return RetValue;
  87. }

  88. /*************************************************************
  89. *函数名称:I2CWriteByte
  90. *函数功能:I2C写一字节数据
  91. *输入参数:
  92. *输出参数:
  93. *备           注:
  94. **************************************************************/
  95. void I2CWriteByte( unsigned char byte )
  96. {
  97.   unsigned char i;

  98.   for( i=0; i<8; i++ )
  99.   {
  100.     if( 0X80 & byte )
  101.       GPIO_SetBits( GPIOB, E2PROM_SDA );
  102.     else
  103.       GPIO_ResetBits( GPIOB, E2PROM_SDA );
  104.     byte <<= 1;
  105.     DelayMs(1);

  106.     GPIO_SetBits( GPIOB, E2PROM_SCL );
  107.     DelayMs(1);
  108.     GPIO_ResetBits( GPIOB, E2PROM_SCL );
  109.     DelayMs(1);
  110.   }
  111. }

  112. /*************************************************************
  113. *函数名称:I2CReadByte
  114. *函数功能:I2C读一字节数据
  115. *输入参数:
  116. *输出参数:
  117. *备           注:
  118. **************************************************************/
  119. unsigned char I2CReadByte( void )
  120. {
  121.   unsigned char i;
  122.   unsigned char ReadValue = 0;
  123.   GPIO_InitTypeDef GPIO_InitStruct;
  124.   unsigned char bit;

  125.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  /*这里一定要设成输入上拉,否则不能读出数据*/
  126.   GPIO_InitStruct.GPIO_Pin = E2PROM_SDA;
  127.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  128.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  129.   for( i=0; i<8; i++ )
  130.   {
  131.     GPIO_SetBits( GPIOB, E2PROM_SCL );
  132.     DelayMs(1);
  133.     if( SET == GPIO_ReadInputDataBit( GPIOB, E2PROM_SDA ) )
  134.       bit = 0X01;
  135.     else
  136.       bit = 0x00;
  137.       
  138.     ReadValue = (ReadValue<<1)|bit;
  139.     GPIO_ResetBits( GPIOB, E2PROM_SCL );
  140.     DelayMs(1);
  141.   }

  142.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  143.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  144.   return ReadValue;
  145. }

  146. /*************************************************************
  147. *函数名称:E2promWriteByte
  148. *函数功能:E2PROM指定地址写一字节数据
  149. *输入参数:addr  E2PROM地址
  150.                              data  写入的数据
  151. *输出参数:SET: 写入正常;RESET:写入错误
  152. *备           注:
  153. **************************************************************/
  154. uint8_t E2promWriteByte( uint16_t addr, uint8_t data )
  155. {
  156.   //asm("CPSID I");  //关中断
  157.   I2CStart();

  158.   I2CWriteByte( E2PROM_CMD_WRITE );
  159.   if( RESET == I2CSlaveAck() )
  160.   {
  161.     return RESET;
  162.   }/*
  163.   I2CWriteByte( (addr >> 8) & 0xFF );
  164.   if( RESET == I2CSlaveAck() )
  165.   {
  166.     return RESET;
  167.   } */
  168.   I2CWriteByte( addr & 0xFF);
  169.   if( RESET == I2CSlaveAck() )
  170.   {
  171.     return RESET;
  172.   }
  173.   I2CWriteByte( data );
  174.   if( RESET == I2CSlaveAck() )
  175.   {
  176.     return RESET;
  177.   }
  178.   I2CStop();
  179.   //asm("CPSIE I");  //关中断

  180.   return SET;
  181. }

  182. /*************************************************************
  183. *函数名称:E2promReadByte
  184. *函数功能:E2PROM指定地址读一字节数据
  185. *输入参数:addr  E2PROM地址
  186. *输出参数:返回读出的数据
  187. *备           注:
  188. **************************************************************/  
  189. uint8_t E2promReadByte( unsigned short int addr )
  190. {
  191.   unsigned char ReadValue;

  192.   I2CStart();

  193.   I2CWriteByte( E2PROM_CMD_WRITE );
  194.   if( RESET == I2CSlaveAck() )
  195.   {
  196.     return RESET;
  197.   }/*
  198.   I2CWriteByte( (addr >> 8) & 0xFF );
  199.   if( RESET == I2CSlaveAck() )
  200.   {
  201.     return RESET;
  202.   }  */
  203.   I2CWriteByte( addr & 0xFF );
  204.   if( RESET == I2CSlaveAck() )
  205.   {
  206.     return RESET;
  207.   }
  208.   I2CStart();
  209.   I2CWriteByte( E2PROM_CMD_READ );
  210.   if( RESET == I2CSlaveAck() )
  211.   {
  212.     return RESET;
  213.   }
  214.   ReadValue = I2CReadByte();
  215.   I2CStop();

  216.   return ReadValue;   
  217. }
复制代码


收藏 5 评论18 发布时间:2015-1-5 14:17

举报

18个回答
hlt512 回答时间:2015-1-5 15:05:12
好像1系列的,大家都用模拟IIC
阿松松 回答时间:2015-1-5 15:13:25
hlt512 发表于 2015-1-5 15:05
好像1系列的,大家都用模拟IIC

额,我一个4系列的也用的是模拟I2C,硬件的死活不通,记得有人给我说过是有问题,可是我的就是硬硬的不通,怎么破
晓枫VS枯叶 回答时间:2015-1-5 15:22:31
我的F0上的I2C跑了两天两夜没死机(可能是侥幸),F4上的I2C能用但是没测试很长时间!
阿松松 回答时间:2015-1-5 15:33:49
晓枫VS枯叶 发表于 2015-1-5 15:22
我的F0上的I2C跑了两天两夜没死机(可能是侥幸),F4上的I2C能用但是没测试很长时间! ...

F4上的可用?
为什么我的就死活调试不通呢,从器件无法响应?

嗯,分享下经验
我们不能屈从权威
晓枫VS枯叶 回答时间:2015-1-5 15:37:11
阿松松 回答时间:2015-1-5 15:42:40
晓枫VS枯叶 发表于 2015-1-5 15:37
https://www.stmcu.org.cn/module/forum/thread-598153-1-1.html之前发过,你去看看吧!

嗯,十分感谢。。。
以后还是得和大家多交流,不能闭门造车,我那个硬件I2C自己吭哧吭哧搞了半个多月,也没结果
hlt512 回答时间:2015-1-5 16:48:45
阿松松 发表于 2015-1-5 15:13
额,我一个4系列的也用的是模拟I2C,硬件的死活不通,记得有人给我说过是有问题,可是我的就是硬硬的不通 ...

每个人对资料的理解不通,你理解估计有极限
mengqiqq 回答时间:2015-1-8 06:54:35
学习学习,楼主辛苦!
阿松松 回答时间:2015-1-8 16:54:49
hlt512 发表于 2015-1-5 16:48
每个人对资料的理解不通,你理解估计有极限

确实,所以还得仔细揣摩下,到底哪儿出问题了
12下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版