2.48 攀藤 PMS7003 颗粒物传感器(来自#ifndef 的贡献)
2.48.1 模块来源
采购链接: https://item.taobao.com/item.htm?spm=a1z09.2.0.0.2d2f2e8dp8UjTu&id=528523423466&_u=dp4d6abef65
资料下载:
**实物展示图**2.48.2 规格参数
工作电压:4.5~5.5V工作电流:<100mA待机电流: <200uA通信方式:串口(3.3V)颗粒物测量范围:0.3~1.0;1.0~2.5;2.5~10um分辨率: 1ug/m3响应时间: <10Sec
说明书
2.48.3 模块原理
激光照射腔室,腔室内被测气体中颗粒物将导致散射,测量散射范围可得出颗粒物浓度值.
2.48.4 移植工程
模块使用串口进行通信,通信速率 9600(8N1).模块使用 5V 供电,但通信信号电平为 3.3V,因此无需电平转换可同梁山派引脚直接连接.其中 Reset 和 Set 均内置上拉,无需连接.
2.48.4-2 移植步骤
创建 bsp_pms7003.c
文档内容如下:
cpp
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "bsp_pms7003.h"
#include "systick.h" // Qa mode timeout
#include "bsp_usart.h" // communication interface & log
/* Private macros ------------------------------------------------------------*/
/* User porting interfaces */
#define PMS7003_API_INIT(n) bsp_uart_user_init((n))
#define PMS7003_API_SEND(dat,len) bsp_uart_user_send((dat),(len))
#define PMS7003_API_RECV(dat,len) bsp_uart_user_recv((dat),(len))
/* Commands */
#define PMS7003_CMD_READ 0xE2 // Read data(passive mode)
#define PMS7003_CMD_MODE 0xE1 // Change sensor transmisson mode(00: Qa,01: Au)
#define PMS7003_CMD_WORK 0xE4 // Change sensor work mode(00: work 01: sleep)
#define PMS7003_CMD_MODE_QA 0x00 // Command option with PMS7003_CMD_MODE
#define PMS7003_CMD_MODE_AU 0x01
#define PMS7003_CMD_WORK_WK 0x00 // Command option with PMS7003_CMD_WORK
#define PMS7003_CMD_WORK_SP 0x01
#define PMS7003_BUFFER_SIZE 32u
/* Private types -------------------------------------------------------------*/
/* Data struct */
typedef struct
{
uint16_t pm1_0_cf; ///< PM1.0 CF=1. unit: ug/m3
uint16_t pm2_5_cf; ///< PM2.5
uint16_t pm10_cf; ///< PM10
uint16_t pm1_0_atm; ///< PM1.0 Atmosphere. unit: ug/m3
uint16_t pm2_5_atm; ///< PM2.5
uint16_t pm10_atm; ///< PM10
uint16_t cnt0_3; ///< Count of >0.3um particles in 0.1L of air
uint16_t cnt0_5; ///< 0.5um
uint16_t cnt1_0; ///< 1.0um
uint16_t cnt2_5; ///< 2.5um
uint16_t cnt5_0; ///< 5.0um
uint16_t cnt10; ///< 10um
uint8_t version; ///< Version number
uint8_t errcode; ///< Error code
} Pms7003Data_t;
/* Private variables ---------------------------------------------------------*/
struct
{
bool initialize;
uint8_t mode; //Default mode is actively upload
} Pms7003Info;
/* Private functions ---------------------------------------------------------*/
static int pms7003_request( void );
static int pms7003_control( uint8_t _Command, uint16_t _Option );
static int packet_format_check( const uint8_t* _Data, uint8_t _Length );
static uint16_t checksumGet( const uint8_t* _Data, uint8_t _Length );
/* External variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/// @brief Initialize Pms7003 device
/// @return @see bsp_uart_user_init
__API__ int bsp_pms7003_init( void )
{
if( Pms7003Info.initialize != false )
{
return 0;
}
/* Initialize uart port */
if( PMS7003_API_INIT( 9600 ) != 0 )
{
return -1;
}
Pms7003Info.initialize = true;
return 0;
}
/// @brief Control Pms7003 mode
/// @param _Option @see Pms7003Ctl_t
/// @retval -1: control fail
/// @retval 0: success
__API__ int bsp_pms7003_control( Pms7003Ctl_t _Option )
{
int _res = -1;
if( _Option == PMS7003_CTL_QA )
{
_res = pms7003_control( PMS7003_CMD_MODE, PMS7003_CMD_MODE_QA );
if( _res == 0 )
{
Pms7003Info.mode = true;
}
}
else if( _Option == PMS7003_CTL_AU )
{
_res = pms7003_control( PMS7003_CMD_MODE, PMS7003_CMD_MODE_AU );
if( _res == 0 )
{
Pms7003Info.mode = false;
}
}
else if( _Option == PMS7003_CTL_WK )
{
_res = pms7003_control( PMS7003_CMD_WORK, PMS7003_CMD_WORK_WK );
}
else if( _Option == PMS7003_CTL_SP )
{
_res = pms7003_control( PMS7003_CMD_WORK, PMS7003_CMD_WORK_SP );
}
return _res;
}
/// @brief Message data parser manager
/// @param _Data input data
/// @param _Length length of data
/// @retval 0 success
/// @retval @see packet_format_check
static int data_manage( const uint8_t* _Data, uint8_t _Length )
{
assert( _Data );
/* Check data packet length */
if( _Length < 32 )
{
return 0;
}
/* parser data */
LOG_HEX( "DataIn", 16, ( uint8_t* )_Data, _Length );
int _res = packet_format_check( _Data, 32 );
if( _res < 0 )
{
return _res;
}
/* Calculation data */
Pms7003Data_t* _data;
uint8_t _len = 4; //Skip head(2)+Length(2)
_data = ( Pms7003Data_t* )_Data;
LOG_RAW( "PMS-CF PM1.0[%6u] PM2.5[%6u] PM10[%6u]\r\n", _data->pm1_0_cf,
_data->pm2_5_cf, _data->pm10_cf );
LOG_RAW( "PMS-ATM PM1.0[%6u] PM2.5[%6u] PM10[%6u]\r\n", _data->pm1_0_atm,
_data->pm2_5_atm, _data->pm10_atm );
LOG_RAW( "PMS-CNT NM0.3[%6u] 0.5[%u] 1.0[%6u] 2.5[%6u] 5.0[%6u] 10[%u]\r\n",
_data->cnt0_3, _data->cnt0_5, _data->cnt1_0, _data->cnt2_5,
_data->cnt5_0, _data->cnt10 );
LOG_RAW( "PMS-VER:%02X ErrCode:%02X\r\n", _data->version, _data->errcode );
return 0;
}
/// @brief Test fucntion
/// @param _Timeout Waiting for module return timeout
/// @return 0 Success <0 Failed
__API__ int bsp_pms7003_coroutine( uint32_t _Timeout )
{
uint8_t _buffer[PMS7003_BUFFER_SIZE];
uint32_t _length;
int _res;
/* Data processing after initialization */
if( Pms7003Info.initialize != true )
{
return 0;
}
/* QA mode */
if( Pms7003Info.mode )
{
pms7003_request();
}
/* Waitting data */
do
{
_length = PMS7003_API_RECV( _buffer, PMS7003_BUFFER_SIZE );
if( _length != PMS7003_BUFFER_SIZE )
{
delay_1ms( 1 );
_Timeout--;
if( _Timeout == 0 )
{
LOG_RAW( "PMS-timeout\r\n" );
return -1; // timeout
}
}
}
while( _length != PMS7003_BUFFER_SIZE );
_res = data_manage( ( const uint8_t* )_buffer, _length );
if( _res < 0 )
{
LOG_RAW( "PMS-Error %d\r\n", _res );
}
/* QA mode */
if( Pms7003Info.mode )
{
delay_1ms( 1000 ); //Reduce QA rate
}
return _res;
}
/// @brief Control sensor mode
/// @param _Command comand types
/// @arg PMS7003_CMD_MODE: Chnage QAmode or AUmode
/// @arg PMS7003_CMD_WORK: Change workmode or sleep
/// @param _Option Comand param
/// @arg PMS7003_CMD_MODE: support PMS7003_CMD_MODE_QA or PMS7003_CMD_MODE_AU
/// @arg PMS7003_CMD_WORK: support PMS7003_CMD_WORK_WK or PMS7003_CMD_WORK_SP
/// @return 0 success, -1 fail
static int pms7003_control( uint8_t _Command, uint16_t _Option )
{
uint16_t _checksum;
uint8_t _data[7];
uint8_t _len = 0;
/* Head */
_data[_len++] = 0x42;
_data[_len++] = 0x4D;
/* Command */
_data[_len++] = _Command;
/* Data */
_data[_len++] = ( uint8_t )( ( _Option >> 8 ) & 0xFF );
_data[_len++] = ( uint8_t )( _Option & 0xFF );
/* Checksum */
_checksum = checksumGet( ( const uint8_t* )_data, 0x05 );
_data[_len++] = ( uint8_t )( ( _checksum >> 8 ) & 0xFF );
_data[_len++] = ( uint8_t )( _checksum & 0xFF );
if( PMS7003_API_SEND( _data, _len ) != _len )
{
return -1;
}
return 0;
}
/// @brief Request data in QA mode
/// @return 0 success, -1 fail
static int pms7003_request( void )
{
uint16_t _checksum;
uint8_t _data[7];
uint8_t _len = 0;
/* Head */
_data[_len++] = 0x42;
_data[_len++] = 0x4D;
/* Command */
_data[_len++] = PMS7003_CMD_READ;
/* Data */
_data[_len++] = 0x00;
_data[_len++] = 0x00;
/* Checksum */
_checksum = checksumGet( ( const uint8_t* )_data, 0x05 );
_data[_len++] = ( uint8_t )( ( _checksum >> 8 ) & 0xFF );
_data[_len++] = ( uint8_t )( _checksum & 0xFF );
if( PMS7003_API_SEND( _data, _len ) != _len )
{
return -1;
}
return 0;
}
/// @brief Check message packet format(Head&Checksum)
/// @param _Data input data
/// @param _Length length of data
/// @retval -101 too short
/// @retval -102 head not match
/// @retval -103 checksum fail
/// @retval 0 success
static int packet_format_check( const uint8_t* _Data, uint8_t _Length )
{
assert( _Data );
if( _Length < 7 )
{
return -101; //data too short
}
/* Check data head */
if( _Data[0] != 0x42 || _Data[1] != 0x4D )
{
return -102; // head not match
}
/* Check checksum */
uint16_t _checksum = checksumGet( _Data, _Length - 2 );
uint16_t _checksum_in = ( _Data[_Length - 2] << 8 | _Data[_Length - 1] );
if( _checksum != _checksum_in )
{
LOG_RAW( "Dart-Checksum fail %04X-%04X\r\n", _checksum_in, _checksum );
return -103; // Checksum check fail
}
return 0;
}
/// @brief Get checksum
/// @param _Data input data
/// @param _Length length of data
/// @return checksum
static uint16_t checksumGet( const uint8_t* _Data, uint8_t _Length )
{
assert( _Data );
uint16_t _checksum = 0x00;
while( _Length-- )
{
_checksum += *_Data;
_Data++;
}
return ( _checksum );
}
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
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
301
302
303
304
305
306
307
308
309
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
301
302
303
304
305
306
307
308
309
创建 bsp_pms7003.h
文档内容如下:
cpp
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_PMS7003_H__
#define __BSP_PMS7003_H__
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Exported constants --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum Pms7003Ctl
{
PMS7003_CTL_QA = 0x00, ///< Set questions and answer mode
PMS7003_CTL_AU, ///< Set actively upload mode
PMS7003_CTL_WK, ///< Set normal work mode
PMS7003_CTL_SP ///< Set sleep mode(low power)
} Pms7003Ctl_t;
/* Exported functions --------------------------------------------------------*/
/// @brief Initialize Pms7003 device
/// @return @see bsp_uart_user_init
__API__ int bsp_pms7003_init( void );
/// @brief Control Pms7003 mode
/// @param _Option @see Pms7003Ctl_t
/// @retval -1: control fail
/// @retval 0: success
__API__ int bsp_pms7003_control( Pms7003Ctl_t _Option );
/// @brief Test fucntion
/// @param _Timeout Waiting for module return timeout
/// @return 0 Success <0 Failed
__API__ int bsp_pms7003_coroutine( uint32_t _Timeout );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BSP_PMS7003_H__ */
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
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
相关串口驱动等底层驱动部分参见 bsp_usart.c
文档内容:
c
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "bsp_usart.h"
#include <string.h> //memcpy
/* Porting config */
// #define UARTx_BOUND 9600
#define UARTx_NAME USART1
#define UARTx_RCC RCU_USART1
#define UARTx_GPIO_RCC (RCU_GPIOA)
#define UARTx_PIN_TX GPIO_PIN_2
#define UARTx_PORT_TX GPIOA
#define UARTx_AF_TX GPIO_AF_7
#define UARTx_PIN_RX GPIO_PIN_3
#define UARTx_PORT_RX GPIOA
#define UARTx_AF_RX GPIO_AF_7
/* interrupt */
#define UARTx_IRQ_CHANNEL USART1_IRQn
#define UARTx_IRQ_HANDLER USART1_IRQHandler
#define UARTx_IRQ_PRIORITY 5
/* Revice data buffer size */
#define UARTx_RX_BUFFER_SIZE 64 // at least 9Bytes
#define MIN(n,m) (((n) < (m)) ? (n) : (m))
struct
{
bool initialize;
bool rx_flag;
uint8_t length;
uint8_t buffer[UARTx_RX_BUFFER_SIZE];
} bsp_uart_user;
__API__ int bsp_uart_user_init( uint32_t _BandRate )
{
if( bsp_uart_user.initialize != false )
{
return 0;
}
/* Enable the UART Clock */
rcu_periph_clock_enable( UARTx_GPIO_RCC );
rcu_periph_clock_enable( UARTx_RCC );
/* Configure the UART TX pin */
gpio_af_set( UARTx_PORT_TX, UARTx_AF_TX, UARTx_PIN_TX );
gpio_mode_set( UARTx_PORT_TX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UARTx_PIN_TX );
gpio_output_options_set( UARTx_PORT_TX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UARTx_PIN_TX );
/* Configure the UART RX pin */
gpio_af_set( UARTx_PORT_RX, UARTx_AF_RX, UARTx_PIN_RX );
gpio_mode_set( UARTx_PORT_RX, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UARTx_PIN_RX );
gpio_output_options_set( UARTx_PORT_RX, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UARTx_PIN_RX );
/* Configure UART param: 8N1 */
usart_deinit( UARTx_NAME );
usart_baudrate_set( UARTx_NAME, _BandRate );
usart_parity_config( UARTx_NAME, USART_PM_NONE );
usart_word_length_set( UARTx_NAME, USART_WL_8BIT );
usart_stop_bit_set( UARTx_NAME, USART_STB_1BIT );
/* Enabel transmit mode */
usart_transmit_config( UARTx_NAME, USART_TRANSMIT_ENABLE );
usart_receive_config( UARTx_NAME, USART_RECEIVE_ENABLE );
/* Configure interrupt */
nvic_irq_enable( UARTx_IRQ_CHANNEL, UARTx_IRQ_PRIORITY, 0 );
/* Interrupt mode */
/* receive data not empty interrupt */
usart_interrupt_enable( UARTx_NAME, USART_INT_RBNE );
usart_interrupt_enable( UARTx_NAME, USART_INT_IDLE );
usart_flag_clear( UARTx_NAME, USART_FLAG_TC );
/* Enable periph */
usart_enable( UARTx_NAME );
bsp_uart_user.initialize = true;
return 0;
}
__API__ uint32_t bsp_uart_user_send( uint8_t* _Data, uint32_t _Length )
{
#if 0
if( USART_CTL0( UARTx_NAME ) & ( USART_CTL0_UEN ) != ( USART_CTL0_UEN ) )
{
return 0; // Device is disable
}
#else
if( bsp_uart_user.initialize == false )
{
return 0;
}
#endif
for( uint32_t i = 0; i < _Length; i++ )
{
usart_data_transmit( UARTx_NAME, *( ( char* )_Data + i ) );
while( usart_flag_get( UARTx_NAME, USART_FLAG_TC ) == RESET );
}
return _Length;
}
__API__ uint32_t bsp_uart_user_recv( uint8_t* _Data, uint32_t _Length )
{
assert( _Data );
uint32_t _len = 0;
if( bsp_uart_user.initialize == false )
{
return 0;
}
_len = MIN( _Length, bsp_uart_user.length );
if( ( bsp_uart_user.rx_flag != false ) && ( _len > 0 ) )
{
memcpy( _Data, bsp_uart_user.buffer, _len );
/* Clear receive status */
bsp_uart_user.length = 0x00;
bsp_uart_user.rx_flag = false;
}
return _len;
}
__IRQ__ void UARTx_IRQ_HANDLER( void )
{
/* Data processing after initialization */
if( bsp_uart_user.initialize != true )
{
return;
}
/* Receive Data not empty */
if( usart_interrupt_flag_get( UARTx_NAME, USART_INT_FLAG_RBNE ) != RESET )
{
/* Read one byte from the receive data register */
uint8_t _recv = ( usart_data_receive( UARTx_NAME ) & 0xFF );
/* Push one byte to receive fifo */
if( bsp_uart_user.rx_flag != false )
{
return; //Buffer data not processed, skipping reception
}
if( bsp_uart_user.length < UARTx_RX_BUFFER_SIZE )
{
// Prevent overflow
bsp_uart_user.buffer[bsp_uart_user.length++] = _recv;
}
}
/* Bus idle */
else if( usart_interrupt_flag_get( UARTx_NAME, USART_INT_FLAG_IDLE ) != RESET )
{
/* Clear IDLE */
( void )USART_STAT0( UARTx_NAME );
( void )USART_DATA( UARTx_NAME );
if( bsp_uart_user.length )
{
bsp_uart_user.rx_flag = true;
}
}
/* Overrun error : skip */
}
/*---- Log output simple apis ----------------------------------------------- */
__API__ void _LOG_HEX( char* _Name, uint8_t _Width, uint8_t* _Data, uint8_t _Length )
{
size_t _len;
for( size_t i = 0; i < _Length; i += _Width )
{
/* Name */
printf( "%-*.*s ", 16, 16, _Name );
/* Timestamp */
/* Fill data */
_len = 0x00;
for( size_t j = 0; j < _Width; j++ )
{
if( ( i + j ) < _Length )
{
printf( "%02X", _Data[i + j] );
}
if( ( j + 1 ) % 4 == 0 )
{
printf( " " );
}
}
printf( "\r\n" );
}
}
/*---- Official printf interface(KeilMDK microLib) -------------------------- */
/************************************************
函数名称 : usart_gpio_config
功 能 : 串口配置GPIO
参 数 : band_rate:波特率
返 回 值 : 无
作 者 : LC
*************************************************/
void usart_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_send_data
功 能 : 串口重发送一个字节
参 数 : ucch:要发送的字节
返 回 值 :
作 者 : LC
*************************************************/
void usart_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 usart_send_string( uint8_t* ucstr )
{
while( ucstr && *ucstr ) // 地址为空或者值为空跳出
{
usart_send_data( *ucstr++ ); // 发送单个字符
}
}
/************************************************
函数名称 : fputc
功 能 : 串口重定向函数
参 数 :
返 回 值 :
作 者 : LC
*************************************************/
int fputc( int ch, FILE* f )
{
usart_send_data( ch );
// 等待发送数据缓冲区标志置位
return ch;
}
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
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
2.48.5 移植验证
工程主函数内修改如下:
c
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
/* Porting files */
#include "pms7003/bsp_pms7003.h"
int main( void )
{
/* Bsp configuration */
nvic_priority_group_set( NVIC_PRIGROUP_PRE2_SUB2 );
systick_config();
usart_gpio_config( 115200U );
/* User configuration */
uint8_t count = 0;
if( bsp_pms7003_init() != 0 )
{
LOG_RAW( "Error component initialization failed\r\n" );
delay_1ms( 5000 );
NVIC_SystemReset(); //Call software reset system
}
LOG_RAW( "Component demo start\r\n" );
while( 1 )
{
{
/* Auto change sensor mode */
count++;
if( count == 100 )
{
bsp_pms7003_control( PMS7003_CTL_QA );
}
else if( count == 200 )
{
bsp_pms7003_control( PMS7003_CTL_AU );
count = 0x00;
}
}
LOG_RAW( "Test count %d %s\r\n", count, ( count >= 100 ) ? "Qa" : "Au" );
bsp_pms7003_coroutine( 1000 ); // test fucntions
// delay_1ms( 1000 );
}
}
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
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
案例现象:
上电后,每 100 计数值切换一次模式,默认处于主动推送模式(200~800ms).
- 推送模式: 梁山派被动等待串口数据(超时等待 1Sec),解析后将结果输出至调试串口
- 查询模式: 梁山派按照 1Hz 频率发送查询命令给模块,将返回数据解析结果输出至调试串口
移植成功示例:
移植成功示例