[mw_shl_code=c,true]void Single_Write(unsigned char Slave_Addr,unsigned char Reg_Addr,unsigned char Reg_Data)
{
IIC_Start();
IIC_Send_Byte(Slave_Addr);
IIC_Wait_Ack();//第一次应答 IIC_Send_Byte(Reg_Addr);
IIC_Wait_Ack();//第二次应答 IIC_Send_Byte(Reg_Data);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(5);
}[/mw_shl_code]
[mw_shl_code=c,true]
[mw_shl_code=c,true]
[/mw_shl_code]
[mw_shl_code=c,true]void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(5);
IIC_SCL=1;
delay_us(5);
IIC_SCL=0;
delay_us(5);
}
}[/mw_shl_code]
[/mw_shl_code]
[mw_shl_code=c,true]//等待应答[/mw_shl_code]
[mw_shl_code=c,true]u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN();
IIC_SCL=0;
delay_us(1);
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;
return 0;
}[/mw_shl_code]
第一次IIC_Wait_Ack()应答了,但第二次却没有应答,调试的结果是READ_SDA一直为1,请教各位大婶这是为什么?弄了好几天了。。
IO配置如下
[mw_shl_code=c,true]#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}
#define IIC_SDA PCout(11)
#define IIC_SCL PCout(12)
#define READ_SDA PCin(11)[/mw_shl_code]
[mw_shl_code=c,true]void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
}[/mw_shl_code]
[mw_shl_code=c,true]void mpu9150a_init(void)
{
Single_Write(MPU_9150A_ADDR,PWR_MGMT_1,0x00); //接触休眠模式
Single_Write(MPU_9150A_ADDR,SMPLRT_DIV,0x07); //设置采样系数为7,即采样频率为8kHz/(1+7)=1kHz
Single_Write(MPU_9150A_ADDR,CONFIG,0x06); //设置数字低通滤波器为0x06,Accelerometer和gyroscope的滤波带宽为5Hz
Single_Write(MPU_9150A_ADDR,GYRO_CONFIG,0x18); //设置FS_SEL[1:0]=3,即陀螺仪选择的满量程为± 2000 °/s
Single_Write(MPU_9150A_ADDR,ACCEL_CONFIG,0x01); //设置AFS_SEL[1:0]=0,ACCEL_HPL[2:0]=1,即加速计的满量程为± 2g,高通滤波器为5Hz
}[/mw_shl_code]
这是今天刚用逻辑分析仪得到的SCL和SDA的时序图,图上标注的为我自己的理解。
就是void mpu9150a_init(void)里面的第一个函数 Single_Write(MPU_9150A_ADDR,PWR_MGMT_1,0x00); //接触休眠模式
所得到的时序图。。
|