江科大學(xué)習(xí)筆記 _13.硬件IIC
第一步:配置IIC外設(shè),代替IIC_Init()
第二步:控制外設(shè)電路,實(shí)現(xiàn)指定地址寫(xiě)時(shí)序,替換Write_Reg()
第三步:控制外設(shè)電路,實(shí)現(xiàn)指定地址讀時(shí)序,替換Read_Reg()
?

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);//時(shí)鐘
????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
?
????GPIO_InitTypeDef GPIO_InitStruct;
????GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
????GPIO_InitStruct.GPIO_Pin = IIC_SCL|IIC_SDA;
????GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
????GPIO_Init(IIC_Port,&GPIO_InitStruct);//GPIO配置
????
????I2C_InitTypeDef I2C_InitStruct;
????I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
????I2C_InitStruct.I2C_ClockSpeed = 400000;
????I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
????I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
????I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
????I2C_InitStruct.I2C_OwnAddress1 = 0x00;
????I2C_Init(I2C2,&I2C_InitStruct);//IIC配置
?
????I2C_Cmd(I2C2, ENABLE);
?
?
?
?
?
主機(jī)發(fā)送
?

I2C_GenerateSTART(I2C2,ENABLE);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)?!= SUCCESS) ;
?
????I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
?while(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)!=SUCCESS);
?
????I2C_SendData(I2C2, RegAddress);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING)?!= SUCCESS);
?
????I2C_SendData(I2C2, Data);
?????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)?!= SUCCESS);
?
????I2C_GenerateSTOP(I2C2,ENABLE);
?
?
?
?
?
?
?
?
?
?
?
?
?
主機(jī)接收
?

I2C_GenerateSTART(I2C2,ENABLE);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
?
????I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
?
????I2C_SendData(I2C2, RegAddress);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS);
?
????I2C_GenerateSTART(I2C2,ENABLE);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);
?
????I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);
????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS);
?
????????????I2C_AcknowledgeConfig(I2C2,DISABLE);//只接收一字節(jié)數(shù)據(jù),ACK不給應(yīng)答
????????????I2C_GenerateSTOP(I2C2,ENABLE);
?
????????????while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS);
????????????Data = I2C_ReceiveData(I2C2);
//如果要接收多字節(jié),for循環(huán)這4行,前面兩行接收前面的字節(jié),后兩行接收最后一個(gè)字節(jié)
?
????I2C_AcknowledgeConfig(I2C2,ENABLE);
?
阻塞式等待容易導(dǎo)致程序一直在while循環(huán)中,程序卡死
所以需要對(duì)while等待處理
?
把判斷標(biāo)志位的函數(shù)封裝進(jìn)下面函數(shù)中,加入超時(shí)退出
void MPU6050_WaitEvent(I2C_TypeDef *I2Cx, uint32_t I2C_EVENT)
{
????uint32_t Timeout;
????Timeout = 10000;
?
????while(I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS)
????{
????????Timeout--;
????????if(Timeout == 0)
????????{
????????????//錯(cuò)誤處理操作
????????????break;
????????}
????}
}
?
?
下面是改進(jìn)之后的等待判斷標(biāo)志位
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
????I2C_GenerateSTART(I2C2,ENABLE);
????MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);
?
????I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);
????MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
?
????I2C_SendData(I2C2, RegAddress);
????MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);
?
????I2C_SendData(I2C2, Data);
????MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
?
????I2C_GenerateSTOP(I2C2,ENABLE);
}