为什么我的stm32 I2C通信读陀螺仪的寄存器读出来的数据是0xFF,求大神指导(代码贴出来了)

2019-07-20 04:00发布

[mw_shl_code=c,true] [mw_shl_code=c,true]#ifndef __LED_H #define __LED_H #include "sys.h" //Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //2010/5/27 //LED端口定义 #define SDA PBout(7)// PA8 #define SCL PBout(6)// PA7 #define LED2 PAout(6)// PA6 #define LED3 PAout(5)// PA5 #define LED4 PDout(2)// PA5 void LED_Init(void);//初始化 #define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读) //地址 #define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz) #define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz) #define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) #define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用) ;sleep,z轴 #define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读) #define SlaveAddress 0x68 //IIC写入时的地址字节数据,+1为读取 #endif[/mw_shl_code]
[mw_shl_code=c,true]#include <stm32f10x_lib.h> #include "led.h" #include "delay.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //Mini STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2010/5/27 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 正点原子 2009-2019 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //初始化PA8和PD2为输出口.并使能这两个口的时钟 //LED IO初始化 void LED_Init(void) { RCC->APB2ENR|=1<<2; //使能PORTA时钟 RCC->APB2ENR|=1<<5; //使能PORTD时钟 RCC->APB2ENR|=1<<3; //使能PORTB时钟 GPIOA->CRH&=0XFFFFFFF0; GPIOA->CRH|=0X00000003;//PA8 推挽输出 GPIOA->ODR|=1<<8; //PA8 输出高 GPIOA->CRL&=0X0FFFFFFF; GPIOA->CRL|=0X30000000;//PA7 推挽输出 GPIOA->ODR|=1<<7; //PA7 输出高 GPIOA->CRL&=0XF0FFFFFF; GPIOA->CRL|=0X03000000;//PA6 推挽输出 GPIOA->ODR|=1<<6; //PA6 输出高 GPIOA->CRL&=0XFF0FFFFF; GPIOA->CRL|=0X00300000;//PA5 推挽输出 GPIOA->ODR|=1<<5; //PA5 输出高 GPIOD->CRL&=0XFFFFF0FF; GPIOD->CRL|=0X00000300;//PD2推挽输出 GPIOD->ODR|=1<<2; //PD2输出高 GPIOB->CRL&=0X0FFFFFFF; GPIOB->CRL|=0X30000000;//PB7 推挽输出 GPIOB->ODR|=1<<7; //PB7 输出高 GPIOB->CRL&=0XF0FFFFFF; GPIOB->CRL|=0X03000000;//PB6 推挽输出 GPIOB->ODR|=1<<6; //PB6 输出高 } //起始信号// void I2C_Start(void) //s { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 //Delay5us(); delay_us(5); //延时 SDA = 0; //产生下降沿,SDA //Delay5us(); delay_us(5); //延时 SCL = 0; //SCL } //停止信号// void I2C_Stop(void) //P { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 //Delay5us(); delay_us(5); //延时 SDA = 1; //产生上升沿 //Delay5us(); delay_us(5); //延时 } //发送应答信号// void I2C_SendAck(bool ACK) { SCL=0; delay_us(5); SDA = ACK; //写应答信号 SCL = 1; //拉高时钟线 //Delay5us(); delay_us(5); //延时 SCL = 0; //拉低时钟线 //Delay5us(); delay_us(5); //延时 } //接收应答信号// bool I2C_ReceiveAck(void) { bool t; SCL = 1; //拉高时钟线 //Delay5us(); delay_us(5); //延时 t= SDA; //读应答信号 SCL = 0; //拉低时钟线 //Delay5us(); delay_us(5); //延时 return t; } //发送字节// void I2C_SendByte(u8 dat) { u8 i,temp,n; u8 num=0x80; for (i=0; i<8; i++) //8位计数器 { //dat <<= 1; //移出数据的最高位,移出最高位?CY为进位? n=7-i; temp=num&dat; temp =temp >> n; SCL = 1; //拉高时钟线 delay_us(5); SDA = temp; //送数据口 //Delay5us(); delay_us(5); //延时 SCL = 0; //拉低时钟线 //Delay5us(); delay_us(5); //延时 num=num>>1; } I2C_ReceiveAck(); } //接收字节// u8 I2C_RecvByte() { u8 i; u8 dat = 0; SCL=0; delay_us(5); SDA = 1; //使能内部上拉,准备读取数据, for (i=0; i<8; i++) //8位计数器 { dat <<= 1; SCL = 1; //拉高时钟线 //Delay5us(); delay_us(5); //延时 dat = dat| SDA; delay_us(5); //读数据 SCL = 0; //拉低时钟线 //Delay5us(); delay_us(5); //延时 } delay_us(5); return dat; } //向I2C设备写入一个字节数据// void Single_WriteI2C(u8 REG_Address,u8 REG_data) { //u8 SlaveAddress=0xD0; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //内部寄存器地址 I2C_SendByte(REG_data); //内部寄存器数据 I2C_Stop(); //发送停止信号 } //从I2C设备读取一个字节数据 u8 Single_ReadI2C(u8 REG_Address) { //u8 SlaveAddress=0xD0; u8 REG_data; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //发送存储单元地址,从0开始 I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号 // LED4= I2C_ReceiveAck(); REG_data=I2C_RecvByte(); //读出寄存器数据 //delay_ms(1000); I2C_SendAck(1); //发送应答信号 I2C_Stop(); //停止信号 return REG_data; } [/mw_shl_code]
[mw_shl_code=c,true]int main(void) { Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 LED2=0; while(1){ u8 temp; LED4=1; //初始化 Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态 Single_WriteI2C(SMPLRT_DIV, 0x07); Single_WriteI2C(CONFIG, 0x06); Single_WriteI2C(GYRO_CONFIG, 0x18); Single_WriteI2C(ACCEL_CONFIG, 0x01); temp=Single_ReadI2C(WHO_AM_I); //temp=I2C_RecvByte() if(temp==0xFF) LED4=0; else LED4=1; delay_ms(1000); //for(i=0;i<8;i++) //{ //t=n&temp; //m=7-i; //LED4=t>>m; //n=n>>1; //delay_ms(1000); //u8 temp=0x68; //u8 n=0x40; //} //bool m=0; //bool n=0; //LED4=m|n; } } [/mw_shl_code]
[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。