在做公司项目的时候,需要用到陀螺仪、加速度、地磁三类传感器,可以知道这三个传感器可以通过IIC总线的方式进行访问,但是中间总是出现各种问题,特别是无法初始化后无法进行启动总线的动作,卡死在查询语句中,经过不断的测试与摸索,终于在网上受到了启发; 下面是我写的一个示例,注意goto语句的用法。 库文件 - <p class="MsoNormal"><span lang="EN-US">#ifndef __HW_IIC_H</span></p>
- <p class="MsoNormal"><span lang="EN-US">#define __HW_IIC_H</span></p>
- <p class="MsoNormal"><span lang="EN-US"> </span></p>
- <p class="MsoNormal"><span lang="EN-US">#include "stm32f10x.h"</span></p>
- <p class="MsoNormal"><span lang="EN-US"> </span></p>
- <p class="MsoNormal"><span lang="EN-US">void I2C_Configuration(void);</span></p>
- <p class="MsoNormal"><span lang="EN-US"> </span></p>
- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t
- I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num);</span></p>
- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t
- I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num);</span></p>
- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_WriteOneByte(I2C_TypeDef
- *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t value);</span></p>
- <p class="MsoNormal"><span lang="EN-US"> </span></p>
- <p class="MsoNormal"><span lang="EN-US">#endif</span></p>
复制代码 源文件 - #include "hw_iic.h"
- #include "stm32f10x_i2c.h"
- #include "stdio.h"
- #include "delay.h"
- /*******************************************************************************
- * Function Name : I2C_Configuration
- * Description :
- * Input : None
- * Output : None
- * Return : None
- * Attention : None
- *******************************************************************************/
-
- void I2C_Configuration(void)
- {
- I2C_InitTypeDef I2C_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);
- /* Configure I2C1 pins: PB10->SCL and PB11->SDA */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- I2C_DeInit(I2C1);
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
- I2C_InitStructure.I2C_OwnAddress1 = 0x30;
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
- I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
- I2C_InitStructure.I2C_ClockSpeed = 400000; //400K全速
-
- I2C_Cmd(I2C1, ENABLE);
- I2C_Init(I2C1, &I2C_InitStructure);
- I2C_AcknowledgeConfig(I2C1, ENABLE);
- }
- /*******************************************************************************
- * Function Name : I2C_delay
- * Description :
- * Input : None
- * Output : None
- * Return : None
- * Attention : None
- *******************************************************************************/
- static void I2C_delay(uint16_t cnt)
- {
- while(cnt--);
- }
- /*******************************************************************************
- * Function Name : I2C_AcknowledgePolling
- * Description :
- * Input : I2C_TypeDef * , uint8_t
- * Output : None
- * Return : None
- * Attention : None
- *******************************************************************************/
- static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)
- {
- vu16 SR1_Tmp;
- do
- {
- I2C_GenerateSTART(I2Cx, ENABLE);
- SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);
- //#ifdef AT24C01A
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
- /*
- #else
- I2C_Send7bitAddress(I2Cx, 0, I2C_Direction_Transmitter);
- #endif
- */
- }while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));
-
- I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
-
- I2C_GenerateSTOP(I2Cx, ENABLE);
- }
- /*******************************************************************************
- * Function Name : I2C_Read
- * Description :
- * Input :
- * Output :
- * Return :
- * Attention : None
- *******************************************************************************/
- uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)
- {
- if(num==0)
- return 1;
-
- while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
-
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
- I2C_GenerateSTART(I2Cx, ENABLE);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
- //#ifdef AT24C01A
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
- while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- I2C_SendData(I2Cx, addr);
- while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
-
- I2C_GenerateSTART(I2Cx, ENABLE);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
-
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- /*
- #else
- I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- #endif
- */
- while (num)
- {
- if(num==1)
- {
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- I2C_GenerateSTOP(I2Cx, ENABLE);
- }
-
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
- *buf = I2C_ReceiveData(I2Cx);
- buf++;
- /* Decrement the read bytes counter */
- num--;
- }
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
- return 0;
- }
- /*******************************************************************************
- * Function Name : I2C_WriteOneByte
- * Description :
- * Input :
- * Output : None
- * Return :
- * Attention : None
- *******************************************************************************/
- uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t value)
- {
- int cnt = 0;
- MY_IIC_START_LABLE:
- I2C_GenerateSTART(I2Cx, ENABLE);
- cnt = 0;
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
- {
- delay_ms(10); //必须延时 否则很容易死机
- // printf("9XX");
-
- if(cnt ++ > 10)
- {
- cnt = 0;
- I2C_Configuration(); //重新进行初始化
- goto MY_IIC_START_LABLE; //跳到本函数的开头
- }
- }
-
-
- //#ifdef AT24C01A
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- I2C_SendData(I2Cx, addr);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- /*
- #else
- I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- #endif
- */
- I2C_SendData(I2Cx, value);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
-
- I2C_GenerateSTOP(I2Cx, ENABLE);
-
- I2C_AcknowledgePolling(I2Cx,I2C_Addr);
- I2C_delay(1000);
- return 0;
- }
- /*******************************************************************************
- * Function Name : I2C_Write
- * Description :
- * Input :
- * Output : None
- * Return :
- * Attention : None
- *******************************************************************************/
- uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)
- {
- uint8_t err=0;
-
- while(num--)
- {
- if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++))
- {
- err++;
- }
- }
- if(err)
- return 1;
- else
- return 0;
- }
复制代码
|
你的程序建议最好通过严格的测试,其实理论上讲,在I2C中,使用这种延时是个最大的隐患,一旦cpu因温度、环境电磁干扰等你的程序就挂了。