A600-CAT1(04)-4G模块
A600-CAT1(04)-TTL 是 一 款 支 持 TDD-LTE(B34/B38/B39/B40/B41) 、 FDDLTE(B1/B3/B5/B8),并具有高稳定性,工业级全网通无线通信模块。模块支持 TCP/UDP 透传模式,可以在各个领域得到广泛运用。模块支持 modbus RTU 与 modbus TCP 两种协议的自动转换,提高了设备互联兼容性。模块支持 MQTT 透传模式,可连接标准 mqtt 服务器、阿里云服务器和 OneNet 服务器,可广泛应用到物联网设备上。模块使用串口 AT 指令配置参数。
模块来源
采购链接:
https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-15265445661.16.3f542862qz2oIa&id=684577334513
资料下载:
http://www.ashining.com/data.aspx?t=15&typeid=155&keywords=cat1(04)-TTL#proid
规格参数
工作电压:有两个电压输入(同一时间只可以输入一个电压)
VCC输入电压:5V-16V
BAT输入电压:3.4V-4.2V
工作电流:
电压是VCC时,20mA-500mA
电压是BAT时,60mA-1.58A
4G全网通数据网络
控制方式:串口
移植过程
我们的目标是在立创开发板GD32E230C8T6上能够完成无线传输的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
查看资料
该模块使用网络是通过物联网卡提供流量,物联网卡链接:
所以例程都在官方的上位机实现,可以通过上位机操作。先通过上位机配置成功之后,根据查看上位机的指令,就可以知道对应模式下如何操作。这里提供阿里云MQTT配置步骤,其余可以参考数据手册进行配置。
1. 获取阿里云三元素
阿里云产品的创建与配置见目录ESP-01S WIFI模块的案例二,创建阿里云完成之后来到设备调试界面点击设备证书,将弹出的3个元素保存下来。3个元素分别是ProductKey、DeviceName、DeviceSecret。
2. 配置上位机
将设备按照目录 引脚选择 接好线。连接上位机。并往梁山派烧录以下我提供的代码。该代码的主要功能是将串口0接收到的数据发送给串口2,串口2接收到的数据发送给串口0。这样我们就可以实现一个USB转TTL模块了。
点击 进入配置模式。
配置阿里云向导
- 根据你插入的SIM卡选择对应的运营商,我是中国移动
选择232接口
串口配置默认不动。
将之前保存的阿里云三元素,填入。
- 选择订阅和发布。填充你自己的 productKey 和 deviceName。
订阅 Topic:/sys/{productKey}/{deviceName}/thing/service/property/set
发布 Topic:/sys/{productKey}/{deviceName}/thing/event/property/post
- 等待配置完成。
点击设备复位,设备复位好之后,我们就不再需要修改了。
3.12.3.2 引脚选择
使用串口1(串口1-TX=PA2,串口1-RX=PA3)
移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_a600cat1.c与bsp_a600cat1.h。移植完成后面修改相关代码。
详细可见【TTP224触摸传感器】中的移植至工程目录。这里不再过多讲述。移植完成后面修改相关代码。
工程参考入门手册工程模板
在文件bsp_a600cat1.c中,编写如下代码。
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "bsp_a600cat1.h"
#include "stdio.h"
#include "string.h"
unsigned char A600CAT1_RX_BUFF[];
unsigned char A600CAT1_RX_FLAG = 0;
unsigned char A600CAT1_RX_LEN = 0;
/*
AT+UTWKMODE=WORK\r\n //设置模式为通讯模式
AT+UTICCID=?\r\n //查询SIM卡是否插入,插入则返回ID码。
AT+NETCSQ=?\r\n //查询信号强度
AT+UTCHMODE1=MQTT\r\n //设置为MQTT模式
AT+UART1=115200,8,1,NONE,1024,5\r\n //设置通讯波特率115200
AT+MQTTMODE1=ALIYUN\r\n //设置MQTT模式为阿里云模式
AT+MQTTUSER1="a144x57BRYZ"\r\n //设置MQTT用户秘钥
AT+MQTTCLIENTID1="TEST"\r\n //设置用户MQTTID
AT+MQTTPWD1="92d295478378f61db21333811555922f"\r\n
AT+MQTTOPT1=60,CLEAN\r\n
AT+MQTT1SUB1="/sys/a144x57BRYZ/TEST/thing/service/property/set",0\r\n
AT+MQTT1PUB1="/sys/a144x57BRYZ/TEST/thing/event/property/post",0,FALSE\r\n
AT+NETAPN="CMNET","","",DEFAULT\r\n
*/
/************************************************************
* 函数名称:A600CAT1_USART_Init
* 函数说明:连接A600CAT1的初始化
* 型 参:bund=串口波特率
* 返 回 值:无
* 备 注:无
*************************************************************/
void A600CAT1_USART_Init(unsigned int bund)
{
/* 使能 A600CAT1_USART 的时钟 */
rcu_periph_clock_enable(RCU_A600CAT1_USART);
/* 使能时钟 */
rcu_periph_clock_enable(RCU_A600CAT1_TX);
rcu_periph_clock_enable(RCU_A600CAT1_RX);
/* 配置引脚为复用功能 */
gpio_af_set(PORT_A600CAT1_TX, BSP_A600CAT1_AF, GPIO_A600CAT1_TX);
/* 配置引脚为复用功能 */
gpio_af_set(PORT_A600CAT1_RX, BSP_A600CAT1_AF, GPIO_A600CAT1_RX);
/* 配置TX引脚为复用上拉模式 */
gpio_mode_set(PORT_A600CAT1_TX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_A600CAT1_TX);
/* 配置RX引脚为复用上拉模式 */
gpio_mode_set(PORT_A600CAT1_RX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_A600CAT1_RX);
/* 配置PA2引脚为为输出模式 */
gpio_output_options_set(PORT_A600CAT1_TX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_A600CAT1_TX);
/* 配置PA3引脚为为输出模式 */
gpio_output_options_set(PORT_A600CAT1_RX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_A600CAT1_RX);
/* 设置A600CAT1_USART的波特率为115200 */
usart_baudrate_set(A600CAT1_USART, bund);
/* 设置A600CAT1_USART的校验位为无 */
usart_parity_config(A600CAT1_USART, USART_PM_NONE);
/* 设置A600CAT1_USART的数据位为8位 */
usart_word_length_set(A600CAT1_USART, USART_WL_8BIT);
/* 设置A600CAT1_USART的停止位为1位 */
usart_stop_bit_set(A600CAT1_USART, USART_STB_1BIT);
/* 使能串口1 */
usart_enable(A600CAT1_USART);
/* 使能A600CAT1_USART传输 */
usart_transmit_config(A600CAT1_USART, USART_TRANSMIT_ENABLE);
/* 使能A600CAT1_USART接收 */
usart_receive_config(A600CAT1_USART, USART_RECEIVE_ENABLE);
/* 使能A600CAT1_USART接收中断标志位 */
usart_interrupt_enable(A600CAT1_USART, USART_INT_RBNE);
/* 使能A600CAT1_USART空闲中断标志位 */
usart_interrupt_enable(A600CAT1_USART, USART_INT_IDLE); // DLE 线检测中断
/* 配置中断优先级 */
nvic_irq_enable(A600CAT1_USART_IRQ, 2); // 配置中断优先级
}
/******************************************************************
* 函 数 名 称:A600CAT1_USART_Send_Bit
* 函 数 说 明:向A600CAT1模块发送单个字符
* 函 数 形 参:ch=字符
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void A600CAT1_USART_Send_Bit(unsigned char ch)
{
//发送字符
usart_data_transmit(A600CAT1_USART, ch);
// 等待发送数据缓冲区标志自动置位
while(RESET == usart_flag_get(A600CAT1_USART, USART_FLAG_TBE) );
}
/******************************************************************
* 函 数 名 称:A600CAT1_USART_send_String
* 函 数 说 明:向A600CAT1模块发送字符串
* 函 数 形 参:str=发送的字符串
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void A600CAT1_USART_send_String(unsigned char *str)
{
while( str && *str ) // 地址为空或者值为空跳出
{
// printf("%c", *str);
A600CAT1_USART_Send_Bit(*str++);
}
}
//清除串口接收的数据
/******************************************************************
* 函 数 名 称:Clear_A600CAT1_RX_BUFF
* 函 数 说 明:清除A600CAT1发过来的数据
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void Clear_A600CAT1_RX_BUFF(void)
{
unsigned char i = A600CAT1_RX_LEN_MAX-1;
while(i)
{
A600CAT1_RX_BUFF[] = 0;
}
A600CAT1_RX_LEN = 0;
A600CAT1_RX_FLAG = 0;
}
/******************************************************************
* 函 数 名 称:A600CAT1_Send_Cmd
* 函 数 说 明:向A600CAT1模块发送指令,并查看A600CAT1模块是否返回想要的数据
* 函 数 形 参:cmd=发送的AT指令 ack=想要的应答 waitms=等待应答的时间 cnt=等待应答多少次
* 函 数 返 回:1=得到了想要的应答 0=没有得到想要的应答
* 作 者:LC
* 备 注:无
******************************************************************/
char A600CAT1_Send_Cmd(char *cmd,char *ack,unsigned int waitms,unsigned char cnt)
{
A600CAT1_USART_send_String((unsigned char*)cmd);//1.发送AT指令
while(cnt--)
{
//时间间隔
delay_1ms(waitms);
//串口中断接收A600CAT1应答
if( A600CAT1_RX_FLAG == 1 )
{
A600CAT1_RX_FLAG = 0;
A600CAT1_RX_LEN = 0;
//查找是否有想要的数据
if( strstr((char*)A600CAT1_RX_BUFF, ack) != NULL )
{
return 1;
}
//清除接收的数据
memset( A600CAT1_RX_BUFF, 0, sizeof(A600CAT1_RX_BUFF) );
}
}
A600CAT1_RX_FLAG = 0;
A600CAT1_RX_LEN = 0;
return 0;
}
/******************************************************************
* 函 数 名 称:A600CAT1_Init
* 函 数 说 明:A600CAT1模块初始化
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:ESP01S的默认波特率是115200
******************************************************************/
void A600CAT1_Init(void)
{
A600CAT1_USART_Init(115200);//默认波特率为115200
}
/*点击LED开关
+MQTTSUBRECV:0,"/sys/a1PJRLOWo3p/TEST/thing/service/property/set",100,
{"method":"thing.service.property.set","id":"367399823","params":{"LED_Switch":1},"version":"1.0.0"}
*/
/*滑动亮度条
+MQTTSUBRECV:0,"/sys/a1PJRLOWo3p/TEST/thing/service/property/set",101,
{"method":"thing.service.property.set","id":"812539841","params":{"brightness":75},"version":"1.0.0"}
*/
/******************************************************************
* 函 数 名 称:Get_Aliyun_json_data
* 函 数 说 明:获取阿里云JSON格式的数据(接收手机发送过来的数据)
* 函 数 形 参:data=数据的保存地址
* 函 数 返 回:1=接收到JSON数据并处理 0=没有接收到数据
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t Get_Aliyun_json_data(JSON_PUBLISH *data)
{
char *buff=0;
//串口中断接收A600CAT1应答
if( A600CAT1_RX_FLAG == SET )
{
printf("\r\n--\r\n");
A600CAT1_RX_FLAG = 0;
A600CAT1_RX_LEN = 0;
//有设备连接了热点
if( strstr((char*)A600CAT1_RX_BUFF, "params\":") != NULL )
{
//获取功能名称
buff = strstr((char*)A600CAT1_RX_BUFF, "params\":");
buff += strlen("params\":{\"");
strcpy(data->keyname,strtok(buff,"\""));
printf("data->keyname = %s\r\n",data->keyname);
//获取功能值
buff = strstr((char*)A600CAT1_RX_BUFF, "params\":" );
buff += strlen("params\":{\"")+strlen(data->keyname)+2;
strcpy(data->value, strtok(buff,"}"));
return 1;
}
}
return 0;
}
/******************************************************************
* 函 数 名 称:Clear_Aliyun_json_data
* 函 数 说 明:清除JSON接收过的数据
* 函 数 形 参:data=要清除的数据
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void Clear_Aliyun_json_data(JSON_PUBLISH *data)
{
uint16_t i = 0;
while( data->keyname[] != 0 )
{
data->keyname[] = '\0';
}
i= 0;
while( data->value[] != 0 )
{
data->keyname[] = '\0';
}
}
/******************************************************************
* 函 数 名 称:A600CAT1_USART_IRQHandler
* 函 数 说 明:连接A600CAT1的串口中断服务函数
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void A600CAT1_USART_IRQHandler(void)
{
if(usart_interrupt_flag_get(A600CAT1_USART,USART_INT_FLAG_RBNE) != RESET) // 接收缓冲区不为空
{
//接收数据
A600CAT1_RX_BUFF[] = usart_data_receive(A600CAT1_USART);
#if DEBUG
//测试,查看接收到了什么数据
printf("%c", A600CAT1_RX_BUFF[]);
#endif
//接收长度限制
A600CAT1_RX_LEN = ( A600CAT1_RX_LEN + 1 ) % A600CAT1_RX_LEN_MAX;
}
if(usart_interrupt_flag_get(A600CAT1_USART,USART_INT_FLAG_IDLE) == SET) // 检测到空闲中断
{
usart_data_receive(A600CAT1_USART); // 必须要读,读出来的值不能要
A600CAT1_RX_BUFF[] = '\0'; //字符串结尾补 '\0'
A600CAT1_RX_FLAG = SET; // 接收完成
usart_interrupt_flag_clear(USART1, USART_INT_FLAG_IDLE);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
在文件bsp_a600cat1.h中,编写如下代码。
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#ifndef _BSP_A600CAT1_H_
#define _BSP_A600CAT1_H_
#include "gd32e23x.h"
#include "string.h"
#include "systick.h"
//是否开启串口0调试,查看WIFI回显数据
#define DEBUG 1
//上传数据结构体
typedef struct
{
char keyname[]; //键读取
char value[]; //读取到的值,类型字符串
}JSON_PUBLISH;
#define A600CAT1_RX_LEN_MAX 250 //串口接收最大长度
/**************************** 串口配置 ****************************/
#define RCU_A600CAT1_TX RCU_GPIOA // 串口TX的端口时钟
#define RCU_A600CAT1_RX RCU_GPIOA // 串口RX的端口时钟
#define RCU_A600CAT1_USART RCU_USART1 // 串口1的时钟
#define PORT_A600CAT1_TX GPIOA // 串口TX的端口
#define PORT_A600CAT1_RX GPIOA // 串口RX的端口
#define GPIO_A600CAT1_TX GPIO_PIN_2 // 串口TX的引脚
#define GPIO_A600CAT1_RX GPIO_PIN_3 // 串口RX的引脚
#define BSP_A600CAT1_AF GPIO_AF_1 // 串口1的复用功能
#define A600CAT1_USART USART1 // 串口1
#define A600CAT1_USART_IRQ USART1_IRQn // 串口1中断
#define A600CAT1_USART_IRQHandler USART1_IRQHandler // 串口1中断服务函数
void A600CAT1_Init(void);
uint8_t Get_Aliyun_json_data(JSON_PUBLISH *data);
void Clear_Aliyun_json_data(JSON_PUBLISH *data);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
移植验证
在main.c中编写以下代码。(确保.c和.h已经按照以上进行移植)
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "gd32e23x.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "BSP_a600cat1.h"
//LED测试
void LED_GPIO_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_13);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
gpio_bit_write(GPIOC,GPIO_PIN_13,RESET);//灭灯状态
}
int main(void)
{
JSON_PUBLISH sta_json_data={0};
systick_config(); //滴答定时器初始化 1ms
LED_GPIO_Init();//LED初始化
usart_gpio_config(115200U);
printf("start\r\n");
A600CAT1_Init();
while(1)
{
//获取数据
Get_Aliyun_json_data(&sta_json_data);
//如果开关按下
if( strstr( sta_json_data.keyname,"powerstate") != NULL )
{
if( strstr( sta_json_data.value,"0") != NULL) //发来的数据是0
{
gpio_bit_write(GPIOC,GPIO_PIN_7,RESET);//灭灯
printf("\r\nCrush out!!!\r\n");
}
if( strstr( sta_json_data.value,"1") != NULL)//发来的数据是1
{
gpio_bit_write(GPIOC,GPIO_PIN_7,SET);//亮灯
printf("\r\nLight!!!!\r\n");
}
Clear_Aliyun_json_data(&sta_json_data);//清除数据
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
实验现象:根据手机的操作实现开关灯。