蓝桥杯嵌入式——串口通信
目录
USART
电平标准-TTL 电平标准与 RS232 电平标准
232通信标准
USB转232
异步通信
串口配置
程序设计
重定向
串口发送函数
发送字符串
串口接收——中断
1.USART
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格 式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特 率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和 IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理 器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。如图也就我们熟悉的串 口通通信标准。
在上面的通讯方式中,两个通讯设备的“DB9 接口”之间通过串口信号线建立起连接,串口信号 线中使用“RS-232 标准”传输数据信号。由于 RS-232 电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL 标准”的电平信号, 才能实现通讯。
电平标准-TTL 电平标准与 RS232 电平标准
232通信标准
串口通过三个引脚与其他设备连接在一起。任何USART双向通信至少需要两 个脚:接收数据输入(RX)和发送数据输出(TX)。
USB转232
RX:接收数据串行输入。通过采样技术来区别数据和噪音,从而恢复数据。
TX :发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。在单线和智能卡模式里,此 I/O 口被同时用于数据的发送和接收。
异步通信
在异步通讯中不使用时钟信号进行数据同步,它们直接在数据信号中穿插一些同步用的信号位, 或者把主体数据进行打包,以数据帧的格式传输数据,见图 ,某些通讯中还需要双方约定 数据的传输速率,以便更好地同步。
在同步通讯中,数据信号所传输的内容绝大部分就是有效数据,而异步通讯中会包含有帧的各种 标识符,所以同步通讯的效率更高,但是同步通讯双方的时钟允许误差较小,而异步通讯双方的 时钟允许误差较大。
串口配置
点击USATR1,设置MODE为异步通信(Asynchronous) ,波特率为115200 Bits/s。传输数据长度为8 Bit。奇偶检验无,停止位1 ,接收和发送都使能。 USART1_RX/USART_TX,默认即可。 图9 U NVIC Settings 一栏使能接收中断。
程序设计
重定向
//重定向 c 库函数printf、 scanf 到串口 USARTx,重写向后可使用 scanf、getchar 等函数
另外还需添加Use MicroLIB以便支持printf。
串口发送函数
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Transmit_DMA();串口DMA模式发送
发送字符串
HAL_UART_Transmit——这是一个阻塞的发送函数,无需重复判断串口是否发送完成 直到遇到空字符才停止发送。 最后使用循环检测发送完成的事件标志来实现保证数据发送完成后才退出函数。
除了使用普通方式发 送,还可用中断方式和DMA方式发送数据
串口接收——中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);
回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(Uart1_Rx_Cnt >= 255)
{
Uart1_Rx_Cnt = 0;
memset(TxBuffer,0x00,sizeof(TxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);
}
else
{
TxBuffer[Uart1_Rx_Cnt++] = RxBuffer;
if((TxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(TxBuffer[Uart1_Rx_Cnt-2] == 0x0D))
{
HAL_UART_Transmit(&huart1, (uint8_t *)&TxBuffer, Uart1_Rx_Cnt,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
Uart1_Rx_Cnt = 0;
memset(TxBuffer,0x00,sizeof(TxBuffer));
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);
}
注:中断接收函数只能触发一次接收中断,所以我们需要在中断回调函数中再次调用中断接收函数。
重定向的这部分工作, 由 fputc(int ch, FILE *f) 这个函数来完成。 重定向时,我们把 fputc( ) 的形参 ch,作为串口将要发送的数据,也就是说,当使用 printf( ) 时,它先调用这个 fputc( ) 函数,然后使用 ST 库的串口发送函数 USART_SendData(),把数据转移到发送数据寄存器 TDR,触发我们的串口向 PC 发 送一个相应的数据。调 用 完 USART_SendData( ) 后 , 要 使 用 while (USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET) 语句不停地检查 串口发送是否完成的标志位TC,一直检测到标志为“完成”,才进入下一步的操作,避免出 错。在这段 while 循环检测的延时中,串口外设已经由发送控制器以及根 据我们的配置把
数据从移位寄存器一位一位地通过串口线 Tx 发送出去了。
printf函数在“stdio.h”头文件里,使用该函数必须引用“stdio.h”库, 还 要在编译器中设置一个选项 Use MicroLIB (使用微库)。设置方式如下: 单击Project,选择option选项,再选择Target 勾选Use MicroLIB 即可。