新手上路
- 积分
- 33
- 金钱
- 33
- 注册时间
- 2020-5-14
- 在线时间
- 11 小时
|
5金钱
真的十分困扰,我自以为对IIC时序非常理解,在初始化MPU6050函数里面加入了返回值,如果得到了正确的MPU6050地址,则控制LED1亮起来,可是无论如何都不行.希望大神能给看看是哪里有问题,如果能成功解决问题,小弟愿意奉上红包表示感谢 //延时函数
void IIC_Delay(void)
{
delay_us(2);
}
//初始化IO口
void SIMIIC_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitS;
GPIO_InitS.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitS.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitS.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitS);
GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);
}
//IIC 起始和结束
void IIC_Start(void)
{
IIC_SDA_OUT();
IIC_SCL = 1;
IIC_SDA_WRITE = 1;
IIC_Delay();
IIC_SDA_WRITE = 0;
IIC_Delay();
IIC_SCL = 0;
}
void IIC_Stop(void)
{
IIC_SDA_OUT();
IIC_SCL = 0;
IIC_SDA_WRITE = 0;
IIC_Delay();
IIC_SCL = 1;
IIC_SDA_WRITE = 1;
IIC_Delay();
}
//主机应答
void IIC_ACK(void)
{
IIC_SDA_OUT();
IIC_SCL = 0;
IIC_SDA_WRITE = 0;
IIC_Delay();
IIC_SCL = 1;
IIC_Delay();
IIC_SCL = 0;
}
//不产生应答信号
void IIC_NAck(void)
{
IIC_SDA_OUT();
IIC_SCL = 0;
IIC_SDA_WRITE = 1;
IIC_Delay();
IIC_SCL = 1;
IIC_Delay();
IIC_SCL = 0;
}
//1:从机应答 0:从机无应答 直接停止
u8 Wait_ACK(void)
{
u8 ack_time;
IIC_SDA_IN();
IIC_Delay();
IIC_SCL = 1;
IIC_Delay();
while(IIC_SDA_READ)
{
ack_time++;
if(ack_time > 250)
{
IIC_SCL = 0;
IIC_Stop();
return 0;
}
}
IIC_SCL = 0;
return 1;
}
发送一个字节
void IIC_Send_Byte(u8 txd)
{
u8 t;
IIC_SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA_WRITE=(txd&0x80)>>7;
txd<<=1;
IIC_SCL=1;
IIC_Delay();
IIC_SCL=0;
IIC_Delay();
}
}
//读取并发送ACK或Nack;
//1:发送ACK 0:发送NAK;
u8 IIC_Read_Byte(u8 a)
{
unsigned char i,receive=0;
IIC_SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
IIC_Delay();
IIC_SCL=1;
receive<<=1;
if(IIC_SDA_READ)receive++;
IIC_Delay();
}
if (!a)
IIC_NAck();//发送nACK
else
IIC_ACK(); //发送ACK
return receive;
}
以下是MPU初始化程序
u8 MPU6050_Init(void)
{
u8 addr;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitTypeDef GPIO_InitS;
GPIO_InitS.GPIO_Pin = GPIO_Pin_15;
GPIO_InitS.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitS.GPIO_Pin = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitS);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_ResetBits(GPIOA,GPIO_Pin_15);
SIMIIC_Init();
MPU_Send_Byte(MPU_PWR_MGMT1_REG,0x80);
delay_ms(100);
MPU_Send_Byte(MPU_PWR_MGMT1_REG,0X00);
Gyroscope_Init(3);
Accelerometer_Init(0);
SampleRate_Init(50);
MPU_Send_Byte(MPU_INT_EN_REG,0X00);
MPU_Send_Byte(MPU_USER_CTRL_REG,0X00);
MPU_Send_Byte(MPU_FIFO_EN_REG,0X00);
MPU_Send_Byte(MPU_INTBP_CFG_REG,0X80);
addr = MPU_Read_Byte(MPU_DEVICE_ID_REG);
if(addr == MPU_ADDR)
{
MPU_Send_Byte(MPU_PWR_MGMT1_REG,0x01);
MPU_Send_Byte(MPU_PWR_MGMT2_REG,0x00);
SampleRate_Init(50);
}
else return 0; //若器件地址和addr不等 则返回0 就是这里得不到正确的地址以至于一直返回0 怎么办啊
return 1;
}
//向MPU某寄存器发送一字节数据 返回0:从机无应答
u8 MPU_Send_Byte(u8 reg_addr,u8 data)
{
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);
if(!Wait_ACK())
{
IIC_Stop();
return 0;
}
IIC_Send_Byte(reg_addr);
Wait_ACK();
IIC_Send_Byte(data);
if(!Wait_ACK())
{
IIC_Stop();
return 0;
}
IIC_Stop();
return 1;
}
//从MPU某寄存器读取数据
u8 MPU_Read_Byte(u8 reg_addr)
{
u8 rec_data = 0;
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);
Wait_ACK();
IIC_Send_Byte(reg_addr);
Wait_ACK();
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|1);
Wait_ACK();
rec_data = IIC_Read_Byte(0);
IIC_Stop();
return rec_data;
}
这程序逻辑清晰,按道理不应该得不到器件地址吧,求大神指点
|
-
最佳答案
查看完整内容[请看2#楼]
淦 我debug出来自己的问题了 还是代码写的不够细心 readdata写成senddata了 擦
另外就是这个问题 可以参考一下 正点的代码确实好 但还是可以再完善一下:https://blog.csdn.net/pamzerbhu/article/details/79949684?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_par ...
|