3.15 NF-03 无线 2.4G 通信模块
该模块是由安信可科技设计的 2.4G 无线通信模块。它是一款 5mW 功率的无线收发一体的 2.4G 模块,2.4G 模块是一种用于无线通信的模块,它能够在 2.4GHz 频段进行无线数据传输和接收。该模块通常由无线收发器和相关的控制电路组成,为用户提供方便的无线通信解决方案。
3.15.1 模块来源
采购链接: https://detail.tmall.com/item.htm?abbucket=8&id=617141843154&ns=1&spm=a21n57.1.0.0.ddbb523cVBTQje
资料下载链接: https://docs.ai-thinker.com/2.4g
3.15.2 规格参数
3.15.3 引脚选择
各引脚说明。
| 无线模块 | 立创·梁山派 |
|---|---|
| GND | GND |
| VCC | 3V3 |
| CE | PG9 |
| CSN | PG10 |
| SCK | PG11 |
| MOSI | PG12 |
| MISO | PG13 |
| IRQ | PB7 |
3.15.4 代码移植
参考官方代码案例进行移植:
官方使用的是 51 单片机实现的功能,我们要将其核心部分驱动代码移植到立创·梁山派开发板上。注意,使用该模块发送与接收,必须使用两个模块,一个发送一个接收。通信部分驱动可以使用同一套代码,只是需要将一个模块设置为发送模式,另一个模块设置为接收模式。
引脚初始化
cpp
/** RF24L01硬件接口定义 */
#define RF24L01_CE_GPIO_PORT GPIOG
#define RF24L01_CE_GPIO_RCU RCU_GPIOG
#define RF24L01_CE_GPIO_PIN GPIO_PIN_9
#define RF24L01_IRQ_GPIO_PORT GPIOB
#define RF24L01_IRQ_GPIO_RCU RCU_GPIOB
#define RF24L01_IRQ_GPIO_PIN GPIO_PIN_7
#define RF24L01_CS_GPIO_PORT GPIOG
#define RF24L01_CS_GPIO_RCU RCU_GPIOG
#define RF24L01_CS_GPIO_PIN GPIO_PIN_10
#define SPI_CLK_GPIO_PORT GPIOG
#define SPI_CLK_GPIO_RCU RCU_GPIOG
#define SPI_CLK_GPIO_PIN GPIO_PIN_11
#define SPI_MISO_GPIO_PORT GPIOG
#define SPI_MISO_GPIO_RCU RCU_GPIOG
#define SPI_MISO_GPIO_PIN GPIO_PIN_13
#define SPI_MOSI_GPIO_PORT GPIOG
#define SPI_MOSI_GPIO_RCU RCU_GPIOG
#define SPI_MOSI_GPIO_PIN GPIO_PIN_121
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
本案例只实现软件 SPI,硬件 SPI 大家自行移植。将引脚 IRQ、MISO 配置为输入模式,其余引脚配置为输出模式。
cpp
void si24r1_gpio_init(void)
{
/* 使能CE引脚时钟 */
rcu_periph_clock_enable(RF24L01_CE_GPIO_RCU);
/* 配置CE引脚GPIO的模式 */
gpio_mode_set(RF24L01_CE_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,RF24L01_CE_GPIO_PIN);
/* 配置CE引脚GPIO的输出 */
gpio_output_options_set(RF24L01_CE_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,RF24L01_CE_GPIO_PIN);
/* IRQ */
rcu_periph_clock_enable(RF24L01_IRQ_GPIO_RCU);
gpio_mode_set(RF24L01_IRQ_GPIO_PORT,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,RF24L01_IRQ_GPIO_PIN);
/* CS */
rcu_periph_clock_enable(RF24L01_CS_GPIO_RCU);
gpio_mode_set(RF24L01_CS_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,RF24L01_CS_GPIO_PIN);
gpio_output_options_set(RF24L01_CS_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,RF24L01_CS_GPIO_PIN);
/* CLK */
rcu_periph_clock_enable(SPI_CLK_GPIO_RCU);
gpio_mode_set(SPI_CLK_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,SPI_CLK_GPIO_PIN);
gpio_output_options_set(SPI_CLK_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,SPI_CLK_GPIO_PIN);
/* MOSI */
rcu_periph_clock_enable(SPI_MOSI_GPIO_RCU);
gpio_mode_set(SPI_MOSI_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,SPI_MOSI_GPIO_PIN);
gpio_output_options_set(SPI_MOSI_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,SPI_MOSI_GPIO_PIN);
/* MISO */
rcu_periph_clock_enable(SPI_MISO_GPIO_RCU);
gpio_mode_set(SPI_MISO_GPIO_PORT,GPIO_MODE_INPUT,GPIO_PUPD_NONE,SPI_MISO_GPIO_PIN);
}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
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
时序控制代码
cpp
//SI24R1 PIN DEFINITION
#define MOSI(x) gpio_bit_write(SPI_MOSI_GPIO_PORT, SPI_MOSI_GPIO_PIN, (x)?SET:RESET) // Master Out, Slave In pin (output)
//#define MISO(x) gpio_bit_write(SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PIN, (x)?SET:RESET) // Master In, Slave Out pin (input)
#define SCK(x) gpio_bit_write(SPI_CLK_GPIO_PORT, SPI_CLK_GPIO_PIN, (x)?SET:RESET) // Serial Clock pin, (output)
#define CSN(x) gpio_bit_write(RF24L01_CS_GPIO_PORT, RF24L01_CS_GPIO_PIN, (x)?SET:RESET) // Slave Select pin, (output to CSN)
#define CE(x) gpio_bit_write(RF24L01_CE_GPIO_PORT, RF24L01_CE_GPIO_PIN, (x)?SET:RESET) // Chip Enable pin signal (output)
//#define IRQ(x) gpio_bit_write(RF24L01_IRQ_GPIO_PORT, RF24L01_IRQ_GPIO_PIN, (x)?SET:RESET) // Interrupt signal, from nRF24L01 (input)
#define GET_MISO() gpio_input_bit_get( SPI_MISO_GPIO_PORT,SPI_MISO_GPIO_PIN)
#define GET_IRQ() gpio_input_bit_get( RF24L01_IRQ_GPIO_PORT,RF24L01_IRQ_GPIO_PIN)1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
cpp
static uint8_t SPI_RW(uint8_t byte)
{
uint8_t bit_ctr;
for(bit_ctr=0; bit_ctr<8; bit_ctr++)
{
if(byte & 0x80)
MOSI(1);
else
MOSI(0);
byte = (byte << 1);
SCK(1);
byte |= GET_MISO();
SCK(0);
}
return(byte);
}
/********************************************************
函数功能:SI24R1引脚初始化
入口参数:无
返回 值:无
*********************************************************/
void SI24R1_Init(void)
{
si24r1_gpio_init();
SCK(0); //SPI时钟线拉低
CSN(1);
CE(0);
// IRQ(1);
}
/********************************************************
函数功能:写寄存器的值(单字节)
入口参数:reg:寄存器映射地址(格式:WRITE_REG|reg)
value:寄存器的值
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Write_Reg(uint8_t reg, uint8_t value)
{
uint8_t status;
CSN(0);
status = SPI_RW(reg);
SPI_RW(value);
CSN(1);
return(status);
}
/********************************************************
函数功能:写寄存器的值(多字节)
入口参数:reg:寄存器映射地址(格式:WRITE_REG|reg)
pBuf:写数据首地址
bytes:写数据字节数
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,byte_ctr;
CSN(0);
status = SPI_RW(reg);
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)
SPI_RW(*pBuf++);
CSN(1);
return(status);
}
/********************************************************
函数功能:读取寄存器的值(单字节)
入口参数:reg:寄存器映射地址(格式:READ_REG|reg)
返回 值:寄存器值
*********************************************************/
uint8_t SI24R1_Read_Reg(uint8_t reg)
{
uint8_t value;
CSN(0);
SPI_RW(reg);
value = SPI_RW(0);
CSN(1);
return(value);
}
/********************************************************
函数功能:读取寄存器的值(多字节)
入口参数:reg:寄存器映射地址(READ_REG|reg)
pBuf:接收缓冲区的首地址
bytes:读取字节数
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,byte_ctr;
CSN(0);
status = SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); //读取数据,低字节在前
CSN(1);
return(status);
}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
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
剩余代码的修改,其看以下完整代码:
bsp_si24r1.c
cpp
#include "bsp_si24r1.h"
uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x0A,0x01,0x07,0x0E,0x01}; // 定义一个静态发送地址
/**********************************************************
* 函 数 名 称:si24r1_gpio_init
* 函 数 功 能:si24r1引脚初始化
* 传 入 参 数:无
* 函 数 返 回:无
* 作 者:LCKFB
* 备 注:无
**********************************************************/
void si24r1_gpio_init(void)
{
/* 使能CE引脚时钟 */
rcu_periph_clock_enable(RF24L01_CE_GPIO_RCU);
/* 配置CE引脚GPIO的模式 */
gpio_mode_set(RF24L01_CE_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,RF24L01_CE_GPIO_PIN);
/* 配置CE引脚GPIO的输出 */
gpio_output_options_set(RF24L01_CE_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,RF24L01_CE_GPIO_PIN);
/* IRQ */
rcu_periph_clock_enable(RF24L01_IRQ_GPIO_RCU);
gpio_mode_set(RF24L01_IRQ_GPIO_PORT,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,RF24L01_IRQ_GPIO_PIN);
/* CS */
rcu_periph_clock_enable(RF24L01_CS_GPIO_RCU);
gpio_mode_set(RF24L01_CS_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,RF24L01_CS_GPIO_PIN);
gpio_output_options_set(RF24L01_CS_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,RF24L01_CS_GPIO_PIN);
/* CLK */
rcu_periph_clock_enable(SPI_CLK_GPIO_RCU);
gpio_mode_set(SPI_CLK_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,SPI_CLK_GPIO_PIN);
gpio_output_options_set(SPI_CLK_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,SPI_CLK_GPIO_PIN);
/* MOSI */
rcu_periph_clock_enable(SPI_MOSI_GPIO_RCU);
gpio_mode_set(SPI_MOSI_GPIO_PORT,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,SPI_MOSI_GPIO_PIN);
gpio_output_options_set(SPI_MOSI_GPIO_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,SPI_MOSI_GPIO_PIN);
/* MISO */
rcu_periph_clock_enable(SPI_MISO_GPIO_RCU);
gpio_mode_set(SPI_MISO_GPIO_PORT,GPIO_MODE_INPUT,GPIO_PUPD_NONE,SPI_MISO_GPIO_PIN);
}
/**********************************************************
* 函 数 名 称:SPI_RW
* 函 数 功 能:SPI读写
* 传 入 参 数:byte:要通过SPI发送的数据
* 函 数 返 回:通过SPI接收到的数据
* 作 者:LCKFB
* 备 注:无
**********************************************************/
static uint8_t SPI_RW(uint8_t byte)
{
uint8_t bit_ctr;
for(bit_ctr=0; bit_ctr<8; bit_ctr++)
{
if(byte & 0x80)
MOSI(1);
else
MOSI(0);
byte = (byte << 1);
SCK(1);
byte |= GET_MISO();
SCK(0);
}
return(byte);
}
/********************************************************
函数功能:SI24R1模块初始化
入口参数:无
返回 值:无
*********************************************************/
void SI24R1_Init(void)
{
si24r1_gpio_init();
SCK(0); //SPI时钟线拉低
CSN(1);
CE(0);
// IRQ(1);
}
/********************************************************
函数功能:写寄存器的值(单字节)
入口参数:reg:寄存器映射地址(格式:WRITE_REG|reg)
value:寄存器的值
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Write_Reg(uint8_t reg, uint8_t value)
{
uint8_t status;
CSN(0);
status = SPI_RW(reg);
SPI_RW(value);
CSN(1);
return(status);
}
/********************************************************
函数功能:写寄存器的值(多字节)
入口参数:reg:寄存器映射地址(格式:WRITE_REG|reg)
pBuf:写数据首地址
bytes:写数据字节数
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,byte_ctr;
CSN(0);
status = SPI_RW(reg);
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)
SPI_RW(*pBuf++);
CSN(1);
return(status);
}
/********************************************************
函数功能:读取寄存器的值(单字节)
入口参数:reg:寄存器映射地址(格式:READ_REG|reg)
返回 值:寄存器值
*********************************************************/
uint8_t SI24R1_Read_Reg(uint8_t reg)
{
uint8_t value;
CSN(0);
SPI_RW(reg);
value = SPI_RW(0);
CSN(1);
return(value);
}
/********************************************************
函数功能:读取寄存器的值(多字节)
入口参数:reg:寄存器映射地址(READ_REG|reg)
pBuf:接收缓冲区的首地址
bytes:读取字节数
返回 值:状态寄存器的值
*********************************************************/
uint8_t SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,byte_ctr;
CSN(0);
status = SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); //读取数据,低字节在前
CSN(1);
return(status);
}
/********************************************************
函数功能:SI24R1接收模式初始化
入口参数:无
返回 值:无
*********************************************************/
void SI24R1_RX_Mode(void)
{
CE(0);
SI24R1_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 接收设备接收通道0使用和发送设备相同的发送地址
SI24R1_Write_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SI24R1_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SI24R1_Write_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40
SI24R1_Write_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度
SI24R1_Write_Reg(WRITE_REG + RF_SETUP, 0x0f); // 数据传输率2Mbps,发射功率7dBm
SI24R1_Write_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式
SI24R1_Write_Reg(WRITE_REG + STATUS, 0xff); //清除所有的中断标志位
CE(1); // 拉高CE启动接收设备
}
/********************************************************
函数功能:SI24R1发送模式初始化
入口参数:无
返回 值:无
*********************************************************/
void SI24R1_TX_Mode(void)
{
CE(0);
SI24R1_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写入发送地址
SI24R1_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 为了应答接收设备,接收通道0地址和发送地址相同
SI24R1_Write_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SI24R1_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SI24R1_Write_Reg(WRITE_REG + SETUP_RETR, 0x0a); // 自动重发延时等待250us+86us,自动重发10次
SI24R1_Write_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40
SI24R1_Write_Reg(WRITE_REG + RF_SETUP, 0x0f); // 数据传输率2Mbps,发射功率7dBm
SI24R1_Write_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电
//CE = 1;
}
/********************************************************
函数功能:读取接收数据
入口参数:rxbuf:接收数据存放首地址
返回 值:0:接收到数据
1:没有接收到数据
*********************************************************/
uint8_t SI24R1_RxPacket(uint8_t *rxbuf)
{
uint8_t state;
state = SI24R1_Read_Reg(STATUS); //读取状态寄存器的值
SI24R1_Write_Reg(WRITE_REG+STATUS,state); //清除RX_DS中断标志
if(state & RX_DR) //接收到数据
{
SI24R1_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH); //读取数据
SI24R1_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
return 0;
}
return 1; //没收到任何数据
}
/********************************************************
函数功能:发送一个数据包
入口参数:txbuf:要发送的数据
返回 值:0x10:达到最大重发次数,发送失败
0x20:发送成功
0xff:发送失败
*********************************************************/
uint8_t SI24R1_TxPacket(uint8_t *txbuf)
{
uint8_t state;
CE(0); //CE拉低,使能SI24R1配置
SI24R1_Write_Buf(WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH); //写数据到TX FIFO,32个字节
CE(1); //CE置高,使能发送
while(GET_IRQ() == 1); //等待发送完成
state = SI24R1_Read_Reg(STATUS); //读取状态寄存器的值
SI24R1_Write_Reg(WRITE_REG+STATUS, state); //清除TX_DS或MAX_RT中断标志
if(state&MAX_RT) //达到最大重发次数
{
SI24R1_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器
return MAX_RT;
}
if(state&TX_DS) //发送完成
{
return TX_DS;
}
return 0XFF; //发送失败
}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
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
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
bsp_si24r1.h
cpp
#ifndef _BSP_SI24R1_H_
#define _BSP_SI24R1_H_
#include "gd32f4xx.h"
/** RF24L01硬件接口定义 */
#define RF24L01_CE_GPIO_PORT GPIOG
#define RF24L01_CE_GPIO_RCU RCU_GPIOG
#define RF24L01_CE_GPIO_PIN GPIO_PIN_9
#define RF24L01_IRQ_GPIO_PORT GPIOB
#define RF24L01_IRQ_GPIO_RCU RCU_GPIOB
#define RF24L01_IRQ_GPIO_PIN GPIO_PIN_7
#define RF24L01_CS_GPIO_PORT GPIOG
#define RF24L01_CS_GPIO_RCU RCU_GPIOG
#define RF24L01_CS_GPIO_PIN GPIO_PIN_10
#define SPI_CLK_GPIO_PORT GPIOG
#define SPI_CLK_GPIO_RCU RCU_GPIOG
#define SPI_CLK_GPIO_PIN GPIO_PIN_11
#define SPI_MISO_GPIO_PORT GPIOG
#define SPI_MISO_GPIO_RCU RCU_GPIOG
#define SPI_MISO_GPIO_PIN GPIO_PIN_13
#define SPI_MOSI_GPIO_PORT GPIOG
#define SPI_MOSI_GPIO_RCU RCU_GPIOG
#define SPI_MOSI_GPIO_PIN GPIO_PIN_12
//SI24R1 PIN DEFINITION
#define MOSI(x) gpio_bit_write(SPI_MOSI_GPIO_PORT, SPI_MOSI_GPIO_PIN, (x)?SET:RESET) // Master Out, Slave In pin (output)
//#define MISO(x) gpio_bit_write(SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PIN, (x)?SET:RESET) // Master In, Slave Out pin (input)
#define SCK(x) gpio_bit_write(SPI_CLK_GPIO_PORT, SPI_CLK_GPIO_PIN, (x)?SET:RESET) // Serial Clock pin, (output)
#define CSN(x) gpio_bit_write(RF24L01_CS_GPIO_PORT, RF24L01_CS_GPIO_PIN, (x)?SET:RESET) // Slave Select pin, (output to CSN)
#define CE(x) gpio_bit_write(RF24L01_CE_GPIO_PORT, RF24L01_CE_GPIO_PIN, (x)?SET:RESET) // Chip Enable pin signal (output)
//#define IRQ(x) gpio_bit_write(RF24L01_IRQ_GPIO_PORT, RF24L01_IRQ_GPIO_PIN, (x)?SET:RESET) // Interrupt signal, from nRF24L01 (input)
#define GET_MISO() gpio_input_bit_get( SPI_MISO_GPIO_PORT,SPI_MISO_GPIO_PIN)
#define GET_IRQ() gpio_input_bit_get( RF24L01_IRQ_GPIO_PORT,RF24L01_IRQ_GPIO_PIN)
#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 32 // 数据通道有效数据宽度
//********************************************************************************************************************//
// SPI(SI24R1) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
//********************************************************************************************************************//
// SPI(SI24R1) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define RSSI 0x09 // 'Received Signal Strength Indecator' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
//********************************************************************************************************************//
// STATUS Register
#define RX_DR 0x40 /**/
#define TX_DS 0x20
#define MAX_RT 0x10
//********************************************************************************************************************//
// FUNCTION's PROTOTYPES //
//********************************************************************************************************************//
//SI24R1 API Functions
void SI24R1_Init(void); //SI24R1 Pin Init
uint8_t SI24R1_Write_Reg(uint8_t reg, uint8_t value);
uint8_t SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes);
uint8_t SI24R1_Read_Reg(uint8_t reg);
uint8_t SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes);
void SI24R1_RX_Mode(void);
void SI24R1_TX_Mode(void);
uint8_t SI24R1_RxPacket(uint8_t *rxbuf);
uint8_t SI24R1_TxPacket(uint8_t *txbuf);
//********************************************************************************************************************//
#endif1
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
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
3.15.5 移植验证
需要准备两个模块,一个负责接收(从机),一个负责发送(主机)。主从机的接线都是一样的。
在负责发送部分(主机)中的 main.c 编写代码如下:
cpp
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·梁山派开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "string.h"
#include "bsp_si24r1.h"
/******************************************************************
两个模式只能开启一个
******************************************************************/
//是否开启发送模式 1=开启 0=关闭
#define SENDING_MODE 1
//是否开启接收模式 1=开启 0=关闭
#define RECEIVING_MODE 0
/******************************************************************
* 函 数 名 称:main
* 函 数 说 明:主函数
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者: LC
* 备 注:无
******************************************************************/
int main(void)
{
uint8_t buf[32] = {"abcdefg"};
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组
//滴答定时器初始化 1us
systick_config();
//串口0初始化(调试)
usart_gpio_config( 9600U );
printf("start\r\n");
//如果是发送模式
#if SENDING_MODE
printf("TX_Mode\r\n");
SI24R1_Init();
//设置为发送模式
SI24R1_TX_Mode();
while(1)
{
//每隔一秒发送 abcdefg
printf("send: %s\r\n",buf);
SI24R1_TxPacket(buf);
delay_1ms(1000);
}
#endif
//如果是接收模式
#if RECEIVING_MODE
printf("RX_Mode\r\n");
SI24R1_Init();
//设置为接收模式
SI24R1_RX_Mode();
while(1)
{
//如果接收到数据
if(!SI24R1_RxPacket(buf))
{
//将接收到的数据通过串口显示出来
printf("%s\r\n",buf);
}
}
#endif
}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
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
在负责接收部分(从机)中的 main.c 编写代码如下:
cpp
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·梁山派开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "string.h"
#include "bsp_si24r1.h"
/******************************************************************
两个模式只能开启一个
******************************************************************/
//是否开启发送模式 1=开启 0=关闭
#define SENDING_MODE 0
//是否开启接收模式 1=开启 0=关闭
#define RECEIVING_MODE 1
/******************************************************************
* 函 数 名 称:main
* 函 数 说 明:主函数
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者: LC
* 备 注:无
******************************************************************/
int main(void)
{
uint8_t buf[32] = {"abcdefg"};
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组
//滴答定时器初始化 1us
systick_config();
//串口0初始化(调试)
usart_gpio_config( 9600U );
printf("start\r\n");
//如果是发送模式
#if SENDING_MODE
printf("TX_Mode\r\n");
SI24R1_Init();
SI24R1_TX_Mode();
while(1)
{
//每隔一秒发送 abcdefg
printf("send: %s\r\n",buf);
SI24R1_TxPacket(buf);
delay_1ms(1000);
}
#endif
//如果是接收模式
#if RECEIVING_MODE
printf("RX_Mode\r\n");
SI24R1_Init();
SI24R1_RX_Mode();
while(1)
{
//如果接收到数据
if(!SI24R1_RxPacket(buf))
{
//将接收到的数据通过串口显示出来
printf("%s\r\n",buf);
}
}
#endif
}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
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
实物验证:
代码工程文件
通过网盘分享的文件:立创·梁山派GD32F470ZGT6开发板【模块移植手册代码】
链接: https://pan.baidu.com/s/1pp44yjD1Dhh7U9iZ2a11IA 提取码: LCKF