最近一直在做2g模块联网的项目,用到了移柯L206 2G模块,今天就简单讲一下移柯L206 2G模块基于STM32+AT命令开发TCP联网的过程,参考文档:移柯L206 TCPIP开发流程说明V1.1

想要实现模块联网,首先需要配置STM32串口,代码如下:

#include "delay.h"
#include "iot.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"    u16 point2 = 0;//串口发送缓存区
#pragma data_alignment = 8
/*__align(8)*/
char USART3_TX_BUF[USART3_MAX_SEND_LEN];    //发送缓冲,最大USART3_MAX_SEND_LEN字节
#ifdef USART3_RX_EN                                 //如果使能了接收
//串口接收缓存区
char USART3_RX_BUF[USART3_MAX_RECV_LEN];                //接收缓冲,最大USART3_MAX_RECV_LEN个字节.//定义变量
unsigned long  Time_Cont = 0;       //定时器计数器
unsigned int   count = 0;//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
u16 USART3_RX_STA=0;        // u8 USART3_Hand(char *a)                   // 串口命令识别函数
// {
//     if(strstr(USART3_RX_BUF,a)!=NULL)
//      return 1;
//  else
//      return 0;
// }void USART3_CLR_Buf(void)                           // 串口缓存清理
{memset(USART3_RX_BUF, 0, USART3_MAX_RECV_LEN);      //清空       USART3_RX_STA = 0;point2 = 0;
}//初始化IO 串口2
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void USART3_Init(u32 bound)
{  NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  // GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);/*CS12G  4G芯片选择引脚,高电平4G芯片,低电平2G芯片CS2芯片品牌选择引脚,高电平移远芯片、低电平移柯芯片*///模块选择引脚初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;                              //PB.1->CS1  PB.5->CS2
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                                //浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);                                            //初始化GPIOB.7  8  9//控制引脚初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;                     //PB.7->IOT_Wkae  PB.8->IOT_Rst  PB.9->IOT_PwrEnGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                    // 推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure);                                           //初始化GPIOB.7  8  9USART_DeInit(USART3);  //复位串口1//USART3_TX   PB.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB.10//USART3_RX      PB.11GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB.11USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;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(USART3, &USART_InitStructure); //初始化串口 2//波特率设置//  USART3->BRR=(pclk1*1000000)/(bound);// 波特率设置     //USART3->CR1|=0X200C;     //1位停止,无校验位.USART_DMACmd(USART3,USART_DMAReq_Tx,ENABLE);    //使能串口2的DMA发送UART_DMA_Config(DMA1_Channel2,(u32)&USART3->DR,(u32)USART3_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART3_TX_BUF USART_Cmd(USART3, ENABLE);                    //使能串口 #ifdef USART3_RX_EN          //如果使能了接收//使能接收中断USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断   NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器TIM4_Init(99,7199);       //10ms中断USART3_RX_STA=0;       //清零TIM4_Set(0);            //关闭定时器4
#endif      }
//串口2,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{  va_list ap;va_start(ap,fmt);vsprintf((char*)USART3_TX_BUF,fmt,ap);va_end(ap);while(DMA_GetCurrDataCounter(DMA1_Channel2)!=0);   //等待通道7传输完成   UART_DMA_Enable(DMA1_Channel2,strlen((const char*)USART3_TX_BUF));    //通过dma发送出去
}//设置TIM4的开关
//sta:0,关闭;1,开启;
void TIM4_Set(u8 sta)
{if(sta){       TIM_SetCounter(TIM4,0);//计数器清空TIM_Cmd(TIM4, ENABLE);  //使能TIMx  }else TIM_Cmd(TIM4, DISABLE);//关闭定时器4
}
//通用定时器中断初始化
//这里始终选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
void TIM4_Init(u16 arr,u16 psc)
{   NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能//TIM4时钟使能    //定时器TIM4初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值  TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIMx更新中断标志 TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;       //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器   }
#endif
///USART3 DMA发送配置部分//
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHx:DMA通道CHx
//cpar:外设地址
//cmar:存储器地址
void UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar)
{DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);   //使能DMA传输DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设DMA_InitStructure.DMA_BufferSize = 0;  //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
}
//开启一次DMA传输
void UART_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u8 len)
{DMA_Cmd(DMA_CHx, DISABLE );  //关闭 指示的通道        DMA_SetCurrDataCounter(DMA_CHx,len);//DMA通道的DMA缓存的大小    DMA_Cmd(DMA_CHx, ENABLE);           //开启DMA传输
}//定时器4中断服务程序
void TIM4_IRQHandler(void)
{   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中断{             TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  //清除TIMx更新中断标志    TIM4_Set(0);         //关闭TIM4  }
}// 串口3中断函数
void USART3_IRQHandler(void)
{u8 res;        if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据{  res =USART_ReceiveData(USART3);        if(point2<USART3_MAX_RECV_LEN)       //还可以接收数据{TIM_SetCounter(TIM4,0);//计数器清空                         if(USART3_RX_STA==0){TIM4_Set(1);        //使能定时器4的中断 USART3_RX_BUF[point2++]=res;     //记录接收到的值   }}}
}

连接TCP初始化代码(前提:模块已经启动):

u8 L206_TCP_init(void)
{
// 测试模块连接情况 if (sendCommand("AT\r\n", "OK\r\n", 3000, 5) == Success);else errorLog(1);delay_ms(10);// 关闭回显sendCommand("ATE0\r\n", "OK\r\n", 1000, 1);// 获取国际移动台设备识别码if (sendCommand("AT+CGSN\r\n", "OK\r\n", 1000, 5) == Success);else errorLog(1);delay_ms(10);    // 获取信号质量if (sendCommand("AT+CSQ\r\n", "+CSQ: ", 1000, 5) == Success);else errorLog(1);delay_ms(10);    // 启用回显sendCommand("ATE1\r\n", "OK\r\n", 1000, 1);// 确认SIM卡的PIN码是否已经解开if (sendCommand("AT+CPIN?\r\n", "READY", 3000, 5) == Success);else errorLog(2);delay_ms(10);  // 确认模块找网是否成功if (sendCommand("AT+CREG?\r\n", "0,1", 2000, 10) == Success);else errorLog(3);delay_ms(10); // 确保模块GPRS附着是否成功if (sendCommand("AT+CGATT?\r\n", "1", 10000, 5) == Success);else errorLog(4);delay_ms(10);// 配置为单连方式if (sendCommand("AT+CIPMUX=0\r\n", "OK\r\n", 1000, 3) == Success);else errorLog(5);delay_ms(10);// 开启TCPSSL模式,服务器未加密不需要,否则连不上
//    if (sendCommand("AT+CIPSSL=1\r\n", "OK\r\n", 1000, 3) == Success);
//    else  errorLog(6);
//    delay_ms(10);    // 设置APN名称if (sendCommand("AT+CSTT=\"CMNET\"\r\n", "OK\r\n", 1000, 3) == Success);else errorLog(7);delay_ms(10);// 激活PDP场景if (sendCommand("AT+CIICR\r\n", "OK\r\n", 1000, 3) == Success);else   errorLog(8);delay_ms(10);// 获取本地IPif (sendCommand("AT+CIFSR\r\n", "AT+CIFSR\r\n", 1000, 3) == Success);else errorLog(9);delay_ms(10);    // 连接服务器 103.46.128.43:18921if (sendCommand("AT+CIPSTART=\"TCP\",\"103.46.128.43\",\"18921\"\r\n", "OK\r\n", 5000, 5) == Success);else   errorLog(10);delay_ms(10);    // 连接状态查询if (sendCommand(" AT+CIPSTATUS\r\n", "OK\r\n", 1000, 5) == Success);else  errorLog(11);delay_ms(10);return Success;
}

其中函数sendCommand()实现如下:

// 发送命令
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry)
{unsigned char n;int i = 0;USART3_CLR_Buf();for (n = 0; n < Retry; n++){u3_printf(Command);      //发送GPRS指令Time_Cont = 0;while (Time_Cont < Timeout){delay_ms(100);Time_Cont += 100;if (strstr(USART3_RX_BUF, Response) != NULL){ // 获取模块串号if(strcmp(Command,"AT+CGSN\r\n") == 0){             for(i = 0; i < 15; i++){UID[i] = USART3_RX_BUF[2+i];}                    }// 获取模块信号强度else if(strcmp(Command,"AT+CSQ\r\n") == 0){             for(i = 0; i < 5; i++){rssi_ber[i] = USART3_RX_BUF[8+i];}                    }USART3_CLR_Buf();return Success;}}USART3_CLR_Buf();Time_Cont = 0;}USART3_CLR_Buf();return Failure;
}

函数errorLog();实现如下:

// 软件复位系统
void Sys_Soft_Reset(void)
{
//    SCB->AIRCR =0X05FA0000|(u32)0x04;    __set_FAULTMASK(1);NVIC_SystemReset();
}void errorLog(int num)
{while (1){if(sendCommand("AT\r\n", "OK\r\n", 100, 10) == Success){Sys_Soft_Reset();}delay_ms(200);}
}

至此,移柯L206模块TCP开发也就完成了。

物联网-移柯L206模块TCP开发(基于STM32+AT命令)相关推荐

  1. 物联网-移远M26模块OpenCPU开发第3讲(看门狗)

    之前在物联网-移远M26模块OpenCPU开发第1讲中提到过需要给外部看门狗芯片喂狗才能正常工作,阅读过的读者应该知道,我是通过周期性的控制M26的一个GPIO引脚电平变化来实现喂狗的.关于其硬件参考 ...

  2. 物联网-移远M26模块MQTT开发(AT命令)

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分.该协议支持所有平台,几乎可以把所有联 ...

  3. 物联网-移远M26模块OpenCPU开发第1讲

    心心恋恋的基于移远M26模块设计的用于开发OpenCPU功能的板子终于完成,废话少说,直接上图: 对于板子外观这里不作讨论,毕竟不是我设计的,期望能用吧. 可能是由于设计者经验不足的原因吧.我刚拿到板 ...

  4. 物联网-移远M26模块OpenCPU开发第2讲(FLASH处理)

    最近有个项目,需要频繁的操作移远M26的内部flash.众所周知,flash的擦写次数为10W次,超过这个次数后flash就没有用了.这个项目需要频繁的对其进行写操作,要想设备工作3~5年,10W明显 ...

  5. 智能手环功能模块设计_基于STM32实现智能手环设计

    龙源期刊网 http://www.qikan.com.cn 基于 STM32 实现智能手环设计 作者:付海生 陈婷婷 韩百科 涂曾兵 来源:<科学导报 · 学术> 2017 年第 10 期 ...

  6. stm32f407 6路串口dma如何配置_stm32cubeMX学习十、扫码模块程序开发(基于正点原子STM32F407开发板)...

    本程序编写基于正点原子STM32F407开发板. 本文使用的扫码模块是下面这个品牌. 扫码模块的应用场景非常广泛,我们可以上百度搜索一下: 等等. 今天就来说说如何在开发板上实现控制它吧,打开数据手册 ...

  7. 【河南省第二届技能大赛-物联网技术】C模块Python开发讲解

    文章目录 前言 题目如下 什么是云平台API API调用的基本流程 Python实例介绍 依赖库介绍 API调用的基本参数 请求返回值 requests库 PyQt5库 总结 源码链接 前言 这是基于 ...

  8. 基于stm32的linux开发的书籍,跟工程师学嵌入式开发:基于STM32和μC OS-Ⅲ 带目录高清版pdf...

    本书选用的STM32芯片基于ARM Cortex-M3体系结构,根据基于MCU的嵌入式技术实际应用需求,合理地选择了多种常用的重要外设接口,如USART.SPI.I2C.FSCM.SDIO总线.以太网 ...

  9. 【LVGL应用开发--基于STM32】第1章 初识LVGL

    文章目录 前言 1.1 LVGL简介 1.2 LVGL移植要求 1.3 LVGL源码下载与介绍 前言 在实际应用中,我们时常需要制作 UI 界面来实现人机交互,简单的 UI 可以直接编写代码,但对于那 ...

最新文章

  1. JQuery 动态创建表单,并自动提交
  2. 大道至简第四章流于形式的沟通——读后感
  3. .net 读word中文字方法
  4. 配置 LBaaS - 每天5分钟玩转 OpenStack(121)
  5. KlayGE中的FXAA已经完成
  6. java排序算法代码_Java实现八种排序算法(代码详细解释)
  7. ashx获取客户端excel文件_Spring Boot实现导出Excel功能
  8. 使用 std::shared_ptr 和 std::unique_ptr 测试 boost/pointer_cast.hpp
  9. 如何在SAP CRM WebClient UI里创建HANA Live Report
  10. android什么是回调,Android中的回调是什么?
  11. MySQL单表删除重复列SQL语句
  12. Eclipse 安装教程附免费安装包资源
  13. java retainAll
  14. (二十六)树莓派3B+ 获取HMC5883L的磁场数据
  15. 他是中国最牛X的黑客,曾让6个国家束手无策,却被怀疑是精神病
  16. 删掉启动分区进不了系统,复活办法(win10)
  17. 服务器usb驱动安装系统安装失败怎么办,USB3.0驱动无法安装失败怎么办?USB驱动失败失败的解决方法...
  18. newifi mini php,NewFi(newifi mini华硕固件)
  19. zencart模板制作步骤详解
  20. 【后端】Nginx 体系

热门文章

  1. 计算机网络与传统的通信网络的最大区别,3G,4G技术3G与传统通信技术的主要区别?主要特色?另对4G稍 爱问知识人...
  2. 天津农学院计算机考研专业,2021年天津农学院计算机与信息工程学院考研专业目录_研究生考试范围 - 学途吧...
  3. c语言程序设计第二版课后答案 机械工业出版社,C语言程序设计 第2版
  4. python求极值(极大值、极小值)
  5. linux安装.AppImage后缀安装包
  6. 嵌入网站的挖矿代码——Webmine
  7. java+getactionmap_Struts2 使用OGNL遍历map方法详解
  8. php 模型 关联,PHP模型关联一对多如何给关联表加条件?
  9. cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔
  10. 九、装配bean--通过properties文件注入值