一:极海APM32F402串口知识分享:
F402共有:3个USART,1个UART,支持ISO7816、LIN 和 IrDA 等功能
USART(通用同步异步收发器)是一个可以灵活地与外部设备进行全双工、半双工数据交换的串行通信设备,且同时满足外部设备对工业标准 NRZ异步串行数据格式的要求。USART还提供宽范围的波特率选择,且支持多处理器通信。
USART 不仅支持标准的异步收发模式,也支持一些其他的串行数据交换模式如 LIN 协议、智能卡协议、IrDA SIR ENDEC 规范和硬件流控制模式。
USART 还支持使用 DMA 功能,以实现高速数据通信。
二:串口的主要特征:
(1)全双工异步通信
(2)单线半双工通信
(3)NRZ 标准格式
(4)可编程的串口特性:
数据位:8位或9位
校验位:偶校验、奇校验、无校验
支持 0.5、1、1.5、2 个停止位
(5)校验控制
发送校验位
校验接收的数据
(6)独立的发送器和接收器使能位
(7)可编程的波特率发生器,波特率最高可达4.5Mbits/s
三:寄存器地址如下:
这里我们使用数据寄存器完成,CPU与外设的数据交互。
四:代码编写过程:
4.1 编写串口的基本流程:
首先串口时钟使能,GPIO时钟使能:
GPIO端口模式设置:
串口参数初始化:
开启中断并且初始化
使能串口:
编写串口发送函数:重映射PRINTF 函数进行数据的发送。
4.2 串口的初始化过程:
- void USART1_INIT(int bound)
- {
- USART_Config_T USART_ConfigStruct;
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
- DMA_USART1_TX_Configuration(sendlength1);
- USART_ConfigStruct.baudRate = bound;
- USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
- USART_ConfigStruct.mode = USART_MODE_TX_RX;
- USART_ConfigStruct.parity = USART_PARITY_NONE;
- USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
- USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
- BOARD_COM_Config(COM1, &USART_ConfigStruct);
4.3 编写发送函数:
- /**
- * @brief bool SendDataToUSART1(int length)
- *
- * @param 串口中断发送方式
- *
- * @retval None
- */
- char SendDataToUSART1(int length)
- {
- uint8_t i;
- for(i = 0; i < length; i++)
- {
- while(USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
- USART_TxData(USART1, SendBuffer1[i]);
- }
- return 1;
- }
这里我们查看一下,官方提供的库函数的原型如下:
- /*!
- * @brief Transmits single data
- *
- * @param usart: Select the USART or the UART peripheral
- *
- * @param data: the data to transmit
- *
- * @retval None
- *
- * @NOTE The usart can be USART1, USART2, USART3, UART4
- */
- void USART_TxData(USART_T* usart, uint16_t data)
- {
- usart->DATA_B.DATA = data;
- }
- /* TX Buffer Data Register */
- union
- {
- __IOM uint32_t DATA;
- struct
- {
- __IOM uint32_t DATA : 9;
- __IM uint32_t RESERVED : 23;
- } DATA_B;
- } ;
可以看到这里,直接将发送的数据放到数据寄存器里就可以了。
定义一下发送的buffer和函数如下所示:
- unsigned char SendBuffer1[sendlength1] ;
- unsigned char RecBuffer1[reclength1] ;
- unsigned char usart1_rx_len; //串口1接收数据长度
- unsigned char Usart1_DEAL_RX_Buf[reclength1]; //串口1处理接收缓冲
- unsigned char usart1_Flag; //串口1接收完整数据包指令
- void ChangePage(unsigned short int no)
- {
- SendBuffer1[0] = 0x5A;
- SendBuffer1[1] = 0xA5;
- SendBuffer1[2] = 0x03;
- SendBuffer1[3] = 0x80;
- SendBuffer1[4] = 0x04;
- SendBuffer1[5] = no;
- SendDataToUSART1(6);
- }
然后将该发送函数在 500ms的任务中调用,效果如下:
在LED闪烁的同时,可以看到串口通过中断的方式发送数据出来。
方式二:重映射printf
- /**
- * @brief int fputc(int ch, FILE* f)
- *
- * @param 重映射printf 函数
- *
- * @retval None
- */
- int fputc(int ch, FILE* f)
- {
- USART_TxData(USART1, (uint8_t)ch);
- while (USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
- return (ch);
- }
测试图片如下所示:
这里需要注意的是,需要等待发送完成的标志触发之后,才可以进行下一个数据的发送,否则会导致数据发送不正常。
|