3.17 安信可 Ai-WB2-01S 模块(来自 zhikun 的贡献)
模块来源
资料下载: https://docs.ai-thinker.com/wb2
规格参数
工作电压:3.3V
工作电流:>500mA
通信接口:UART
引脚数量:8
Combo-AT-Guide ‒ 安信可科技 documentation该模块 AT 指令集
模块原理图
管脚说明
应用电路指导
1-如果 IO 口作为 PWM 使用,建议在模组外围预留 4.7K 的下拉电阻。尤其是灯控方面
的应用,防止上电启动的瞬间出现闪灯现象。
2- IO8/NC、RST/NC 脚,默认不可使用。如需使用,请联系安信可。
模块实际图
移植工程
引脚选择
| Ai-WB2-01S | 立创-梁山派 |
|---|---|
| TX | PB11 |
| RX | PB10 |
| 3V3 | 3V3 |
| GND | GND |
移植步骤
按照引脚选择进行 IO 配置和驱动,编写驱动函数,最后通过手机蓝牙控制 APP 去控制蓝牙模块告知开发板进行 LED2 亮灭控制。这里为了节省时间直接在立创开发板的资料中(梁山 Pi 开发板资料\资源包\08 代码例程-视频注释版-GD32F470 版\005 串口打印信息)005 例子作为工程模板进行开发。
Ai-WB2-01S 固件更新
最新固件下载:
https://docs.ai-thinker.com/wb2
如下图所示,不要选择错误:
本人已下载最新固件,如下:
下载工具
https://docs.ai-thinker.com/wb2
下载最新的烧写工具
本人已经下载,如下
固件下载方法:
https://aithinker.blog.csdn.net/article/details/125781602
如上,官方已有指导,不再赘述。
需要注意,一体化烧写,本人如下,
Ai-WB2-01S 驱动移植
串口配置
这里采用 Ai-WB2-01S 进行串口通信控制,因此使用了开发板的 PB11、PB10 作为 USART2 与之通,PA9、PA10 作为 USART0 进行调试信息打印。具体配置如下。
bsp_usart.h 文件,增加了 USART2
#ifndef _BSP_USART_H
#define _BSP_USART_H
#include "gd32f4xx.h"
#include "systick.h"
#define BSP_USART_TX_RCU RCU_GPIOA // 串口TX的端口时钟
#define BSP_USART_RX_RCU RCU_GPIOA // 串口RX的端口时钟
#define BSP_USART_RCU RCU_USART0 // 串口0的时钟
#define BSP_USART_TX_PORT GPIOA // 串口TX的端口
#define BSP_USART_RX_PORT GPIOA // 串口RX的端口
#define BSP_USART_AF GPIO_AF_7 // 串口0的复用功能
#define BSP_USART_TX_PIN GPIO_PIN_9 // 串口TX的引脚
#define BSP_USART_RX_PIN GPIO_PIN_10 // 串口RX的引脚
#define BSP_USART USART0 // 串口0
#define USART_RECEIVE_LENGTH 256
extern uint8_t g_recv_buff[USART_RECEIVE_LENGTH]; // 接收缓冲区
extern uint8_t g_recv_length; // 接收数据长度
extern uint8_t g_recv_complete_flag; // 接收完成标志位
void usart0_gpio_config(uint32_t band_rate); // 配置串口0
void usart0_send_data(uint8_t ucch); // 发送一个字符
void usart0_send_string(uint8_t *ucstr); // 发送一个字符串
void usart2_gpio_config(uint32_t band_rate); // 配置串口2
void usart2_send_data(uint8_t ucch); // 发送一个字符
void usart2_send_string(uint8_t *ucstr); // 发送一个字符串
#endif /* BSP_USART_H */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
bsp_usart.c 文件,增加 USART2 功能,支持中断接收,这点很重要。
/********************************************************************************
* 文 件 名: bsp_usart.c
* 版 本 号: 初版
* 修改作者: LC
* 修改日期: 2022年04月14日
* 功能介绍:
******************************************************************************
* 注意事项:
*********************************************************************************/
#include "bsp_usart.h"
#include "stdio.h"
uint8_t g_recv_buff[USART_RECEIVE_LENGTH]; // 接收缓冲区
uint8_t g_recv_length = 0; // 接收数据长度
uint8_t g_recv_complete_flag = 0; // 接收数据完成标志位
/************************************************
函数名称 : usart_gpio_config
功 能 : 串口配置GPIO
参 数 : band_rate:波特率
返 回 值 : 无
作 者 : LC
*************************************************/
void usart0_gpio_config(uint32_t band_rate)
{
/* 开启时钟 */
rcu_periph_clock_enable(BSP_USART_TX_RCU); // 开启串口时钟
rcu_periph_clock_enable(BSP_USART_RX_RCU); // 开启端口时钟
rcu_periph_clock_enable(BSP_USART_RCU); // 开启端口时钟
/* 配置GPIO复用功能 */
gpio_af_set(BSP_USART_TX_PORT,BSP_USART_AF,BSP_USART_TX_PIN);
gpio_af_set(BSP_USART_RX_PORT,BSP_USART_AF,BSP_USART_RX_PIN);
/* 配置GPIO的模式 */
/* 配置TX为复用模式 上拉模式 */
gpio_mode_set(BSP_USART_TX_PORT,GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_TX_PIN);
/* 配置RX为复用模式 上拉模式 */
gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_RX_PIN);
/* 配置TX为推挽输出 50MHZ */
gpio_output_options_set(BSP_USART_TX_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,BSP_USART_TX_PIN);
/* 配置RX为推挽输出 50MHZ */
gpio_output_options_set(BSP_USART_RX_PORT,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, BSP_USART_RX_PIN);
/* 配置串口的参数 */
usart_deinit(BSP_USART); // 复位串口
usart_baudrate_set(BSP_USART,band_rate); // 设置波特率
usart_parity_config(BSP_USART,USART_PM_NONE); // 没有校验位
usart_word_length_set(BSP_USART,USART_WL_8BIT); // 8位数据位
usart_stop_bit_set(BSP_USART,USART_STB_1BIT); // 1位停止位
/* 使能串口 */
usart_enable(BSP_USART); // 使能串口
usart_transmit_config(BSP_USART,USART_TRANSMIT_ENABLE); // 使能串口发送
usart_receive_config(BSP_USART,USART_RECEIVE_ENABLE); // 使能串口接收
}
/************************************************
函数名称 : usart_send_data
功 能 : 串口重发送一个字节
参 数 : ucch:要发送的字节
返 回 值 :
作 者 : LC
*************************************************/
void usart0_send_data(uint8_t ucch)
{
usart_data_transmit(BSP_USART,(uint8_t)ucch); // 发送数据
while(RESET == usart_flag_get(BSP_USART,USART_FLAG_TBE)); // 等待发送数据缓冲区标志置位
}
/************************************************
函数名称 : usart_send_String
功 能 : 串口发送字符串
参 数 : ucstr:要发送的字符串
返 回 值 :
作 者 : LC
*************************************************/
void usart0_send_string(uint8_t *ucstr)
{
while(ucstr && *ucstr) // 地址为空或者值为空跳出
{
usart0_send_data(*ucstr++); // 发送单个字符
}
}
//*******************************************************************
//串口2实现开始
//增加串口2配置与驱动
//2023/9/26
/************************************************
函数名称 : usart2_gpio_config
功 能 : 串口配置GPIO
参 数 : band_rate:波特率
返 回 值 : 无
作 者 : kwin
*************************************************/
void usart2_gpio_config(uint32_t band_rate)
{
/* 开启时钟 */
rcu_periph_clock_enable(RCU_USART2); // 开启串口时钟
rcu_periph_clock_enable(RCU_GPIOB); // 开启端口时钟
/* 配置GPIO复用功能 */
gpio_af_set(GPIOB,GPIO_AF_7,GPIO_PIN_11);
gpio_af_set(GPIOB,GPIO_AF_7,GPIO_PIN_10);
/* 配置GPIO的模式 */
/* 配置TX为复用模式 上拉模式 */
gpio_mode_set(GPIOB,GPIO_MODE_AF,GPIO_PUPD_PULLUP,GPIO_PIN_10);
/* 配置RX为复用模式 上拉模式 */
gpio_mode_set(GPIOB, GPIO_MODE_AF,GPIO_PUPD_PULLUP,GPIO_PIN_11);
/* 配置TX为推挽输出 50MHZ */
gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
/* 配置RX为推挽输出 50MHZ */
gpio_output_options_set(GPIOB,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
/* 配置串口的参数 */
usart_deinit(USART2); // 复位串口
usart_baudrate_set(USART2,band_rate); // 设置波特率
usart_parity_config(USART2,USART_PM_NONE); // 没有校验位
usart_word_length_set(USART2,USART_WL_8BIT); // 8位数据位
usart_stop_bit_set(USART2,USART_STB_1BIT); // 1位停止位
/* 使能串口 */
usart_enable(USART2); // 使能串口
usart_transmit_config(USART2,USART_TRANSMIT_ENABLE); // 使能串口发送
usart_receive_config(USART2,USART_RECEIVE_ENABLE); // 使能串口接收
/* 中断配置 */
nvic_irq_enable(USART2_IRQn, 2, 2); // 配置中断优先级
usart_interrupt_enable(USART2,USART_INT_RBNE); // 读数据缓冲区非空中断和溢出错误中断
usart_interrupt_enable(USART2,USART_INT_IDLE); // 空闲检测中断
}
/************************************************
函数名称 : usart2_send_data
功 能 : 串口重发送一个字节
参 数 : ucch:要发送的字节
返 回 值 :
作 者 : kwin
*************************************************/
void usart2_send_data(uint8_t ucch)
{
usart_data_transmit(USART2,(uint8_t)ucch); // 发送数据
while(RESET == usart_flag_get(USART2,USART_FLAG_TBE)); // 等待发送数据缓冲区标志置位
}
/************************************************
函数名称 : usart2_send_String
功 能 : 串口发送字符串
参 数 : ucstr:要发送的字符串
返 回 值 :
作 者 : kwin
*************************************************/
void usart2_send_string(uint8_t *ucstr)
{
while(ucstr && *ucstr) // 地址为空或者值为空跳出
{
usart2_send_data(*ucstr++); // 发送单个字符
}
}
//串口2实现完成
/************************************************
函数名称 : fputc
功 能 : 串口重定向函数
参 数 :
返 回 值 :
作 者 : LC
*************************************************/
int fputc(int ch, FILE *f)
{
usart0_send_data(ch);
// 等待发送数据缓冲区标志置位
return ch;
}
/************************************************
函数名称 : USART2_IRQHandler
功 能 : 串口接收中断服务函数
参 数 : 无
返 回 值 : 无
作 者 : kwin
*************************************************/
void USART2_IRQHandler(void)
{
if(usart_interrupt_flag_get(USART2,USART_INT_FLAG_RBNE) == SET) // 接收缓冲区不为空
{
g_recv_buff[g_recv_length++] = usart_data_receive(USART2); // 把接收到的数据放到缓冲区中
}
if(usart_interrupt_flag_get(USART2,USART_INT_FLAG_IDLE) == SET) // 检测到帧中断
{
usart_data_receive(USART2); // 必须要读,读出来的值不能要
g_recv_buff[g_recv_length] = '\0'; // 数据接收完毕,数组结束标志
g_recv_complete_flag = 1; // 接收完成
}
}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
Ai-WB2-01S 驱动文件
这里主要是对 Ai-WB2-01S 的通信确认,以及信息读取。相应的指 AT 令还有很多,大家在这个基础上可以实现更多的函数功能,在这里简单写几个,抛转引玉。或者大家还有什么需要的功能,可以留言,有时间的时候,我再持续增加与更新。
bsp_Ai_WB2_01S.h
#ifndef _bsp_Ai_WB2_01S_H
#define _bsp_Ai_WB2_01S_H
#include "gd32f4xx.h"
#include "systick.h"
uint8_t IsOK(void);//测试AT指令是否返回OK
uint8_t Set_WIFI(uint8_t *SSID,uint8_t *PWD);//Set_WIFI mode
void Get_Ver(void);//获取模块版本号
void Get_Addr(void);//获取模块MAC地址
void Get_Name(void);//获取模块名称
void Get_Pin(void);//获取模块Pin码
void Init_BLE(void);//
#endif /* _bsp_Ai_WB2_01S_H */2
3
4
5
6
7
8
9
10
11
12
13
14
bsp_Ai_WB2_01S.c 文件
/********************************************************************************
* 文 件 名: bsp_Ai_WB2_01S.c
* 版 本 号: 初版
* 修改作者: kwin
* 修改日期: 2023年049月26日
* 功能介绍:
******************************************************************************
* 注意事项:
*********************************************************************************/
#include "bsp_usart.h"
#include "bsp_Ai_WB2_01S.h"
/************************************************
函数名称 : IsOK
功 能 : 测试AT指令是否返回OK
参 数 :
返 回 值 : 1:OK,0:Fail
作 者 : kwin
*************************************************/
uint8_t IsOK(void)
{
uint8_t i=0;
usart2_send_string("AT\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(5);
i++;
if(i>200) return 0;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
if((g_recv_buff[2]=='O')&&(g_recv_buff[3]=='K'))
return 1;
else
return 0;
}
/************************************************
函数名称 : Get_Ver
功 能 : 获取模块版本号
参 数 :
返 回 值 :
作 者 : kwin
*************************************************/
void Get_Ver(void)
{
uint8_t i=0;
usart2_send_string("AT+GMR\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
}
/************************************************
函数名称 : Set_WIFI
功 能 : 设置WIFI,statiion,并连接
参 数 : <ssid>:连接的AP的SSID(最大长度为32字节)<pwd>:连接的AP的密码(最大长度为32字节)
返 回 值 :
作 者 : kwin
*************************************************/
uint8_t Set_WIFI(uint8_t *SSID,uint8_t *PWD)
{
uint8_t i=0;
usart2_send_string("AT+WMODE=1,1\r\n"); //设置STA模式,保存到FLASH
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return 1;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
i=0;
usart2_send_string("AT+WSDHCP=1\r\n"); //使用DHCP获取IP
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return 1;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
printf("\r\n%s",g_recv_buff);
usart2_send_string("AT+WJAP=");
usart2_send_string(SSID);
usart2_send_string(",");
usart2_send_string(PWD);
usart2_send_string("\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return 1;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
printf("\r\n%s",g_recv_buff);
usart2_send_string("AT+WAUTOCONN=1\r\n");// 上电自动重连Wi-Fi
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return 1;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
return 0;
}
/************************************************
函数名称 : Get_Addr
功 能 : 获取模块蓝牙MAC地址
参 数 :
返 回 值 :
作 者 : kwin
*************************************************/
void Get_Addr(void)
{
uint8_t i=0;
usart2_send_string("AT+BLEMAC\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
}
/************************************************
函数名称 : Get_Name
功 能 : 获取模块蓝牙名称
参 数 :
返 回 值 :
作 者 : kwin
*************************************************/
void Get_Name(void)
{
uint8_t i=0;
usart2_send_string("AT+BLENAME\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
}
/************************************************
函数名称 : Get_Pin
功 能 : 获取模块Pin
参 数 :
返 回 值 :
作 者 : kwin
*************************************************/
void Get_Pin(void)
{
uint8_t i=0;
usart2_send_string("AT+BLEAUTH\r\n");
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("\r\n%s",g_recv_buff);
}
/************************************************
函数名称 : Init_BLE
功 能 : 初始化蓝牙模块
参 数 :
返 回 值 :
作 者 : kwin
*************************************************/
void Init_BLE(void)
{
uint8_t i=0;
usart2_send_string("AT+BLENAME=Kwin_Test\r\n");//设置蓝牙名称,
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
usart2_send_string("AT+BLESERUUID=55535343fe7d4ae58fa99fafd2054321\r\n");//设置蓝牙透传服务 UUID
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
usart2_send_string("AT+BLETXUUID=49535343884143f4a8d4ecbe34728888\r\n");//设置蓝牙透传服务TX特征UUID
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
usart2_send_string("AT+BLERXUUID=495353431e4d4bd9ba6123c647246666\r\n");//设置蓝牙透传服务RX特征UUID
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
i=0;
usart2_send_string("AT+BLEMODE=0\r\n");//设置蓝牙工作模式为从机模式
while(g_recv_complete_flag==0)
{
delay_1ms(1);
i++;
if(i>200) return;
}
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度 i=0;
}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
main 函数实现
在 main 函数中实现验证驱动函数验证,无限循环中实现等待蓝牙连接以及数据收发。通过手机发送蓝牙指令控制 LED2 亮灭。开发板收到手机指令并返回信息给手机,同时向上位机打印提示信息。
| 指令 | LED2 状态 |
|---|---|
| LEDk | 亮 |
| LEDg | 灭 |
大家可以通过此例,实现更多的功能或者任务。
具体代码如下:
/********************************************************************************
* 文 件 名: main.c
* 版 本 号: 初版
* 修改作者: kwin
* 修改日期: 2023年09月26日
* 功能介绍:1-现验证驱动函数验证;
2-无限循环中实现等待蓝牙连接以及数据收发;
3-通过手机发送蓝牙指令控制LED2亮灭;
4-开发板收到手机指令并返回信息给手机;
5-同时向上位机打印提示信息。
******************************************************************************
* 注意事项:
*********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "bsp_led.h"
#include "sys.h"
#include "bsp_usart.h"
#include "bsp_Ai_WB2_01S.h"
/************************************************
函数名称 : main
功 能 : 主函数
参 数 : 无
返 回 值 : 无
作 者 : kwin
*************************************************/
int main(void)
{
uint8_t i=0;
systick_config(); // 滴答定时器初始化
led_gpio_config(); // led初始化
usart0_gpio_config(115200U); // 串口0初始化
usart2_gpio_config(115300U); // 串口2初始化
LED2OFF;
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
printf("AT test begin \r\n");
while(0==IsOK())
{
LED2TOGGLE;//模块不返回OK,则LED2每秒闪一下,并一直等待下去
printf("waiting for Ai_WB2_01s\r\n");
}
Get_Ver();
Init_BLE();
Get_Addr();
Get_Pin();
Get_Name();
while(1) {
delay_1ms(100);
//LED2TOGGLE;
if(g_recv_complete_flag)
{
if(g_recv_length>4)
{
if((g_recv_buff[0]=='L')&&(g_recv_buff[1]=='E')&&(g_recv_buff[2]=='D'))
{
if(g_recv_buff[3]=='k')
{
LED2ON;
printf("\r\nLED2 ON\r\n");
usart2_send_string("LED2 is opened\r\n");
}else if(g_recv_buff[3]=='g')
{
LED2OFF;
printf("\r\nLED2 OFF\r\n");
usart2_send_string("LED2 is closed\r\n");
}
}
}else printf("REC:%s",g_recv_buff);
g_recv_complete_flag = 0; // 等待下次接收
g_recv_length = 0; // 清空长度
}
}
}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
移植验证
验证效果
代码编译并下载到开发板中,可以看到显示与代码实现一致。
源代码打包:
通过网盘分享的文件:立创·梁山派GD32F470ZGT6开发板【模块移植手册代码】
链接: https://pan.baidu.com/s/1pp44yjD1Dhh7U9iZ2a11IA 提取码: LCKF
关于手机端 APP 如下载
请参考 CC2541 BLE蓝牙4.0串口模块 章节