G0001配置串口之串口接收中断
分享作者:F888
作者昵称:我爱小易
评测品牌:灵动微电子
评测型号:MM32G0001A1TC
发布时间:2025-10-11 13:48:05
1
前言
在第一篇贴子,已经全面论述了串口如何初始化,以及重定向,但是如果我们需要用串口来控制设备最好就是通过中断来进行......
开源口碑分享内容

G0001单片机串口接收中断配置详解

在上一篇中,我们成功实现了串口的基本发送功能,并通过 printf 输出调试信息。但真正的串口通信往往是双向的——不仅要发,还要能实时接收上位机指令并做出响应

今天,我们就来深入讲解如何在 G0001 单片机(以 MM32G0001 为例)上配置 USART 接收中断(RXNE 中断),并通过一个简单的“串口控制LED”示例,展示中断的实际应用价值。



一、为什么需要接收中断?

           轮询方式(不断检查 RXNE 标志位)会占用大量 CPU 资源,效率低下。而使用 接收中断,可以在数据到达时自动触发中断服务函数(ISR),主程序无需等待,真正做到“有数据才处理”,极大提升系统响应性和资源利用率。

二、接收中断配置三步走

步骤 1:使能 USART (详细过程见上一篇贴)

步骤 2:配置 NVIC(嵌套向量中断控制器)

	NVIC_InitTypeDef NVIC_Init_Structure;
	
	NVIC_Init_Structure.NVIC_IRQChannel=USART1_IRQn;
	NVIC_Init_Structure.NVIC_IRQChannelCmd=ENABLE;	
	NVIC_Init_Structure.NVIC_IRQChannelPriority=1;
	NVIC_Init(&NVIC_Init_Structure);

步骤 3:使能接收中断

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

三、编写中断服务函数(ISR)

当串口接收到一个字节数据时,USART1_IRQHandler 会被自动调用:

void USART1_IRQHandler(void)
{
    static char buffer[128];
    static int index = 0;

    if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
    {
        char ch = USART_ReceiveData(USART1); // 读取数据,同时清除 RXNE 标志

        // 缓存字符(防止溢出)
        if (index < sizeof(buffer) - 1) {
            buffer[index++] = ch;
        }

        // 判断是否为换行(命令结束)
        if (ch == '\r' || ch == '\n') {
            buffer[index - 1] = '\0'; // 截断字符串
            index = 0;

            // 解析命令
            if (strcmp(buffer, "LED_ON") == 0) {
                GPIO_ResetBits(GPIOA, GPIO_Pin_11); // 点亮 LED(低电平有效)
                printf(">>> LED ON\r\n");
            }
            else if (strcmp(buffer, "LED_OFF") == 0) {
                GPIO_SetBits(GPIOA, GPIO_Pin_11);   // 熄灭 LED
                printf(">>> LED OFF\r\n");
            }
            else {
                printf(">>> Unknown command: %s\r\n", buffer);
            }
        }
    }
}

四、测试代码

void GPIO_init()
{
	GPIO_InitTypeDef GPIO_Init_structure;
	RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA,ENABLE);

	GPIO_Init_structure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init_structure.GPIO_Pin=GPIO_Pin_11;//LED接口
	GPIO_Init_structure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Init_structure);
	
}
int main(void)
{
	GPIO_init();
	uart_init();
	GPIO_SetBits(GPIOA,GPIO_Pin_11);
	printf("=======ICEasy=======");	
	printf("\r\nBOARD : Mini-G0001");
	
	printf("\r\n");
    while (1)
    {		
      printf("\r\nMCU : MM32G0001A1T");
			for(int i=0;i<999999;i++);
    }
}

五、测试效果

  1. 下载程序到 Mini-G0001 开发板;
  2. 打开串口助手(波特率 115200,8N1);
  3. 输入 LED_ON → LED 点亮;
  4. 输入 LED_OFF → LED 熄灭;
  5. 输入其他内容 → 返回“Unknown command”。


全部评论
暂无评论
0/144