本帖最后由 hwhcgx 于 2021-4-7 11:03 编辑
求助大佬们。板子IIC接的是PB8和PB9,配置也是照抄官方的,系统时钟也调好了,不知道为啥就是没波形,SDL和SDA一直是低电平。发从机地址也就超时了。这个是配置代码
i2c.h
#ifndef I2C_H
#define I2C_H
#include "gd32f4xx.h"
#define I2C0_SPEED 400000
#define I2C0_SLAVE_ADDRESS7 0xA0
#define I2C_TIMEOUT 100000
enum I2C_ErrNum
{
I2C_ERROR = 0,
I2C_OK,
I2C_START_TIMEOUT,
I2C_SLAVEADDR_TIMEOUT,
I2C_BUFEMPTY_TIMEOUT,
I2C_REGADDR_TIMEOUT,
I2C_DATA_TIMEOUT,
I2C_STOP_TIMEOUT
};
void i2c0_init(void);
/* configure the GPIO ports */
void i2c0_gpio_config(void);
/* configure the I2C0 interfaces */
void i2c0_config(void);
enum I2C_ErrNum i2c0_codec_byte_write(uint8_t data, uint8_t regaddr,uint8_t slaveaddr);
#endif /* I2C_H */
i2c.c
void i2c0_init(void)
{
i2c0_gpio_config();
i2c0_config();
}
/*!
\brief configure the GPIO ports
\param[in] none
\param[out] none
\retval none
*/
void i2c0_gpio_config(void)
{
/* enable GPIOB clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* connect PB8 to I2C0_SCL */
gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_8);
/* connect PB9 to I2C0_SDA */
gpio_af_set(GPIOB, GPIO_AF_4, 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);
}
/*!
\brief configure the I2C0 interfaces
\param[in] none
\param[out] none
\retval none
*/
void i2c0_config(void)
{
/* enable I2C clock */
rcu_periph_clock_enable(RCU_I2C0);
/* configure I2C clock */
i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2);
/* configure I2C address */
i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,I2C0_SLAVE_ADDRESS7);
/* enable I2C0 */
i2c_enable(I2C0);
/* enable acknowledge */
i2c_ack_config(I2C0,I2C_ACK_ENABLE);
}
/*!
\brief write one byte to the I2C slave
\param[in] data
\param[in] register address/only wrte data if NULL
\param[out] none
\retval none
*/
enum I2C_ErrNum i2c0_codec_byte_write(uint8_t data, uint8_t regaddr,uint8_t slaveaddr)
{
uint32_t timeout = I2C_TIMEOUT;
/* 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))
{
if(0 == timeout--)
{
return I2C_START_TIMEOUT;
}
}
/* send slave address to I2C bus */
i2c_master_addressing(I2C0, slaveaddr, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
if(0 == timeout--)
{
return I2C_SLAVEADDR_TIMEOUT;
}
}
/* clear the ADDSEND bit */
i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
/* wait until the transmit data buffer is empty */
while(SET != i2c_flag_get(I2C0, I2C_FLAG_TBE))
{
if(0 == timeout--)
{
return I2C_BUFEMPTY_TIMEOUT;
}
}
if(NULL != regaddr)
{
i2c_data_transmit(I2C0, regaddr);
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC))
{
if(0 == timeout--)
{
return I2C_REGADDR_TIMEOUT;
}
}
}
/* send the byte to be written */
i2c_data_transmit(I2C0, data);
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC))
{
if(0 == timeout--)
{
return I2C_DATA_TIMEOUT;
}
}
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
/* wait until the stop condition is finished */
while(I2C_CTL0(I2C0)&0x0200)
{
if(0 == timeout--)
{
return I2C_STOP_TIMEOUT;
}
}
return I2C_OK;
}
main.c
void initialization(void)
{
led_gpio_config();
systick_config();
i2c0_init();
}
int main(void)
{
enum I2C_ErrNum err = I2C_ERROR;
initialization();
/* turn on LED5*/
gpio_bit_reset(GPIOB, GPIO_PIN_11);
err = i2c0_codec_byte_write(1,NULL,0x18);
} |
|