3.串口USART标准固件库发送与中断接收解析

本文详细介绍了如何在MCU中使用USART标准固件库进行串口发送和中断接收,包括GPIO配置、波特率设置、中断服务启用,以及一个基础应用案例,展示了如何利用串口进行数据交换和控制操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.描述

串口通信常见于MCU之间以及MCU与高速上位机等场景,用于传输数据。

2.串口设置

2.1.串口GPIO初始化和引脚复用

/* USART0 Initialize*/
nvic_irq_enable(USART0_IRQn, 0, 0);
rcu_periph_clock_enable(RCU_GPIOB);	/* enable GPIO clock */
rcu_periph_clock_enable(RCU_USART0);	/* enable USART clock */
gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6);	/* connect port to USARTx_Tx */
gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7);	/* connect port to USARTx_Rx */
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);	/* configure USART Tx as alternate function push-pull */
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);	/* configure USART Rx as alternate function push-pull */
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
/* USART2 Initialize*/
 nvic_irq_enable(USART2_IRQn, 0, 0);
 rcu_periph_clock_enable(RCU_GPIOC);	/* enable GPIO clock */
 rcu_periph_clock_enable(RCU_USART2);	/* enable USART clock */
 gpio_af_set(GPIOC, GPIO_AF_7, GPIO_PIN_10);	/* connect port to USARTx_Tx */
 gpio_af_set(GPIOC, GPIO_AF_7, GPIO_PIN_11);	/* connect port to USARTx_Rx */
 gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10);	/* configure USART Tx as alternate function push-pull */
 gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
 gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_11);	/* configure USART Rx as alternate function push-pull */
 gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11);

2.1.串口的波特率、停止位等与USART的中断服务在NVIC使能

/* USART0 configure */
usart_deinit(USART0);
usart_baudrate_set(USART0,115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
usart_interrupt_enable(USART0, USART_INT_RBNE);
 /* USART2 configure */
 usart_deinit(USART2);
 usart_baudrate_set(USART2,115200U);
 usart_receive_config(USART2, USART_RECEIVE_ENABLE);
 usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);
 usart_enable(USART2);
 usart_interrupt_enable(USART2, USART_INT_RBNE);

3.串口发送

  • 输入参数:usartx、发送字节串、字节长度。
  • 返回参数:发送字节的长度。
uint16_t uart_send_bytes(uint32_t usart_periph, uint8_t *data, uint16_t len)
{
		uint8_t i;
		for(i = 0; i < len; i++) 
		{
				while(usart_flag_get(usart_periph, USART_FLAG_TC) == RESET);      
				usart_data_transmit(usart_periph, data[i]);
		}
		while(usart_flag_get(usart_periph, USART_FLAG_TC) == RESET);
		return len;
}

4.串口中断接收

  • 串口中断使能于接收缓冲区非空中断标志位。
usart_interrupt_enable(USART2, USART_INT_RBNE);
void USART0_IRQHandler(void)
{
		if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) != RESET)
		{
				usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RBNE);
				

				Uart0_RecvBuffer[Uart0_RecvLenth] = usart_data_receive(USART0);
				Uart0_RecvLenth ++;
				if(Uart0_RecvLenth == 1)
					Uart0_RecvLenth = 0;

				
		}
}

5.基础应用案例

  • 此应用案例的使用场景为上位机成功实现人脸识别后发送信令给下位机,下位机对灯进行点亮(用于替代开门功能)。
  • 此应用案例将展现串口普通发送、串口中断接收,其他内容将省略。
  • 串口初始化将被省略。
uint8_t flag = 0;
//串口数据接收缓存
uint8_t   USART0_RecvBuffer[8];
uint8_t   USART0_buf[8];
uint16_t  USART0_RecvLenth = 0;

uint8_t callback_order[4] = {0x4F, 0x4B, 0x0D, 0x0A};

void process(void)
{
	memset(USART0_RecvBuffer, 0, 8);//清空缓冲变量
	if(USART0_RecvBuffer[0] == 'S')
	{
		if(USART0_RecvBuffer[7] == 'E')
		{
			if(USART0_RecvBuffer[1] == '1')
				LED_ON();
			if(USART0_RecvBuffer[1] == '2')
				LED_OFF();
		}
	}
	delay(500);
}

void USART0_IRQHandler(void)
{
		if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) != RESET)//接收缓冲区非空(用于判断是否接收到数据)
		{
			usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RBNE);
			
			USART0_RecvBuffer[USART0_RecvLenth] = usart_data_receive(USART0);
			if (USART0_RecvBuffer[0] == 'S')//开始位
			{
				flag = 1;
			}
			
			if (flag == 1)
				USART0_RecvLenth ++;
			
			if (USART0_RecvBuffer[7] == 'E')//数据结束位
			{
				flag = 0;
				//判断区域
				process();
				delay(500);
				//结束时清空索引、标志位、接收变量
				memset(USART0_RecvBuffer, 0, 8);
				USART0_RecvLenth = 0;		
				uart_send_bytes(USART0, callback_order, 4);
			}	
			if (USART0_RecvLenth >= 7)
				USART0_RecvLenth = 0;
		}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AzusaFighting

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

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

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

打赏作者

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

抵扣说明:

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

余额充值