(域格)4G模块与单片机通信并发数据到TCP服务
4G模块这里选择的是域格的YM310 X09物美价廉,单片机选择国产普冉(PUYA)单片机,通过串口和单片机交互。按照下面这样替换上面AT的字符串发送就行。对返回数据进行对比确定是否正常,不正常循环发送。连接TCP后就能进行发送相关信息了,因为发送完字符串需要发送结束符0x1A,这里做个函数进行发送数据。4G模块本身的AT指令并不复杂,下面是模块需要设置的相关AT指令。
·
4G模块这里选择的是域格的YM310 X09物美价廉,单片机选择国产普冉(PUYA)单片机,通过串口和单片机交互。
软件
4G模块本身的AT指令并不复杂,下面是模块需要设置的相关AT指令。
uint8_t CGATT[] = "AT+CGATT?\r\n"; //查看当前 GPRS 附着状态
uint8_t CIPMUX[] = "AT+CIPMUX=0\r\n"; //设置为单连接模式
uint8_t CIPQSEND[] = "AT+CIPQSEND=1\r\n"; //设置为快发模式
uint8_t CSTT[] = "AT+CSTT\r\n"; //启动任务,设置 APN模块注册网络后会从网络自动获取<apn>并激活一个 PDP 上下文
uint8_t CIICR[] = "AT+CIICR\r\n"; //激活移动场景,获取 IP 地址
uint8_t CIFSR[] = "AT+CIFSR\r\n"; //查询分配的 IP 地址
uint8_t CIPSTART[] = "AT+CIPSTART=\"TCP\",\"XX.XX.XX.XX\",1000\r\n"; //其中:"TCP"为链接的协议类型,"XX.XX.XX.XX"为对端服务器的 IP 地址, 1000为对端服务器的 TCP 端口号
初始化单片机
初始化串口,并重定向UART1
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)(&ch), 1, HAL_MAX_DELAY);
return ch;
}
void UART_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置 UART1 的 GPIO 引脚
// PA9 - UART1 TX
// PA10 - UART1 RX
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_USART1; // 根据芯片手册选择正确的复用功能
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 UART2 的 GPIO 引脚
// PA2 - UART2 TX
// PA3 - UART2 RX
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_USART2; // 根据芯片手册选择正确的复用功能
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
void UART1_Init(void)
{
// 使能 UART1 时钟
__HAL_RCC_USART1_CLK_ENABLE();
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
// 初始化错误处理
APP_ErrorHandler();
}
}
void UART2_Init(void)
{
// 使能 UART2 时钟
__HAL_RCC_USART2_CLK_ENABLE();
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
// 初始化错误处理
APP_ErrorHandler();
}
}
void UART_Interrupt_Init(void)
{
// 使能 UART1 中断
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
// 使能 UART2 中断
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
}
单片机发送接收AT实现连接TCP
按照下面这样替换上面AT的字符串发送就行。对返回数据进行对比确定是否正常,不正常循环发送。
HAL_UART_Transmit(&huart2, CIPSTART, sizeof(CIPSTART) - 1, HAL_MAX_DELAY);
HAL_Delay(100);
strx=strstr((const char*)g_usart_rx_buf,(const char*)"OK");
while(strx == NULL)
{
memset(g_usart_rx_buf, 0, sizeof(g_usart_rx_buf));
HAL_UART_Transmit(&huart2, CIPSTART, sizeof(CIPSTART) - 1, HAL_MAX_DELAY);
HAL_Delay(100);
strx = strstr((const char*)g_usart_rx_buf,(const char*)"OK");
}
memset(g_usart_rx_buf, 0, sizeof(g_usart_rx_buf));
连接TCP后就能进行发送相关信息了,因为发送完字符串需要发送结束符0x1A,这里做个函数进行发送数据。
/**
* @brief 发送AT命令及数据,以0x1A结尾
* @param huart: UART句柄指针
* @param atCmd: AT命令字符串 (如"AT+QISEND=0\r\n")
* @param data: 要发送的数据缓冲区
* @param timeout: 超时时间(ms)
* @retval HAL状态
*/
HAL_StatusTypeDef UART_SendCommandWithData(UART_HandleTypeDef *huart, const char *atCmd, const char *data, uint32_t timeout)
{
HAL_StatusTypeDef status;
uint8_t endMarker = 0x1A; // 结束符
// 1. 发送AT命令
if((status = HAL_UART_Transmit(huart, (uint8_t*)atCmd, strlen(atCmd), timeout)) != HAL_OK)
{
return status;
}
// 2. 发送数据
if(data != NULL && *data != '\0')
{
if((status = HAL_UART_Transmit(huart, (uint8_t*)data, strlen(data), timeout)) != HAL_OK)
{
return status;
}
}
// 3. 发送结束符0x1A
return HAL_UART_Transmit(huart,&endMarker, 1, timeout);
HAL_Delay(100);
strx=strstr((char*)g_usart_rx_buf,(char*)"SEND OK");//是否正确发送
while(strx==NULL)
{
strx=strstr((char*)g_usart_rx_buf,(char*)"SEND OK");//是否正确发送
HAL_Delay(100);
}
HAL_Delay(100);
下面是主函数实现:
int main(void)
{
HAL_Init(); // systick初始化
// 初始化 UART GPIO
UART_GPIO_Init();
// 初始化 UART1 和 UART2
UART1_Init(); //串口1初始化,打印调试信息
UART2_Init(); //串口2初始化,连接X09模块
// 初始化 UART 中断
UART_Interrupt_Init();
BSP_LED_Init(LED_GREEN); //LED初始化
printf("+++\r\n");
HAL_Delay(500);
printf("start\r\n");
HAL_UART_Receive_IT(&huart2, &g_usart_rx_buf[0], 1); // 启动接收
X09_init(); //X09模块注册网络
TCP_init(); //发送指令让模块连接MQTT服务器
while (1)
{
// 或者直接调用发送TCP数据
UART_SendCommandWithData(&huart2, "AT+QISEND=0\r\n", "Test data payload", 1000);
}
}
更多推荐



所有评论(0)