3.串口USART标准固件库发送与中断接收
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;
}
}