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

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