GD32F303 硬件IIC参考例程
时间: 2023-10-04 14:07:39 浏览: 78
对于 GD32F303 硬件 IIC,以下是一个参考例程:
```c
#include "gd32f30x.h"
#define IIC_SCL_PIN GPIO_PIN_6
#define IIC_SDA_PIN GPIO_PIN_7
#define IIC_GPIO_PORT GPIOB
#define IIC_GPIO_CLK RCU_GPIOB
#define IIC_SCL_HIGH() gpio_bit_set(IIC_GPIO_PORT, IIC_SCL_PIN)
#define IIC_SCL_LOW() gpio_bit_reset(IIC_GPIO_PORT, IIC_SCL_PIN)
#define IIC_SDA_HIGH() gpio_bit_set(IIC_GPIO_PORT, IIC_SDA_PIN)
#define IIC_SDA_LOW() gpio_bit_reset(IIC_GPIO_PORT, IIC_SDA_PIN)
#define IIC_SDA_READ() gpio_input_bit_get(IIC_GPIO_PORT, IIC_SDA_PIN)
#define IIC_ACK 0
#define IIC_NACK 1
void iic_gpio_init(void)
{
rcu_periph_clock_enable(IIC_GPIO_CLK);
gpio_mode_set(IIC_GPIO_PORT, GPIO_MODE_OUTPUT_OD, GPIO_PUPD_PULLUP, IIC_SCL_PIN);
gpio_output_options_set(IIC_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, IIC_SCL_PIN);
gpio_mode_set(IIC_GPIO_PORT, GPIO_MODE_OUTPUT_OD, GPIO_PUPD_PULLUP, IIC_SDA_PIN);
gpio_output_options_set(IIC_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
IIC_SCL_HIGH();
IIC_SDA_HIGH();
}
void iic_delay_us(uint32_t us)
{
uint32_t i, j;
for (i = 0; i < us; i++)
for (j = 0; j < 8; j++);
}
void iic_start(void)
{
IIC_SDA_HIGH();
IIC_SCL_HIGH();
iic_delay_us(4);
IIC_SDA_LOW();
iic_delay_us(4);
IIC_SCL_LOW();
}
void iic_stop(void)
{
IIC_SDA_LOW();
IIC_SCL_HIGH();
iic_delay_us(4);
IIC_SDA_HIGH();
iic_delay_us(4);
}
uint8_t iic_wait_ack(void)
{
uint8_t ack;
IIC_SDA_HIGH();
iic_delay_us(1);
IIC_SCL_HIGH();
iic_delay_us(1);
ack = IIC_SDA_READ();
IIC_SCL_LOW();
return ack;
}
void iic_send_byte(uint8_t byte)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (byte & 0x80)
IIC_SDA_HIGH();
else
IIC_SDA_LOW();
byte <<= 1;
iic_delay_us(1);
IIC_SCL_HIGH();
iic_delay_us(1);
IIC_SCL_LOW();
iic_delay_us(1);
}
}
uint8_t iic_receive_byte(void)
{
uint8_t i, byte = 0;
IIC_SDA_HIGH();
for (i = 0; i < 8; i++) {
byte <<= 1;
IIC_SCL_HIGH();
iic_delay_us(1);
if (IIC_SDA_READ())
byte |= 0x01;
IIC_SCL_LOW();
iic_delay_us(1);
}
return byte;
}
uint8_t iic_write_byte(uint8_t dev_addr, uint8_t reg_addr, uint8_t data)
{
iic_start();
iic_send_byte(dev_addr);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
iic_send_byte(reg_addr);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
iic_send_byte(data);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
iic_stop();
return 0;
}
uint8_t iic_read_byte(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data)
{
iic_start();
iic_send_byte(dev_addr);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
iic_send_byte(reg_addr);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
iic_start();
iic_send_byte(dev_addr | 0x01);
if (iic_wait_ack() == IIC_NACK) {
iic_stop();
return 1;
}
*data = iic_receive_byte();
iic_stop();
return 0;
}
```
该例程中,包含了 IIC 总线初始化、延时、启动、停止、等待应答、发送字节和接收字节等基本操作函数。其中,启动和停止函数为 IIC 总线上的起始和停止信号,等待应答函数为等待从设备的应答信号,发送字节和接收字节函数为 IIC 总线上的数据通信操作。在发送和接收数据时,需要先发送从设备地址和寄存器地址,再发送或接收数据。需要注意的是,在发送或接收数据时,需要等待从设备的应答信号,以判断通信是否成功。