extern void Delay(__IO uint32_t nCount); USARType USART_SendStr(UART_HandleTypeDef * USART_Handler,char * str) { while (*str != '\0') { while(__HAL_UART_GET_FLAG(USART_Handler,UART_FLAG_TXE)==RESET); HAL_UART_Transmit(USART_Handler,(uint8_t *)str,1,1000); str++; } return USARTOK; } /* * 功能:固定時間指令匹配函數 * 入口參數1:串口句柄 * 入口參數2:串口接受緩沖區 * 入口參數3:發送的字符串 * 入口參數4:要匹配的字符串 * 返回值: * USARTTIMEOUT:超時未讀取到數據 * USARTOK :成功讀取到數據 * USARTERROR :接受到數據,但是沒有提取到*recestr */ USARType USART_Cmd_Marry(UART_HandleTypeDef * USART_Handler,Usart_RecerivePoint Rusart,char *sendstr,char *recestr) { /*通過串口發送指令*/ char * val; char * str; int count1 = 0; int count2 = 0; str = recestr; USART_SendStr(USART_Handler,sendstr);//發送字符串 while (*recestr != '\0')//如果讀取到\0則匹配完成 { if(Usart_fifo_Read(Rusart,(uint8_t *)val,1) == USARTOK) { if (*val == *recestr)//讀取到的第一個字節數相同 { recestr++; } else { recestr = str; count1++; if (count1 == 600) { return USARTERROR; } } } else { count2++; Delay_ms(1); if (count2 > 1000) { return USARTTIMEOUT; } } } return USARTOK; } /* * 功能:固定時間指令應答函數 * 入口參數1:串口句柄 * 入口參數2:串口接受緩沖區 * 入口參數3:發送的字符串 * 入口參數4:接受數據的地址 * 返回值: * USARTTIMEOUT:超時未讀取到數據 * USARTOK :成功讀取到數據 * */ USARType USART_Cmd_Ack(UART_HandleTypeDef * USART_Handler,Usart_RecerivePoint Rusart,char *sendstr,char *recestr) { /*通過串口發送指令*/ char * val; int count2 = 0; USART_SendStr(USART_Handler,sendstr); while (1) { if(Usart_fifo_Read(Rusart,(uint8_t *)val,1) == USARTOK) { *recestr = *val; recestr++; if (*val == 10) { *recestr = '\0'; return USARTOK; } } else { Delay_ms(1); count2++; if (count2 > 1000) { return USARTTIMEOUT; } } } } /* * 功能:可變時間指令匹配函數 * 入口參數1:串口句柄 * 入口參數2:串口接受緩沖區 * 入口參數3:發送的字符串 * 入口參數4:要匹配的字符串 * 入口參數5:限制的時間內檢測,單位ms * 入口參數6:限制的數據大小內查找,單位字節 * 返回值: * USARTTIMEOUT:超時未讀取到數據 * USARTOK :成功讀取到數據 * USARTERROR :接受到數據,但是沒有提取到*recestr */ USARType USART_Cmd_Time_Marry(UART_HandleTypeDef * USART_Handler,Usart_RecerivePoint Rusart,char *sendstr,char *recestr,uint16_t timeout,uint16_t countout) { /*通過串口發送指令*/ char * val; char * str; uint16_t count1 = 0; uint16_t count2 = 0; str = recestr; USART_SendStr(USART_Handler,sendstr);//發送字符串 while (*recestr != '\0')//如果讀取到\0則匹配完成 { if(Usart_fifo_Read(Rusart,(uint8_t *)val,1) == USARTOK) { if (*val == *recestr)//讀取到的第一個字節數相同 { recestr++; } else { recestr = str; count1++; if (count1 == countout) { return USARTERROR; } } } else { count2++; Delay_ms(1); if (count2 > timeout) { return USARTTIMEOUT; } } } return USARTOK; } /* * 功能:可變時間指令應答函數 * 入口參數1:串口句柄 * 入口參數2:串口接受緩沖區 * 入口參數3:發送的字符串 * 入口參數4:接受數據的地址 * 入口參數5:限制的時間內檢測,單位ms * 入口參數6:限制的數據大小內查找,單位字節 * 返回值: * USARTTIMEOUT:超時未讀取到數據 * USARTOK :成功讀取到數據 * */ USARType USART_Cmd_Time_Ack(UART_HandleTypeDef * USART_Handler,Usart_RecerivePoint Rusart,char *sendstr,char *recestr,uint16_t timeout,uint16_t countout) { /*通過串口發送指令*/ char * val; int count2 = 0; USART_SendStr(USART_Handler,sendstr); while (1) { if(Usart_fifo_Read(Rusart,(uint8_t *)val,1) == USARTOK) { *recestr = *val; recestr++; if (*val == 10) { *recestr = '\0'; return USARTOK; } } else { Delay_ms(1); count2++; if (count2 > 1000) { return USARTTIMEOUT; } } } }
這個里面一共有四段代碼,其實是兩段代碼,只是因為需求不同而復制出來了而已
實現原理是一樣的,目的是實現AT指令的匹配,和響應返回,詳細信息在代碼中都給出來了,這里面用到的數據類型和程序代碼都在前面的文章中給出來了,我發出來的代碼都是經過測試的,絕對可行,若有疑問可以添加QQ大家相互交流