我无法在ARM CORTEX M3进程上使用I2C。 我究竟做错了什么?我可以执行哪个测试来发现问题?
这是GD32F130C8(主版),我正在用KEIL进行编程(使用GD32F1x0固件库)
从站是MPU-6050(加速度计)
我用本地地址和MPU-6050设备定义了变量:
#define I2C_ACCELEROMETER_ADDRESS 0xD0 //( 0x68 + one bit)
#define I2C_OWN_ADDRESS 0x72
然后我以这种方式初始化I2C PIN:
//Init I2C communication to accelerometer
// enable I2C0 clock
rcu_periph_clock_enable(RCU_I2C0);
// connect PB8 to I2C0_SCL
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_8);
// connect PB9 to I2C0_SDA
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_9);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
然后我以这种方式初始化I2C:
void I2C_Accelerometer_init(void){
// configure I2C0 clock
i2c_clock_config(I2C0, 100000, I2C_DTCY_2);
// configure I2C0 address
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS);
// enable I2C0
i2c_enable(I2C0);
// enable acknowledge
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
然后定期(每秒)尝试从加速度计获取数据。 没有错误,但是变量“ accelerometer_x_high”始终为零(这基本上是我的问题)。
每秒执行以下代码。如您所见,我将电源管理设置为0,然后请求向加速度计数据注册,然后尝试从从设备获取数据:
extern uint8_t Accelerometer_X_High;
//periodically called by timers in it.c
void GetAccelerometerData(void){
uint8_t bytesToReadIndex=0;
//WAKE UP ACCELEROMETER (6B 00)
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_TRANSMITTER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// send a data byte
i2c_data_transmit(I2C0,0x6B); //PWR MANAGEMENT
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a data byte
i2c_data_transmit(I2C0,0x00); //WAKE UP
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a stop condition to I2C bus
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
//REQUEST ACELEROMETER DATA (3B )
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_TRANSMITTER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// send a data byte
i2c_data_transmit(I2C0,0x3B); //ACCELEROMETER REGISTER
// wait until the transmission data register is empty
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
// send a stop condition to I2C bus
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
//now reopen the bus to receive the reply
// wait until I2C bus is idle
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
// send a start condition to I2C bus
i2c_start_on_bus(I2C0);
// wait until SBSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
// send slave address to I2C bus
i2c_master_addressing(I2C0, I2C_ACCELEROMETER_ADDRESS, I2C_RECEIVER);
// wait until ADDSEND bit is set
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
// if we receive only one byte: reset ACKEN bit
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
//clear ADDSEND bit
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
// if we receive only one byte: send stop condition
i2c_stop_on_bus(I2C0);
/* wait until the RBNE bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
//read a data from I2C_DATA
Accelerometer_X_High = i2c_data_receive(I2C0);
// if we receive more bytes: send a stop condition to I2C bus
//i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0)&0x0200);
// enable acknowledge
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
这是完整信号的屏幕截图: http://www.tr3ma.com/Dati/IMG_1526.JPG
信号上也有奇怪的尖峰:
http://www.tr3ma.com/Dati/spike1.JPG
http://www.tr3ma.com/Dati/spike2.JPG
答案 0 :(得分:0)
有效。我创建了一个循环以读取所有寄存器,并且能够读取芯片的全部内容。固件没有错误。唯一的问题是该芯片不是我想象的那样。我必须找到正确的加速度计部件号并找到将其唤醒的寄存器。