GD32F103硬件IIC主机接收,器件发送通讯程序
时间: 2023-12-19 12:07:04 浏览: 104
STM32F103实验:IIC程序源代码.rar
5星 · 资源好评率100%
以下是基于GD32F103芯片的硬件IIC主机接收,器件发送通讯程序:
```
#include "gd32f10x.h"
/* 定义IIC的GPIO端口和引脚 */
#define IIC_SCL_PORT GPIOB
#define IIC_SCL_PIN GPIO_PIN_10
#define IIC_SDA_PORT GPIOB
#define IIC_SDA_PIN GPIO_PIN_11
/* 定义IIC时钟频率 */
#define IIC_CLOCK_FREQ 400000
/* IIC总线操作函数 */
void iic_delay(uint32_t nCount);
void iic_gpio_init(void);
void iic_start(void);
void iic_stop(void);
void iic_ack(void);
void iic_nack(void);
uint8_t iic_wait_ack(void);
void iic_send_byte(uint8_t data);
uint8_t iic_receive_byte(void);
int main(void)
{
uint8_t data;
/* 初始化GPIO */
iic_gpio_init();
/* 发送START信号 */
iic_start();
/* 发送器件地址和写入位 */
iic_send_byte(0x50 << 1);
/* 发送数据 */
iic_send_byte(0x00);
iic_send_byte(0x01);
iic_send_byte(0x02);
iic_send_byte(0x03);
/* 发送STOP信号 */
iic_stop();
/* 延时一段时间 */
iic_delay(100000);
/* 发送START信号 */
iic_start();
/* 发送器件地址和读取位 */
iic_send_byte((0x50 << 1) | 0x01);
/* 读取数据 */
data = iic_receive_byte();
iic_ack();
data = iic_receive_byte();
iic_ack();
data = iic_receive_byte();
iic_ack();
data = iic_receive_byte();
iic_nack();
/* 发送STOP信号 */
iic_stop();
while (1);
}
/* IIC总线操作函数 */
/* 延时函数 */
void iic_delay(uint32_t nCount)
{
for (; nCount != 0; nCount--);
}
/* 初始化GPIO */
void iic_gpio_init(void)
{
/* 使能GPIOB时钟 */
rcu_periph_clock_enable(RCU_GPIOB);
/* 配置GPIOB10和GPIOB11为复用推挽输出模式 */
gpio_init(IIC_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, IIC_SCL_PIN);
gpio_init(IIC_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 配置GPIOB10和GPIOB11的复用功能 */
gpio_pin_remap_config(GPIO_SWJ_NONJTRST_DISABLE, GPIO_SPI0_REMAP, ENABLE);
}
/* 发送START信号 */
void iic_start(void)
{
/* 设置SDA为输出模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 发送START信号 */
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
gpio_bit_set(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(4);
gpio_bit_reset(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(4);
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
}
/* 发送STOP信号 */
void iic_stop(void)
{
/* 设置SDA为输出模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 发送STOP信号 */
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
gpio_bit_reset(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(4);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
gpio_bit_set(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(4);
}
/* 发送ACK信号 */
void iic_ack(void)
{
/* 设置SDA为输出模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 发送ACK信号 */
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
gpio_bit_reset(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(2);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
}
/* 发送NACK信号 */
void iic_nack(void)
{
/* 设置SDA为输出模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 发送NACK信号 */
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
gpio_bit_set(IIC_SDA_PORT, IIC_SDA_PIN);
iic_delay(2);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
}
/* 等待ACK信号 */
uint8_t iic_wait_ack(void)
{
uint8_t ack;
/* 设置SDA为输入模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 等待ACK信号 */
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
ack = gpio_input_bit_get(IIC_SDA_PORT, IIC_SDA_PIN);
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
return ack;
}
/* 发送一个字节的数据 */
void iic_send_byte(uint8_t data)
{
uint8_t i;
/* 设置SDA为输出模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 发送一个字节的数据 */
for (i = 0; i < 8; i++) {
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
if (data & 0x80) {
gpio_bit_set(IIC_SDA_PORT, IIC_SDA_PIN);
} else {
gpio_bit_reset(IIC_SDA_PORT, IIC_SDA_PIN);
}
data <<= 1;
iic_delay(2);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
}
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
}
/* 接收一个字节的数据 */
uint8_t iic_receive_byte(void)
{
uint8_t data = 0;
uint8_t i;
/* 设置SDA为输入模式 */
gpio_init(IIC_SDA_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
/* 接收一个字节的数据 */
for (i = 0; i < 8; i++) {
data <<= 1;
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
gpio_bit_set(IIC_SCL_PORT, IIC_SCL_PIN);
iic_delay(2);
if (gpio_input_bit_get(IIC_SDA_PORT, IIC_SDA_PIN)) {
data |= 0x01;
}
}
gpio_bit_reset(IIC_SCL_PORT, IIC_SCL_PIN);
return data;
}
```
程序中的iic_gpio_init()函数用于初始化IIC的GPIO端口和引脚,iic_start()函数用于发送START信号,iic_stop()函数用于发送STOP信号,iic_ack()函数用于发送ACK信号,iic_nack()函数用于发送NACK信号,iic_wait_ack()函数用于等待ACK信号,iic_send_byte()函数用于发送一个字节的数据,iic_receive_byte()函数用于接收一个字节的数据。程序中的0x50是器件地址,可以根据实际情况进行修改。
阅读全文