草庐IT

STM32开发 | 移远4G-Cat.1模组EC200N-CN开发

`Eliauk 2024-07-28 原文

一、硬件说明

1、引脚分配图

2、常用引脚说明

  • 模块输入电源

    引脚名描述
    VBAT_BB模块基带电源(Vnom = 3.8 V)
    VBAT_RF模块射频电源(Vnom = 3.8 V)
    GND接地引脚
  • 模块输出电源

    引脚名描述
    VDD_EXT外部电路 1.8 V 供电(Vnom = 1.8 V)
  • 开/关机

    引脚名描述
    RESET_N模块复位(低电平有效,1.8 V 电压域,不用则悬空。)
    PWRKEY模块开/关机 (VBAT 电压域)
  • SIM 接口

    引脚名描述
    USIM_VDD(U)SIM 供电电源(模块自动识别 1.8 V或 3.0 V (U)SIM 卡。)
    USIM_DATA(U)SIM 数据
    USIM_CLK(U)SIM 时钟
    USIM_RST(U)SIM 复位
  • 主串口

    引脚名描述
    MAIN_TXD主串口发送(1.8 V 电压域)
    MAIN_RXD主串口接收(1.8 V 电压域)
  • 天线接口

    引脚名描述
    ANT_MAIN主天线接口(50 Ω 特性阻抗)

二、常用AT指令说明

1、AT

  • 说明: 检测AT指令收发是否正常
  • 模组收到指令回复:
    AT
    OK
    

2、AT+CPIN?

  • 说明: 查询SIM卡状态(是否插入SIM卡、锁定SIM卡、解锁SIM卡),返回 READY则表示模组正常
  • 模组收到指令回复:
    AT+CPIN?
    +CPIN: READY
    
    OK
    

3、AT+CREG?

  • 说明: 查询当前网络注册状态,正常则回复 +CREG: 0,1
  • 模组收到指令回复:
    AT+CREG?
    +CREG: 0,1
    
    OK
    

4、AT+CEREG?

  • 说明: 查询当前EPS网络注册状态,正常则回复 +CEREG: 0,1
  • 模组收到指令回复:
    AT+CEREG?
    +CEREG: 0,1
    
    OK
    

5、AT+QICSGP=1,1,“CMNET”,“”,“”,0

  • 说明: 配置 TCP/IP 场景1参数,指令原型为AT+QICSGP=<contextID>,<context_type>,<apn>,<username>,<password>,<authentication>;

  • 模组收到指令回复:

    AT+QICSGP=1,1,"CMNET","","",0
    OK
    
  • 参数说明:

    参数说明
    contextID整型。移动场景 ID。范围:1~15。
    context_type整型。协议类型。(1 IPv4 \ 2 IPv6 \ 3 IPv4v6)
    APN字符串类型。接入点名称。(CMNET 中国移动 \ CTNET 中国电信 \ UNINET 中国联通)
    username字符串类型。用户名。最大长度:127 字节。
    password字符串类型。密码。最大长度:127 字节。
    authentication整型。APN 鉴权方式。(0 None \ 1 PAP \ 2 CHAP \ 3 PAP 或 CHAP)

6、AT+QIACT=1

  • 说明: 激活移动场景1配置,正常则回复 OK,指令原型为AT+QIACT=<contextID>;
  • 模组收到指令回复:
    AT+QIACT=1
    OK
    

7、AT+QIOPEN=1,0,“TCP”,“112.168.19.12”,28014,0,2

  • 说明: 打开socket建立TCP连接并进入透传模式,指令原型为AT+QIOPEN=<contextID>,<connectI D>,<service_type>,"<IP_address>/<domain_name>",<remote_port>[,<local_port>[,<access_mode>]]

  • 模组收到指令回复:

    AT+QIOPEN=1,0,"TCP","112.168.19.12",28014,0,2
    CONNECT
    
  • 参数说明:

    参数说明
    contextID整型。移动场景 ID。范围:1~15。
    connectID整型。Socket ID。范围:0~11。
    service_type字符串类型。Socket 服务类型。(“TCP” \ “UDP” \ “TCP LISTENER” \ “UDP SERVICE”)
    IP_address字符串类型。(如果 service_type 是 “TCP” 或者 “UDP”, 则为远程服务器的IP地址,例如112.168.19.12。如果service_type是"TCP LISTENER"或者"UDP SERVICE",请输入 127.0.0.1。)
    domain_name字符串类型。远程服务器的域名地址。
    remote_port整型。远程服务器端口。范围:0~65535。仅当service_type是"TCP"或者"UDP"时才有效。
    local_port整型。本地端口。范围:0~65535。(如果service_type是"TCP LISTENER"或者"UDPSERVICE",该参数必须指定。如果service_type是 “TCP” 或者 “UDP”,且local_port是 0,那么将会自动分配本地端口;否则本地端口会被指定。)
    access_mode整型。Socket 服务的数据访问模式。(0 缓存模式 \ 1 直吐模式 \ 2 透传模式)
  • 透传模式说明

    透传模式下,相对应的串口(比如 UART 口、USB Modem 口等)会进入独占模式,通过 COM 口接收的数据会直接发送到网络端,从网络接收到的数据会从 COM 口直接输出。+++可以用来退出透传模式:当输入+++返回 OK 后,访问模式就会切换到缓存模式,如需切换回透传模式,可使用AT+QISWTMD命令。

  • 退出透传模式

    用户可以通过+++或者 DTR(需先设置 AT&D1)两种方式退出透传模式,为了防止+++被当成数据发送,实际操作时必须遵循以下步骤:

    • +++输入前 1 秒或更长时间内不能输入其它任何数据;
    • 必须在 1 秒内输入+++,并且不能输入其它任何数据;
    • +++输入后 1 秒内不能输入其它任何数据;
    • 通过+++或者 DTR(设置 AT&D1)方式使模块退出透传模式,直到模块返回 OK;此时模块成功退出透传模式。
  • 在透传模式下,不可执行 AT 命令。 若因网络错误或者其他原因导致 Socket 连接断开,模块会上报 NO CARRIER,并退出透传模式,在这种情况下可以执行 AT+QICLOSE 来关闭 Socket 服务。

三、实现流程

Created with Raphaël 2.3.0 开始 模块开机 模块初始化 初始化成功? 激活移动场景 场景激活成功? 打开socket建立TCP连接并进入透传模式 通过网络与串口助手进行通信测试 结束 yes no yes no

四、程序代码

  • 串口发送代码

    #include "stm32f10x.h"
    #include "stm32f10x_conf.h"
    
    /**
      * @brief  串口1发送字符串
      * @param  pStr: 字符串指针
      * @retval None
      */
    void USART1_SendStr(char *pStr)
    {
    	uint8_t tx_str;
    	while(1)
    	{
    		tx_str = *pStr++;
    		if(tx_str == 0) break;
    		USART_ClearFlag(USART1, USART_FLAG_TC);
    		USART_SendData(USART1, tx_str);
    		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    	}
    }
    
    /**
      * @brief  串口2发送字符串
      * @param  pStr: 字符串指针
      * @retval None
      */
    void USART2_SendStr(char *pStr)
    {
    	uint8_t tx_str;
    	while(1)
    	{
    		tx_str = *pStr++;
    		if(tx_str == 0) break;
    		USART_ClearFlag(USART2, USART_FLAG_TC);
    		USART_SendData(USART2, tx_str);
    		while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
    	}
    }
    
    /**
      * @brief  串口1发送命令帧
      * @param  pcmd: 命令帧指针
      * 		count: 命令帧长度
      * @retval None
      */
    void USART1_SendCmd(uint8_t *pcmd, uint16_t count)
    {
    	uint8_t tx_cmd;
    	uint16_t i;
    	for(i=0; i < count; i++)
    	{
    		tx_cmd = *pcmd++;
         	USART_ClearFlag(USART1, USART_FLAG_TC);
    		USART_SendData(USART1, tx_cmd);
    		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    	}
    }
    
    
  • EC200N-CN驱动程序

    /**
      * @brief  EC200N-CN初始化
      * @param  step: 步骤
      * @retval step: 步骤值
      */
    uint16_t LTEUECat1Init(uint16_t step)
    {
    	switch(step)
    	{
    		case 0:
    			//查询AT指令是否正常
    			SendCmd("AT\r\n", "OK", "Error: AT\r\n", 10, step);
    			if(step == 0) break;
    		case 1:
    			//检测SIM卡状态
    			SendCmd("AT+CPIN?\r\n", "+CPIN: READY", "Error: AT+CPIN?\r\n", 2, step);
    			if(step == 1) break;
    		case 2:
    			//查询当前网络注册状态
    			SendCmd("AT+CREG?\r\n", "+CREG: 0,1", "Error: AT+CREG?\r\n", 1, step);
    			if(step == 2) break;
    		case 3:
    			//查询当前EPS网络注册状态
    			SendCmd("AT+CEREG?\r\n", "OK", "Error: AT+CEREG?\r\n", 1, step);
    			if(step == 3) break;
    		case 4:
    			//配置移动场景参数
    			SendCmd("AT+QICSGP=1,1,\"CMNET\",\"\",\"\",0\r\n", "OK", "Error: AT+QICSGP\r\n", 1, step);
    			if(step == 4) break;
    		default: break;
    	}
    	if(step == 4)
    	{
    		//激活移动场景
    		USART2_SendStr("AT+QIACT=1\r\n");
    		//等待30s
    		while(3000--)
    		{
    			if(strstr((const char*)com2_rx_buffer, "OK") != NULL)
    			{
    				step = 5;
    				break;
    			}
    			else delay_ms(100);
    		}
    	}
    	return step;
    }
    
    /**
      * @brief  发送AT指令进行初始化
      * @param  cmd: 命令帧指针
      * 		echo: 判断字收到的数据中所出现的字符
      * 		num: 发送命令帧的次数
      * 		count: 返回值
      * @retval None
      */
    uint16_t SendCmd(char *cmd, char *echo, char *error, uint16_t num, uint16_t count)
    {
    	for(int i = 0; i < num; i++)
    	{
    		USART2_SendStr(cmd);
    		//延时1秒
    		delay_ms(1000);
    		//判断接收到的数据中是否存在指定字符
    		if(strstr((const char*)com2_rx_buffer, echo) != NULL) 
    		{
    			//向串口输出USART2接收到的数据
    			USART1_SendStr(echo);
    			//初始化缓存
    			memset(com2_rx_buffer, 0, sizeof(com2_rx_buffer));
    			count++;
    			return count;
    		}else
    		{
    			USART1_SendStr(error);
    		}
    	}
    	return 0;
    }
    
    /**
      * @brief  连接网络
      * @param  None
      * @retval None
      */
    void LTEUECat1Connect(void)
    {
    	short times = 3000;
    	USART2_SendStr("AT+QIOPEN=1,0,\"TCP\",\"112.168.19.12\",28014,0,2\r\n");
    	while(times--)
    	{
    		if(strstr((const char*)com2_rx_buffer, "CONNECT") != NULL)
    		{
    			USART1_SendStr("Connect OK!\r\n");
    			break;
    		}
    		else delay_ms(100);
    	}
    }
    

五、例程说明

  • STM32芯片串口USART2与EC200N-CN串口MAIN_TXD跟MAIN_RXD
  • 串口通讯采用DMA中断模式
  • ECC200N-CN默认串口通讯速率为115200

有关STM32开发 | 移远4G-Cat.1模组EC200N-CN开发的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  10. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

随机推荐