新版改动的地方有:
第一,不使用中断接收,而使用while来等待,因为本身函数的功能就是等待;
第二,去掉各种各样的全局数组;
第三,调用的函数指针更加简单;
第四,采用goto语句实现各种情形下的返回和收尾工作。
char UART_wait_spe_char(USART_TypeDef* USARTx, void (*fun)(void), int len, ...)
{
char byte = 0xFF, *p = (char *)&len + sizeof(len);
int i = 0;
uint8_t channel;
if (USARTx == USART1)
channel = USART1_IRQn;
else if (USARTx == USART2)
channel = USART2_IRQn;
else if (USARTx == USART3)
channel = USART3_IRQn;
else
return -1;
NVIC->ICER[channel >> 0x05] = (uint32_t)0x01 << (channel & (uint8_t)0x1F);
while (1) {
fun();
while (USART_GetITStatus(USARTx,USART_IT_RXNE) == RESET);
byte = USART_ReceiveData(USARTx);
uart_send_byte(USARTx, byte);
for (i = 0; i < len; i++) {
if (byte == *((char *)(p + i * sizeof(int))))
goto END;
}
}
END:
NVIC->ISER[channel >> 0x05] = (uint32_t)0x01 << (channel & (uint8_t)0x1F);
return byte;
}
使用时,先定义函数入口参数fun:
void uart1_wait_fun(void)
{
uart_printf(USART1, "rnPlease enter your choice (a/b/c/d): ");
}
然后在主函数中执行:
byte = UART_wait_spe_char(USART1, uart1_wait_fun, 4, 'a', 'b', 'c', 'd');
uart_printf(USART1, "rnControl the LED.rn");
在串口终端minicom就会显示:
Please enter your choice (a/b/c/d): F
Please enter your choice (a/b/c/d): D
Please enter your choice (a/b/c/d): a
Control the LED.