STM32单片机控制(域格)4G模块http post请求数据
开发板介绍这里选择STM32f103开发板和域格YM310 X09开发板。STM32F103系列价格低廉,开发板成本低,丰富的外设扩展。YM310 X09开发板是域格推出的基于移芯平台设计的,包含电源,SIM卡,USB,天线,音频等必要功能的最小硬件系统。模块这边直接用普通AT版本就行了。
开发板介绍
这里选择STM32f103开发板和域格YM310 X09开发板。
STM32F103系列价格低廉,开发板成本低,丰富的外设扩展。
YM310 X09开发板是域格推出的基于移芯平台设计的,包含电源,SIM 卡,USB,天线,音频等必要功能的最小硬件系统。模块这边直接用普通AT版本就行了。
一、软件
这里我单片机用得标准库,直接重定向UART2支持printf函数。
#pragma import(__use_no_semihosting)
// FILE结构体定义
struct __FILE { int handle; };
FILE __stdout;
// 退出函数
void _sys_exit(int x) { while(1); }
// 串口输出
int fputc(int ch, FILE *f) {
while(!(USART2->SR & 0x40)); // 等待发送完成
USART2->DR = ch; // 发送字符
return ch;
}
初始化UART2串口与模块进行通信
//初始化IO 串2
//bound:波特率
void uart2_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//USART2
USART_DeInit(USART2); //复位串口2
//USART2_TX PA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA2
//USART2_RX PA.3,
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA3
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化串口
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART2, ENABLE); //使能串口
}
这里串口初始化完成,后面通过串口查询模块注网是否正常。
void X09_Init(void)
{
printf("AT\r\n");
delay_ms(500);
printf("AT\r\n");
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"OK");//返回OK
while(strx==NULL)
{
Clear_Buffer(); //清空接收buff缓存
printf("AT\r\n");
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"OK");//返回OK
}
printf("ATE0\r\n"); //关闭回显
delay_ms(500);
Clear_Buffer();
printf("AT+CSQ\r\n"); //检查CSQ
delay_ms(500);
/////////////////////////////////
printf("AT+CPIN?\r\n");//检查SIM卡是否在位
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+CPIN: READY");//查看是否返回ready
while(strx==NULL)
{
Clear_Buffer();
printf("AT+CPIN?\r\n");
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+CPIN: READY");//检查SIM卡是否在位,等待卡在位。
}
Clear_Buffer();
printf("AT+CEREG?\r\n");//查看是否注册GSM网络
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+CEREG: 0,1");//返回正常
extstrx=strstr((const char*)RxBuffer,(const char*)"+CEREG: 0,5");//返回正常,漫游
while(strx==NULL&&extstrx==NULL)
{
Clear_Buffer();
printf("AT+CEREG?\r\n");//查看是否注册GSM网络
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"+CEREG: 0,1");//返回正常
extstrx=strstr((const char*)RxBuffer,(const char*)"+CEREG: 0,5");//返回正常,漫游
}
Clear_Buffer();
}
确定模块注网成功后,这里确定http post AT流程。4G模块本身AT指令不复杂,下面是模块需要设置的相关AT指令
AT+SAPBR=3,1,"CONTYPE","GPRS" //设置 HTTP 功能的承载类型
OK
AT+SAPBR=3,1,"APN","" //模块注册网络后会从网络自动获取<apn>并激活一个PDP 上下文OK
AT+SAPBR=1,1 //激活该承载的 GPRS PDP 上下文OK
AT+SAPBR=2,1 //查询下承载的状态+SAPBR: 1,1,"10.63.47.89"
OK
AT+HTTPINIT //HTTP 协议栈初始化OK
AT+HTTPPARA="CID",1 //设置 HTTP 会话参数:CIDOK
AT+HTTPPARA="URL","http://xx.xx.xx.xx:xxxx/parse" //设置 HTTP 会话参数:URLOK
AT+HTTPPARA="USER_DEFINED","Content-Type: application/json" //设置HTTP参数值OK
这里post数据案例:
AT+HTTPDATA=253,100000 //输入 253个字节,等待时间是 10S,输入时间要设定的足够大以保证数据输入DOWNLOAD
。。。这里输入具体post数据
OK
AT+HTTPACTION=1 //POST开始OK
+HTTPACTION: 1,200,1038
AT+HTTPREAD //读取post获取得内容+HTTPREAD: 1038
{"message":具体返回消息}
OK
上面是AT指令,下面是单片机具体post 主要代码获取
char datalu[] =
"{\"xxxx\":\"2025-01-14 10:54:33\","
"\"xxx\":\"http://xx.xx.xx.xx:8081/mall\","
"\"xx\":\"MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=\","
"\"xx\":\"S00000012501144dd3dc4\","
"\"xx\":\"a07551ecef7daa76c3d299353038a705\","
"\"xx\":\"S0000001\","
"\"xx\":\"20250114105433\"}";
void HTTP_Init(void)
{
...........
printf("AT+HTTPDATA=%d,100000\r\n",sizeof(datalu)); // 输入N字节,等待时间是10S,输入时间要设定的足够大以保证数据输入
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"DOWNLOAD");
if(strx!=NULL)
{
Clear_Buffer();
printf("%s\r\n",datalu); //post的字符串
}
delay_ms(500);
extstrx=strstr((const char*)RxBuffer,(const char*)"OK");
while(extstrx==NULL)
{
Clear_Buffer();
printf("AT+HTTPDATA=%d,100000\r\n",sizeof(datalu));
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"DOWNLOAD");
if(strx!=NULL)
{
//printf("%s",RxBuffer);
printf("%s\r\n",datalu); //post的字符串
Clear_Buffer();
}
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"OK");
}
Clear_Buffer();
printf("AT+HTTPACTION=1\r\n"); //psot开始
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"OK");
extstrx=strstr((const char*)RxBuffer,(const char*)"+HTTPACTION: 1,200");//psot成功 例:+HTTPACTION: 1,200,1038
while(strx==NULL&&extstrx==NULL)
{
Clear_Buffer();
printf("AT+HTTPACTION=1\r\n");
delay_ms(500);
strx=strstr((const char*)RxBuffer,(const char*)"OK");
extstrx=strstr((const char*)RxBuffer,(const char*)"+HTTPACTION: 1,200"); //psot成功
}
Clear_Buffer();
printf("AT+HTTPREAD\r\n"); //将post打印到串口
while(1)
{
printf("post 执行完成");
}
//这里接收buff已经有post数据了。
}
这里写个函数处理一下post接收得数据,只要中间得数据部分。
void json_from_rx_buffer(char *rx_buffer) {
// 1. 检查是否包含有效数据
if (rx_buffer == NULL || strlen(rx_buffer) == 0) {
Uart1_Send("No data in RxBuffer!\n");
return;
}
// 2. 查找第一个 '{' 和最后一个 '}'
char *json_start = strchr(rx_buffer, '{');
char *json_end = strrchr(rx_buffer, '}');
// 3. 检查是否找到有效JSON
if (json_start && json_end && json_end > json_start) {
// 计算JSON长度
int json_length = json_end - json_start + 1;
// 4. 提取JSON数据(可存入全局变量或直接处理)
char json_data[json_length + 1]; // +1 存放 '\0'
strncpy(json_data, json_start, json_length);
json_data[json_length] = '\0'; // 确保字符串结束
Uart1_Send(json_data); // 输出: {数据}
} else {
Uart1_Send("No valid JSON found!\n");
}
}
这里http post数据就已经在json_data里面了。
主函数:
int main(void)
{
delay(); //延时函数初始化
NVIC(); //设置NVIC
LED_Init(); //初始化与LED连接的硬件接口
uart1_init(115200);//串口1初始化,打印调试信息
uart2_init(115200);//串口2初始化,连接X09模块
printf("+++");
delay_ms(500);
printf("+++");
delay_ms(500);
X09_Init(); //X09初始化查询注网
HTTP_Init(); //HTTP服务
while(1)
{
Uart1_Send(json_data); // 输出: {数据}
delay_ms(500);
LED1=!LED1;
}
}
这里就完成把模块post数据发送到单片机UART1串口了。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)