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

STM32F4软件模拟I2C操控UV传感器代码

[复制链接]
阿松松 发布时间:2015-1-5 14:24
硬件I2C调不通啊调不通,纠结中,可是不能放弃啊,先搞通软件模拟的再说,其他的,慢慢来
坛子里面有没有硬件I2C用起来没问题的,我的硬件I2C发送了Start和从机Device地址后SDA和SCL线上就不出信号了,郁闷。

分析模拟I2C代码
  1. /*******************************************************************************
  2.   * Copyright(C),2014
  3.   * @file Name  user_i2c.h   
  4.   * @author  chansane
  5.   * @version V2.0.0
  6.   * @date   09-12-2014  
  7.   * @brief  In this file we use the ImitateI2C to read the data of UV_Ambient
  8.     Sensor ,after read all the data we send data using USART3.
  9.     You must known that we turn on the pinmap of USART3.
  10.   * @History
  11. *******************************************************************************/
  12. #include "stm32f4xx.h"
  13. #include "user_i2c.h"
  14. //===============================================================================
  15. //GPIO 模拟I2C ,操作UV_Ambient sensor

  16. /**
  17.   * @brief  Initializes peripherals used by the I2C Periph driver.
  18.   * @param  None
  19.   * @retval None
  20.   */
  21. void I2C_HighLevel_Init(void)
  22. {
  23. //  I2C_LowLevel_DeInit();
  24.   
  25.   I2C_LowLevel_Init();

  26. }

  27. /**
  28.   * @brief  Initializes peripherals used by the I2C Periph driver.
  29.   * @param  None
  30.   * @retval None
  31.   */
  32. void I2C_LowLevel_Init(void)
  33. {
  34.   GPIO_InitTypeDef  GPIO_InitStructure;
  35.    
  36.   /*!< GPIO_CLK Periph clock enable */
  37.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  38.   /*!< GPIO configuration */  
  39.   /*!< Configure I2C pins: SCL */
  40. //  GPIO_StructInit(&GPIO_InitStructure);
  41.   GPIO_InitStructure.GPIO_Pin = Uv_SCL;
  42.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  43.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  44.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  45.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  46.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  47.   GPIO_SetBits( GPIOB, Uv_SCL );

  48.   /*!< Configure I2C pins: SDA */
  49.   GPIO_InitStructure.GPIO_Pin = Uv_SDA;
  50.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  51.   GPIO_SetBits( GPIOB, Uv_SDA );
  52. }


  53. static void DelayMs(uint8_t uc)
  54. {
  55.         uint8_t        i, j;

  56.         for (i=0; i<uc; i++) {
  57.                 for (j=0; j<I2C_DELAY; j++);
  58.         }
  59. }
  60. /*************************************************************
  61. *函数名称:I2CStart
  62. *函数功能:I2C开始信号
  63. *输入参数:
  64. *输出参数:
  65. *备           注:时钟线高时,数据线由高到低的跳变,表示I2C开始信号
  66. **************************************************************/
  67. void I2CStart( void )
  68. {
  69.   GPIO_SetBits( GPIOB, Uv_SDA );
  70.   DelayMs(1);
  71.   GPIO_SetBits( GPIOB, Uv_SCL );
  72.   DelayMs(1);
  73.   GPIO_ResetBits( GPIOB, Uv_SDA );
  74.   DelayMs(1);

  75.   GPIO_ResetBits( GPIOB, Uv_SCL );
  76. }

  77. /*************************************************************
  78. *函数名称:I2CStop
  79. *函数功能:I2C停止信号
  80. *输入参数:
  81. *输出参数:
  82. *备           注:时钟线高时,数据线由低到高的跳变,表示I2C停止信号
  83. **************************************************************/
  84. void I2CStop( void )
  85. {
  86.   GPIO_ResetBits( GPIOB, Uv_SDA );
  87.   DelayMs(1);
  88.   GPIO_SetBits( GPIOB, Uv_SCL );
  89.   DelayMs(1);
  90.   GPIO_SetBits( GPIOB, Uv_SDA );
  91.   DelayMs(1);

  92.   GPIO_ResetBits( GPIOB, Uv_SCL );
  93. }

  94. /*************************************************************
  95. *函数名称:I2CSlaveAck
  96. *函数功能:I2C从机设备应答查询
  97. *输入参数:
  98. *输出参数:
  99. *备           注:
  100. **************************************************************/
  101. unsigned char I2CSlaveAck( void )
  102. {
  103.   GPIO_InitTypeDef GPIO_InitStruct;
  104.   unsigned int TimeOut;
  105.   unsigned char RetValue;

  106.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;  /*这里一定要设成输入上拉,否则不能读出数据*/
  107.   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  108.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  109.   GPIO_InitStruct.GPIO_Pin = Uv_SDA;
  110.   GPIO_Init( GPIOB, &GPIO_InitStruct );

  111.   GPIO_SetBits( GPIOB, Uv_SCL );
  112.   TimeOut = 10000;
  113.   while( TimeOut-- > 0 )
  114.   {
  115.     if( SET == GPIO_ReadInputDataBit( GPIOB, Uv_SDA ) )
  116.     {
  117.       RetValue = RESET;
  118.       break;
  119.     }
  120.     else
  121.     {
  122.       RetValue = SET;
  123.     }
  124.   }
  125.   GPIO_ResetBits( GPIOB, Uv_SCL );
  126.    
  127.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  128.   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  129.   
  130.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  131.   return RetValue;
  132. }

  133. /*************************************************************
  134. *函数名称:I2CWriteByte
  135. *函数功能:I2C写一字节数据
  136. *输入参数:
  137. *输出参数:
  138. *备           注:
  139. **************************************************************/
  140. void I2CWriteByte( unsigned char byte )
  141. {
  142.   unsigned char i;

  143.   for( i=0; i<8; i++ )
  144.   {
  145.     if( 0X80 & byte )
  146.       GPIO_SetBits( GPIOB, Uv_SDA );
  147.     else
  148.       GPIO_ResetBits( GPIOB, Uv_SDA );
  149.     byte <<= 1;
  150.     DelayMs(1);

  151.     GPIO_SetBits( GPIOB, Uv_SCL );
  152.     DelayMs(1);
  153.     GPIO_ResetBits( GPIOB, Uv_SCL );
  154.     DelayMs(1);
  155.   }
  156. }

  157. /*************************************************************
  158. *函数名称:I2CReadByte
  159. *函数功能:I2C读一字节数据
  160. *输入参数:
  161. *输出参数:
  162. *备           注:
  163. **************************************************************/
  164. unsigned char I2CReadByte( void )
  165. {
  166.   unsigned char i;
  167.   unsigned char ReadValue = 0;
  168.   GPIO_InitTypeDef GPIO_InitStruct;
  169.   unsigned char bit;

  170.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;  /*这里一定要设成输入上拉,否则不能读出数据*/
  171.   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  172.   
  173.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  174.   GPIO_InitStruct.GPIO_Pin = Uv_SDA;
  175.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  176.   for( i=0; i<8; i++ )
  177.   {
  178.     GPIO_SetBits( GPIOB, Uv_SCL );
  179.     DelayMs(1);
  180.     if( SET == GPIO_ReadInputDataBit( GPIOB, Uv_SDA ) )
  181.       bit = 0X01;
  182.     else
  183.       bit = 0x00;
  184.       
  185.     ReadValue = (ReadValue<<1)|bit;
  186.     GPIO_ResetBits( GPIOB, Uv_SCL );
  187.     DelayMs(1);
  188.   }

  189.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  190.   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  191.   
  192.   GPIO_Init( GPIOB, &GPIO_InitStruct );
  193.   return ReadValue;
  194. }

  195. /*************************************************************
  196. *函数名称:UvWriteByte
  197. *函数功能:Uv指定地址写一字节数据
  198. *输入参数:addr  Uv地址 +Reg地址
  199.            data  写入的数据
  200. *输出参数:SET: 写入正常;RESET:写入错误
  201. *备           注:
  202. **************************************************************/
  203. uint8_t UvWriteByte( uint16_t addr, uint8_t data )
  204. {
  205.   //asm("CPSID I");  //关中断
  206.   I2CStart();

  207.   I2CWriteByte( Uv_ADD_WRITE );
  208.   if( RESET == I2CSlaveAck() )
  209.   {
  210.     return RESET;
  211.   } /*
  212.   I2CWriteByte( (addr >> 8) & 0xFF );
  213.   if( RESET == I2CSlaveAck() )
  214.   {
  215.     return RESET;
  216.   } */
  217.   I2CWriteByte( addr & 0xFF);
  218.   if( RESET == I2CSlaveAck() )
  219.   {
  220.     return RESET;
  221.   }
  222.   I2CWriteByte( data );
  223.   if( RESET == I2CSlaveAck() )
  224.   {
  225.     return RESET;
  226.   }
  227.   I2CStop();
  228.   //asm("CPSIE I");  //关中断

  229.   return SET;
  230. }

  231. /*************************************************************
  232. *函数名称:UvReadByte
  233. *函数功能:Uv指定地址读一字节数据
  234. *输入参数:addr  Uv地址
  235. *输出参数:返回读出的数据
  236. *备           注:
  237. **************************************************************/  
  238. uint8_t UvReadByte( unsigned short int addr )
  239. {
  240.   unsigned char ReadValue;

  241.   I2CStart();

  242.   I2CWriteByte( Uv_ADD_WRITE );
  243.   if( RESET == I2CSlaveAck() )
  244.   {
  245.     return RESET;
  246.   }/*
  247.   I2CWriteByte( (addr >> 8) & 0xFF );
  248.   if( RESET == I2CSlaveAck() )
  249.   {
  250.     return RESET;
  251.   }*/
  252.   I2CWriteByte( addr & 0xFF );
  253.   if( RESET == I2CSlaveAck() )
  254.   {
  255.     return RESET;
  256.   }
  257.   I2CStart();
  258.   I2CWriteByte( Uv_ADD_READ );
  259.   if( RESET == I2CSlaveAck() )
  260.   {
  261.     return RESET;
  262.   }
  263.   ReadValue = I2CReadByte();
  264.   I2CStop();

  265.   return ReadValue;   
  266. }
复制代码


收藏 评论2 发布时间:2015-1-5 14:24

举报

2个回答
zhaojunlin123 回答时间:2015-1-5 15:11:49
学习学习了········
kanimal 回答时间:2015-4-27 22:34:00
正在被硬件I2C折磨。。。

所属标签

STM32团队

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


最新内容

相似技术帖

官网相关资源

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