2.47 达特 WZ-S 型甲醛检测模块(来自#ifndef 的贡献)
2.47.1 模块来源
采购链接: https://item.taobao.com/item.htm?spm=a1z09.2.0.0.23c42e8d87067p&id=558145830853&_u=dp4d6ab3253
资料下载:
实物展示图
2.47.2 规格参数
工作电压:5~7V工作电流:实测约 7mA通信方式:串口(3.3V)检测量程:0~2ppm分辨率: 0.001ppm **响应时间: <40****Sec** 使用手册
2.47.3 模块原理
电化学传感器模组,通过化学反应转换为电信号方式的装置.燃料电池一般使用环境苛刻且使用寿命较短,需在选型使用中着重考虑,具体参数请参见模块说明书内容.
2.47.4 移植工程
模块使用串口进行通信,通信速率 9600(8N1).模块使用 5V 供电,但通信信号电平为 3.3V,因此无需电平转换可同梁山派引脚直接连接.
2.47.4-2 移植步骤
创建 bsp_dartwzs.c
文档内容如下,其中函数 bsp_dartwzs_coroutine()为测试用例,具体使用可从函数 data_manage_xx()两函数中提取返回值:
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_dartwzs.h"
#include "systick.h" // Qa mode timeout
#include "bsp_usart.h" // communication interface & log
/* Private types -------------------------------------------------------------*/
/* Au mode data struct */
typedef struct
{
uint8_t head; ///< Always is 0xFF
uint8_t type; ///< Gas type 0x17
uint8_t unit; ///< Ppb 0x04
uint8_t decimal; ///< None
uint8_t ppmH; ///< Unit: 0.001ppm
uint8_t ppmL;
uint8_t rangeH; ///< range 0x07D0(0~2ppm)
uint8_t rangeL;
uint8_t checksum;
} DartWZSData_t;
/* Qa mode data struct */
typedef struct
{
uint8_t head; ///< Always is 0xFF
uint8_t command; ///< command 0x86
uint8_t ugnumH; ///< 1ug/m3=1ppm
uint8_t ugnumL;
uint8_t none0;
uint8_t none1;
uint8_t ppmH;
uint8_t ppmL;
uint8_t checksum;
} DartWZSQAData_t;
/* Private macros ------------------------------------------------------------*/
#define DARTWZS_BUFFER_SIZE 9u
/* User porting interfaces */
#define DARTWZS_API_INIT(n) bsp_uart_user_init((n))
#define DARTWZS_API_SEND(dat,len) bsp_uart_user_send((dat),(len))
#define DARTWZS_API_RECV(dat,len) bsp_uart_user_recv((dat),(len))
/* Private variables ---------------------------------------------------------*/
struct
{
bool initialize;
uint8_t mode; //Default mode is actively upload
} DartWZSInfo;
/* Private functions ---------------------------------------------------------*/
static uint8_t checksumGet( const uint8_t* _Data, uint8_t _Length );
static void bsp_dartwzs_request( void );
static int packet_format_check( const uint8_t* _Data, uint8_t _Length );
/* External variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
__API__ int bsp_dartwzs_init( void )
{
if( DartWZSInfo.initialize != false )
{
return 0;
}
/* Initialize uart port */
if( DARTWZS_API_INIT( 9600 ) != 0 )
{
return -1;
}
DartWZSInfo.initialize = true;
return 0;
}
static int data_manage_au( void )
{
uint8_t _buffer[DARTWZS_BUFFER_SIZE];
uint32_t _length;
/* Get data */
_length = DARTWZS_API_RECV( _buffer, DARTWZS_BUFFER_SIZE );
if( _length != DARTWZS_BUFFER_SIZE )
{
return 0;
}
/* parser data */
LOG_HEX( "AuData", 16, ( uint8_t* )_buffer, _length );
int _res = packet_format_check( _buffer, _length );
if( _res < 0 )
{
return _res;
}
/* Calculation data */
DartWZSData_t* _data;
_data = ( DartWZSData_t* )_buffer;
LOG_RAW( "Dart-AU-%dppm Range0~%d GasType[%02X] Unit[%02X]\r\n",
( ( _data->ppmH << 8 ) | _data->ppmL ),
( ( _data->rangeH << 8 ) | _data->rangeL ),
_data->type, _data->unit );
return ( ( _data->ppmH << 8 ) | _data->ppmL );
}
static int data_manage_qa( uint32_t _Timeout )
{
uint8_t _buffer[DARTWZS_BUFFER_SIZE];
uint32_t _length;
/* Request data */
bsp_dartwzs_request();
/* Wating sensor */
do
{
_length = DARTWZS_API_RECV( _buffer, DARTWZS_BUFFER_SIZE );
if( _length != DARTWZS_BUFFER_SIZE )
{
delay_1ms( 1 );
_Timeout--;
if( _Timeout == 0 )
{
return -1; // timeout
}
}
}
while( _length != DARTWZS_BUFFER_SIZE );
/* parser data */
LOG_HEX( "QaData", 16, ( uint8_t* )_buffer, _length );
int _res = packet_format_check( _buffer, _length );
if( _res < 0 )
{
return _res;
}
/* Calculation data */
DartWZSQAData_t* _data;
_data = ( DartWZSQAData_t* )_buffer;
LOG_RAW( "Dart-QA-%dppm %dug/m3\r\n", ( ( _data->ppmH << 8 ) | _data->ppmL ),
( ( _data->ugnumH << 8 ) | _data->ugnumL ) );
return ( ( _data->ppmH << 8 ) | _data->ppmL );
}
__API__ int bsp_dartwzs_coroutine( void )
{
int _res;
/* Data processing after initialization */
if( DartWZSInfo.initialize != true )
{
return 0;
}
if( DartWZSInfo.mode == true )
{
/* Questions and answer */
_res = data_manage_qa( 1000 );
if( _res < 0 )
{
LOG_RAW( "Dart-Error qa %d", _res );
}
}
else
{
/* Actively upload */
_res = data_manage_au();
if( _res < 0 )
{
LOG_RAW( "Dart-Error au %d\r\n", _res );
}
}
return 0;
}
/* ---- Commands -------------------------------------------------------------*/
__API__ int bsp_dartwzs_mode( uint8_t _Mode )
{
uint8_t _data[9];
uint8_t _len = 0x00;
/* Fill struct */
_data[_len++] = 0xFF; // head
_data[_len++] = 0x01;
_data[_len++] = 0x78; // Command
_data[_len++] = ( _Mode ? 0x41 : 0x40 ); // Mode
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = checksumGet( ( const uint8_t* ) _data, 0x09 );
/* Send command with no return */
if( DARTWZS_API_SEND( _data, 0x09 ) != 0x09 )
{
return -1;
}
/* Change mode */
if( _Mode )
{
DartWZSInfo.mode = true; // Questions and answer
LOG_RAW( "Dart-Set Qa mode\r\n" );
}
else
{
DartWZSInfo.mode = false; // Actively upload
LOG_RAW( "Dart-Set Au mode\r\n" );
}
return 0;
}
static void bsp_dartwzs_request( void )
{
uint8_t _data[9];
uint8_t _len = 0x00;
/* Fill struct */
_data[_len++] = 0xFF; // head
_data[_len++] = 0x01;
_data[_len++] = 0x86; // Command
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x00;
_data[_len++] = 0x79;
DARTWZS_API_SEND( _data, 0x09 );
}
static int packet_format_check( const uint8_t* _Data, uint8_t _Length )
{
assert( _Data );
if( _Length < 0x09 )
{
return -101; // data too short
}
/* Check data head */
if( _Data[0] != 0xFF )
{
return -102; // head not match
}
/* Check checksum */
uint8_t _checksum = checksumGet( _Data, 0x09 );
if( _Data[8] != _checksum )
{
LOG_RAW( "Dart-Checksum fail %02X-%02X\r\n", _Data[8], _checksum );
return -103; // Checksum check fail
}
return 0;
}
static uint8_t checksumGet( const uint8_t* _Data, uint8_t _Length )
{
assert( _Length > 2 );
uint8_t i;
uint8_t checksum = 0x00;
/* Skip default head byte */
for( i = 1; i < ( _Length - 1 ); i++ )
{
checksum += _Data[i];
}
return ( ( ~checksum ) + 1 );
}
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
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
创建 bsp_dartwzs.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_DARTWZS_H__
#define __BSP_DARTWZS_H__
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Exported constants --------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/// @brief Initialize Dart WZ-S sensor
/// @return @see bsp_uart_user_init
__API__ int bsp_dartwzs_init( void );
/// @brief Test function
/// @return sensor value. unit: 0.001ppm
__API__ int bsp_dartwzs_coroutine( void );
/// @brief Change sensor mode
/// @param _Mode true: QaMode false: AuMode(default when powerOn)
/// @retval -1: send command fail
/// @retval 0: success
__API__ int bsp_dartwzs_mode( uint8_t _Mode );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BSP_DARTWZS_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
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
相关串口驱动等底层驱动部分参见 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 16 // 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.47.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 "dartwzs/bsp_dartwzs.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_dartwzs_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_dartwzs_mode( true );
}
else if( count == 200 )
{
bsp_dartwzs_mode( false );
count = 0x00;
}
}
LOG_RAW( "Test count %d %s\r\n", count, ( count >= 100 ) ? "Qa" : "Au" );
bsp_dartwzs_coroutine(); // 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 秒切换一次模式,默认处于主动推送模式(1Hz).
- 推送模式: 梁山派被动等待串口数据(每秒查询一次),解析后将结果输出至调试串口
- 查询模式: 梁山派按照 1Hz 频率发送查询命令给模块,将返回数据解析结果输出至调试串口
注意: 日志中数据单位非实际单位,仅作为数据类型提示.如 ppm 值日志显示 3ppm 实际应为 0.003ppm
移植成功示例:
移植成功示例