看看串口(轮询/中断)

usart:轮询/中断式(/DMA) 收发数据包

  • 轮询式数据包帧尾应该不能是\r\n (实验下来\n才行)

extern 是找的其他文件里的全局变量。。。

阻塞式:

void Serial_SendByte(USART_TypeDef* USARTx, uint16_t data) { // 阻塞式发送底层
	USART_SendData(USARTx, data);
	while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) != SET);
}

void Serial_SendMsg(USART_TypeDef* USARTx, uint8_t data[], uint16_t len) {
	for (uint16_t i = 0; i < len && data[i] != '\0'; i++) Serial_SendByte(USARTx,data[i]);
	Serial_SendByte(USARTx,'\r');
	Serial_SendByte(USARTx,'\n');
}

uint16_t Serial_RxByte(USART_TypeDef* USARTx) { // 阻塞式接收底层
	while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) != SET);
	uint16_t Rx = USART_ReceiveData(USARTx);
	return Rx;
}

void Serial_RxMsg(USART_TypeDef* USARTx, uint8_t RxMsg[], size_t len) { // ...要检测到 \n 才行,(win下只有enter的\n ?)
	for (size_t i = 0; i + 1 < len; i++) {
		RxMsg[i] = (uint8_t)Serial_RxByte(USARTx);
		if (i > 0 && RxMsg[i] == '\n') {
			RxMsg[i] = '\0';
            return;
        }
    }
}

(malloc, free, memset, memcpy, memmove ?)

如果是用中断实现上述功能的话。。。

(又是经典的标志位满天飞吗,不过必须得先弄熟这个了...)

extern volatile uint8_t RxMsg[50];
static volatile uint8_t pData = 0;
extern volatile uint8_t RxFlag;
void USART2_IRQHandler() {
	if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) { // 以后或许可以改造一下RxMsg[],手动维护一个环形队列
		uint8_t temp = (uint8_t)USART_ReceiveData(USART2);
		if (temp == '\n') {
			temp = '\0';
			RxMsg[pData] = '\0'; // 要添加这个标志才不会乱显...
			RxFlag = 1;
			pData = 0;
			return;
		}
		if (pData < sizeof(RxMsg) - 1) RxMsg[pData++] = temp;
		else pData = 0;
	}
}
while (1) {
	...
	if (RxFlag == 1) {
		RxFlag = 0;
		OLED_Clear();
		OLED_ShowString(1, 1, (char *)RxMsg);
	}
}
posted @ 2026-09-16 10:44  绿帽子玩家  阅读(9)  评论(0)    收藏  举报