小编CSDN突破2W访问量,值得庆祝谢谢大家支持!
现在NB-IOT模组应用越来越流行,经常需要进行AT指令的配置,AT指令配置又涉及到字符串的处理,经过小编摸爬滚打几个模组后,终于找到了快捷的操作AT指令和编写自己AT指令的办法,在此向大家分享,如有问题还望指出修正,谢谢大家!
一、调两个头文件
#include <stdio.h> //单片机printf重定义头文件
#include <string.h> //C语言字符串处理头文件
二、重定义串口 “printf”
//串口重定义
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 0xFFFF);
return ch;
}
三、定义全局变量
uint8_t rx_buff[256]; //uart receive buff
uint8_t rx_data; //uart receive data value
uint8_t rx_count =0; //uart receive data count
char *str1; //AT commnd string pointer
char *str2;
char imei[20];
四、串口中断函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
rx_buff[rx_count]= rx_data;
rx_count ++;
HAL_UART_Receive_IT(&huart1,&rx_data,1);
}
}
五、主函数main的内容
while (1)
{
str1 = (char *)rx_buff; //get uart data
//"AT\r\n" command ***************************
//如果串口缓存中有“AT”字符串,那么打印 “AT TEST OK”
if(strstr(str1, "AT") != NULL)
{
printf("\r\nAT TEST OK\r\n");
rx_count = 0;
//clear buff data
//清除数组数组,全部赋值为 零
memset((char *)rx_buff, 0, strlen((const char*)rx_buff));
}
else
{
//get IMEI
//如果串口缓存中有“IMEI”字符串,那么执行以下语句
str2 = strstr(str1, "IMEI");
if( str2!= NULL) //"IMEI:123456000000789" command
{
//pirntf receive all data
//打印接收到的IMEI数据段
printf("\r\nreceive data:%s\r\n",str2); //pirntf receive all data
//get IMEI
//取出IMEI数据,从第6开始,取出后面15位数据
strncpy((char*)(imei), (char*)(&str2[5]), 15);
printf("IMEI:%s\r\n",imei);
rx_count = 0;
memset((char *)rx_buff, 0, strlen((const char*)rx_buff)); //clear buff data 0
}
}
//LED闪烁查看单片机运行状态
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
HAL_Delay(500);
}
六、展示效果
最后送上大家喜欢的,直接上源码,_
路径:WL-open-projects/STM32/at-demo-20200607-1610.rar
https://github.com/NoSmallWhite/WL-open-projects.git
-------------------------------------------------------------------------------------
本段取出字符串中间的一段数据的方法;
void uart_testfunction(void)
{
char *str1 = NULL; //AT commnd string pointer
char *str2 = NULL;
char userData[256]; //定义数组
char *pcBegin = NULL;
char *pcEnd = NULL;
if(uart1_state.bits.interrupt_idle == ON)
{
uart1_state.bits.interrupt_idle = OFF;
printf("\r\n串口1接收数据:%s\r\n",uart1_data.uart1_rxbuff);
//接收到的字符串
//Open source and win each other filename=uarttestfile.txt
//Learn from each other
str1 = (char *)uart1_data.uart1_rxbuff; //取出串口数据
str2 = strstr(str1, "filename="); //取出”filename=“以后的字符串
if(str2 != NULL) //对比存在需要的数据
{
pcBegin = strstr(str2, "filename="); //str2:获取需要以后的数据
pcEnd = strstr(str2, "Learn"); //找到结束符,实际测试不能用换行符,直接查看英文字符吧
pcBegin += 9; //补偿”filename=“长度的地址位
if((pcBegin != NULL) && (pcEnd != NULL)) //开始和结束都有对应的字符
{
memcpy(userData, pcBegin, (pcEnd-pcBegin)); //从pcBegin地址开始,复制出(pcEnd-pcBegin)个数据
}
printf("文件名:%s\r\n",userData); //打印字符串
memset((char *)uart1_data.uart1_rxbuff, 0, strlen((const char*)uart1_data.uart1_rxbuff)); //clear buff data 0
}
}
}
串口发送的字符串1:
Open source and win each other filename=uarttestfile.txt Learn from each other
串口发送的字符串2:
Open source and win each other filename=uarttest123456789file.txt Learn from each other
源码在上面的github中,文件名是:
“demo-adc-vet6-串口读取字符串中的任意数据”