GD32 笔记 03:如何利用串口中断接收不定长数据,并使用阻塞方式发送数据

一. 前言

  • 测试时,使用的 MCU 是:GD32E230C8
  • 测试例程下载子地址:下载

二. 主要功能代码

1. 宏定义与相关变量定义

#define USART_RECV_BUF_SIZE 32

uint8_t usart_recv_buf[USART_RECV_BUF_SIZE] = {0};// 接收缓存区
uint16_t usart_recv_count = 0;                    // 接收数据个数

2. 初始化配置函数(GPIO,USART,NVIC)

void usart_init()
{
	rcu_periph_clock_enable(RCU_GPIOA); // 使能外设时钟
	rcu_periph_clock_enable(RCU_USART0);
	
	gpio_af_set            (GPIOA, GPIO_AF_1,     GPIO_PIN_9); // 设置GPIO的备用功能
	gpio_af_set            (GPIOA, GPIO_AF_1,     GPIO_PIN_10);
	gpio_mode_set          (GPIOA, GPIO_MODE_AF,  GPIO_PUPD_PULLUP,  GPIO_PIN_9); // 设置GPIO模式
	gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9); // 设置GPIO输出模式和速度
	gpio_mode_set          (GPIOA, GPIO_MODE_AF,  GPIO_PUPD_PULLUP,  GPIO_PIN_10);
	gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
	
	usart_deinit                   (USART0);                        // 复位外设USARTx
	usart_word_length_set          (USART0, USART_WL_8BIT);         // 配置USART字长
	usart_stop_bit_set             (USART0, USART_STB_1BIT);        // 配置USART停止位
	usart_parity_config            (USART0, USART_PM_NONE);         // 配置USART奇偶校验
	usart_baudrate_set             (USART0, 115200U);               // 配置USART波特率
	usart_receive_config           (USART0, USART_RECEIVE_ENABLE);  // USART接收器配置
	usart_transmit_config          (USART0, USART_TRANSMIT_ENABLE); // USART发送器配置
	usart_enable                   (USART0);                        // 使能USART
	
	nvic_irq_enable(USART0_IRQn, 0);                // 使能NVIC的中断
	usart_interrupt_enable(USART0, USART_INT_RBNE); // 使能USART中断, USART_INT_RBNE:读数据缓冲区非空中断和过载错误中断
	usart_interrupt_enable(USART0, USART_INT_IDLE); // USART_INT_IDLE:IDLE线检测中断
}

3. 串口数据发送函数

for(int i=0; i<len; i++)
{
	usart_data_transmit(usart_periph, (uint8_t) (*(data + i)));  // USART发送数据功能
	while(RESET == usart_flag_get(usart_periph, USART_FLAG_TBE));// 获取USART STAT/CHC/RFCS寄存器标志位,USART_FLAG_TBE:发送数据缓冲区空标志
}

4. 串口中断服务函数

void USART0_IRQHandler(void)
{
	if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE))// 获取USART中断标志位状态
		                                                                // USART_INT_FLAG_RBNE:读数据缓冲区非空中断标志
	{ 
		usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);// 清除USART中断标志位状态
		
		uint8_t ch = (uint8_t)usart_data_receive(USART0);// USART接收数据功能
		
		if(usart_recv_count < USART_RECV_BUF_SIZE)
		{
			usart_recv_buf[usart_recv_count++] = ch;
		}
	}

	if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE))// USART_INT_FLAG_IDLE:IDLE线检测中断标志
	{
		usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);
		
		if(usart_recv_count > 0)
		{		
			usart_receive_config(USART0, USART_RECEIVE_DISABLE); 
			
			/* 测试部分,接收到的数据最好在main中处理掉 */
			usart_send(USART0, usart_recv_buf, usart_recv_count);
			for(int i=0; i<usart_recv_count; i++)
			{
				SEGGER_RTT_printf(0, "%#x\n", usart_recv_buf[i]);
			}
			
			usart_recv_count = 0;
			usart_receive_config  (USART0, USART_RECEIVE_ENABLE);  // USART接收器配置
			usart_interrupt_enable(USART0, USART_INT_RBNE);        // 使能USART中断, USART_INT_RBNE:读数据缓冲区非空中断和过载错误中断
			usart_interrupt_enable(USART0, USART_INT_IDLE);        // USART_INT_IDLE:IDLE线检测中断
		}
	}
}

5. 主函数

systick_config();

usart_init();

while(1)
{
	delay_1ms(1000);
}
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Simple Man ZHR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值