Я не могу использовать I2C в процессе ARM CORTEX M3.Что я делаю неправильно?Какой тест я могу выполнить, чтобы найти проблему?
Это 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
http://www.tr3ma.com/Dati/spike3.JPG
http://www.tr3ma.com/Dati/spike4.JPG