硬件I2C调不通啊调不通,纠结中,可是不能放弃啊,先搞通软件模拟的再说,其他的,慢慢来
坛子里面有没有硬件I2C用起来没问题的,我的硬件I2C发送了Start和从机Device地址后SDA和SCL线上就不出信号了,郁闷。
分析模拟I2C代码
- /*******************************************************************************
- * Copyright(C),2014
- * @file Name user_i2c.h
- * @author chansane
- * @version V2.0.0
- * @date 09-12-2014
- * @brief In this file we use the ImitateI2C to read the data of UV_Ambient
- Sensor ,after read all the data we send data using USART3.
- You must known that we turn on the pinmap of USART3.
- * @History
- *******************************************************************************/
- #include "stm32f4xx.h"
- #include "user_i2c.h"
- //===============================================================================
- //GPIO 模拟I2C ,操作UV_Ambient sensor
- /**
- * @brief Initializes peripherals used by the I2C Periph driver.
- * @param None
- * @retval None
- */
- void I2C_HighLevel_Init(void)
- {
- // I2C_LowLevel_DeInit();
-
- I2C_LowLevel_Init();
- }
- /**
- * @brief Initializes peripherals used by the I2C Periph driver.
- * @param None
- * @retval None
- */
- void I2C_LowLevel_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /*!< GPIO_CLK Periph clock enable */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
- /*!< GPIO configuration */
- /*!< Configure I2C pins: SCL */
- // GPIO_StructInit(&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = Uv_SCL;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_SetBits( GPIOB, Uv_SCL );
- /*!< Configure I2C pins: SDA */
- GPIO_InitStructure.GPIO_Pin = Uv_SDA;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_SetBits( GPIOB, Uv_SDA );
- }
- static void DelayMs(uint8_t uc)
- {
- uint8_t i, j;
- for (i=0; i<uc; i++) {
- for (j=0; j<I2C_DELAY; j++);
- }
- }
- /*************************************************************
- *函数名称:I2CStart
- *函数功能:I2C开始信号
- *输入参数:
- *输出参数:
- *备 注:时钟线高时,数据线由高到低的跳变,表示I2C开始信号
- **************************************************************/
- void I2CStart( void )
- {
- GPIO_SetBits( GPIOB, Uv_SDA );
- DelayMs(1);
- GPIO_SetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- GPIO_ResetBits( GPIOB, Uv_SDA );
- DelayMs(1);
- GPIO_ResetBits( GPIOB, Uv_SCL );
- }
- /*************************************************************
- *函数名称:I2CStop
- *函数功能:I2C停止信号
- *输入参数:
- *输出参数:
- *备 注:时钟线高时,数据线由低到高的跳变,表示I2C停止信号
- **************************************************************/
- void I2CStop( void )
- {
- GPIO_ResetBits( GPIOB, Uv_SDA );
- DelayMs(1);
- GPIO_SetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- GPIO_SetBits( GPIOB, Uv_SDA );
- DelayMs(1);
- GPIO_ResetBits( GPIOB, Uv_SCL );
- }
- /*************************************************************
- *函数名称:I2CSlaveAck
- *函数功能:I2C从机设备应答查询
- *输入参数:
- *输出参数:
- *备 注:
- **************************************************************/
- unsigned char I2CSlaveAck( void )
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- unsigned int TimeOut;
- unsigned char RetValue;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; /*这里一定要设成输入上拉,否则不能读出数据*/
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStruct.GPIO_Pin = Uv_SDA;
- GPIO_Init( GPIOB, &GPIO_InitStruct );
- GPIO_SetBits( GPIOB, Uv_SCL );
- TimeOut = 10000;
- while( TimeOut-- > 0 )
- {
- if( SET == GPIO_ReadInputDataBit( GPIOB, Uv_SDA ) )
- {
- RetValue = RESET;
- break;
- }
- else
- {
- RetValue = SET;
- }
- }
- GPIO_ResetBits( GPIOB, Uv_SCL );
-
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
-
- GPIO_Init( GPIOB, &GPIO_InitStruct );
- return RetValue;
- }
- /*************************************************************
- *函数名称:I2CWriteByte
- *函数功能:I2C写一字节数据
- *输入参数:
- *输出参数:
- *备 注:
- **************************************************************/
- void I2CWriteByte( unsigned char byte )
- {
- unsigned char i;
- for( i=0; i<8; i++ )
- {
- if( 0X80 & byte )
- GPIO_SetBits( GPIOB, Uv_SDA );
- else
- GPIO_ResetBits( GPIOB, Uv_SDA );
- byte <<= 1;
- DelayMs(1);
- GPIO_SetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- GPIO_ResetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- }
- }
- /*************************************************************
- *函数名称:I2CReadByte
- *函数功能:I2C读一字节数据
- *输入参数:
- *输出参数:
- *备 注:
- **************************************************************/
- unsigned char I2CReadByte( void )
- {
- unsigned char i;
- unsigned char ReadValue = 0;
- GPIO_InitTypeDef GPIO_InitStruct;
- unsigned char bit;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; /*这里一定要设成输入上拉,否则不能读出数据*/
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
-
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStruct.GPIO_Pin = Uv_SDA;
- GPIO_Init( GPIOB, &GPIO_InitStruct );
- for( i=0; i<8; i++ )
- {
- GPIO_SetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- if( SET == GPIO_ReadInputDataBit( GPIOB, Uv_SDA ) )
- bit = 0X01;
- else
- bit = 0x00;
-
- ReadValue = (ReadValue<<1)|bit;
- GPIO_ResetBits( GPIOB, Uv_SCL );
- DelayMs(1);
- }
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
-
- GPIO_Init( GPIOB, &GPIO_InitStruct );
- return ReadValue;
- }
- /*************************************************************
- *函数名称:UvWriteByte
- *函数功能:Uv指定地址写一字节数据
- *输入参数:addr Uv地址 +Reg地址
- data 写入的数据
- *输出参数:SET: 写入正常;RESET:写入错误
- *备 注:
- **************************************************************/
- uint8_t UvWriteByte( uint16_t addr, uint8_t data )
- {
- //asm("CPSID I"); //关中断
- I2CStart();
- I2CWriteByte( Uv_ADD_WRITE );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- } /*
- I2CWriteByte( (addr >> 8) & 0xFF );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- } */
- I2CWriteByte( addr & 0xFF);
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }
- I2CWriteByte( data );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }
- I2CStop();
- //asm("CPSIE I"); //关中断
- return SET;
- }
- /*************************************************************
- *函数名称:UvReadByte
- *函数功能:Uv指定地址读一字节数据
- *输入参数:addr Uv地址
- *输出参数:返回读出的数据
- *备 注:
- **************************************************************/
- uint8_t UvReadByte( unsigned short int addr )
- {
- unsigned char ReadValue;
- I2CStart();
- I2CWriteByte( Uv_ADD_WRITE );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }/*
- I2CWriteByte( (addr >> 8) & 0xFF );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }*/
- I2CWriteByte( addr & 0xFF );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }
- I2CStart();
- I2CWriteByte( Uv_ADD_READ );
- if( RESET == I2CSlaveAck() )
- {
- return RESET;
- }
- ReadValue = I2CReadByte();
- I2CStop();
- return ReadValue;
- }
复制代码
|