2.43 HP203B 气压高度传感器
2.43.1 模块来源
采购链接: https://item.szlcsc.com/149984.html
**图 2.43.1-1 产品实物展示**2.43.2 规格参数
工作电压:1.8-3.6V 消耗电流:最大 1.3mA 压力量程:300mbar~1200mbar 压力精度:±1.5mbar 高度精度:10cm
通信接口:IIC 尺寸大小:46x30x17.6mm 相关资料手册
2.43.3 移植过程
我们的目标是在梁山派 GD32F470 上能够判断粉尘浓度的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.43.3.1 查看资料
HP203B 是高分辨率(0.1meter)压力传感器,带有 I²C 接口,包括一个硅压阻压力元件和一个高分辨率 24 位 △∑ ADC。HP203B 提供高精度 24 位压力和温度数字输出,客户可以根据应用需要转换速度和高度,所 有内置计算采用了高速 4MHz 的浮点运算,计算误差小,数据补偿是内部集成,通讯连接非常简单,高度及温 度上下限比较的可编程事件及中断输出控制。HP203B 传感器是采用不锈钢盖子表面封装和符合 RoHS 标准,尺 寸非常小,仅为 3.6x3.8mm,厚度为 1.2mm。
可以直接读取压力值,高度值,温度值
2.43.3.2 引脚选择
######### HP203B | ######### 立创·梁山派 | ######### 接线图 |
---|
2.43.3.3 移植至工程
移植步骤中的导入.c 和.h 文件与上一节相同,只是将.c 和.h 文件更改为 bsp_hb203b.c 与 bsp_hb203b.h。见 2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件 bsp_hb203b.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_hb203b.h"
#include "systick.h"
/******************************************************************
* 函 数 名 称:IIC_Init
* 函 数 说 明:IIC引脚初始化
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Init(void)
{
/* 使能时钟 */
rcu_periph_clock_enable(RCU_IIC_SCL);
rcu_periph_clock_enable(RCU_IIC_SDA);
/* 配置SCL为输出模式 */
gpio_mode_set(PORT_IIC_SCL,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_IIC_SCL);
/* 配置为推挽输出 50MHZ */
gpio_output_options_set(PORT_IIC_SCL,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_IIC_SCL);
/* 配置SDA为输出模式 */
gpio_mode_set(PORT_IIC_SDA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_IIC_SDA);
/* 配置为推挽输出 50MHZ */
gpio_output_options_set(PORT_IIC_SDA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_IIC_SDA);
}
/******************************************************************
* 函 数 名 称:IIC_Start
* 函 数 说 明:IIC开始信号
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
char IIC_Start(void)
{
SDA_OUT();
SCL(1);
SDA(0);
SDA(1);
delay_us(5);
SDA(0);
delay_us(5);
SCL(0);
return 0;
}
/******************************************************************
* 函 数 名 称:IIC_Stop
* 函 数 说 明:IIC停止信号
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_us(5);
SDA(1);
delay_us(5);
}
/******************************************************************
* 函 数 名 称:IIC_Write_Byte
* 函 数 说 明:IIC写一个字节
* 函 数 形 参:要写的数据
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Write_Byte(uint8_t dat)
{
int i = 0;
SDA_OUT();
SCL(0);//拉低时钟开始数据传输
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
__nop();
SCL(1);
delay_us(5);
SCL(0);
delay_us(5);
dat<<=1;
}
}
/******************************************************************
* 函 数 名 称:IIC_Read_Byte
* 函 数 说 明:IIC读取一个字节
* 函 数 形 参:无
* 函 数 返 回:读到的字节
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL(0);
delay_us(5);
SCL(1);
delay_us(5);
receive<<=1;
if( SDA_GET() )
{
receive|=1;
}
delay_us(5);
}
SCL(0);
return receive;
}
/******************************************************************
* 函 数 名 称:IIC_Send_Nack
* 函 数 说 明:IIC发送非应答
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Send_Nack(void)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
SDA(1);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
/******************************************************************
* 函 数 名 称:IIC_Send_Ack
* 函 数 说 明:IIC发送应答
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Send_Ack(void)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
SDA(0);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
/******************************************************************
* 函 数 名 称:I2C_WaitAck
* 函 数 说 明:等待从机应答
* 函 数 形 参:无
* 函 数 返 回:0有应答 1超时无应答
* 作 者:LC
* 备 注:无
******************************************************************/
unsigned char I2C_WaitAck(void)
{
char ack = 0;
unsigned char ack_flag = 10;
SCL(0);
SDA(1);
SDA_IN();
SCL(1);
while( (SDA_GET()==1) && ( ack_flag ) )
{
ack_flag--;
delay_us(5);
}
if( ack_flag <= 0 )
{
IIC_Stop();
return 1;
}
else
{
SCL(0);
SDA_OUT();
}
return ack;
}
/******************************************************************
* 函 数 名 称:HP203B_Reset
* 函 数 说 明:传感器复位
* 函 数 形 参:无
* 函 数 返 回:0=复位成功 1=未检测到传感器 2=写数据失败
* 作 者:LC
* 备 注:无
******************************************************************/
char HP203B_Reset(void)
{
IIC_Start();
IIC_Write_Byte(0xEE); //addr+w
if( I2C_WaitAck() == 1 ) return 1;
IIC_Write_Byte(0x06); //cmd reset
if( I2C_WaitAck() == 1 ) return 2;
IIC_Stop();
return 0;
}
/******************************************************************
* 函 数 名 称:HP203B_StartConv
* 函 数 说 明:传感器开始转换数据
* 函 数 形 参:无
* 函 数 返 回:0=设置成功 1=未检测到传感器 2=发送数据失败
* 作 者:LC
* 备 注:
******************************************************************/
char HP203B_StartConv(void)
{
IIC_Start();
IIC_Write_Byte(0xEE); //addr+w
if( I2C_WaitAck() == 1 ) return 1;
IIC_Write_Byte(0x40); //cmd conv+osr(4096)+ch(pt)
if( I2C_WaitAck() == 1 ) return 2;
IIC_Stop();
return 0;
}
/******************************************************************
* 函 数 名 称:HP203B_ReadReg
* 函 数 说 明:读取传感器的某一个寄存器
* 函 数 形 参:reg_addr寄存器地址
* 函 数 返 回:1=未检测到传感器 2=读寄存器失败 其他=成功读到的值
* 作 者:LC
* 备 注:无
******************************************************************/
unsigned char HP203B_ReadReg(unsigned char reg_addr)
{
uint8_t val =0;
IIC_Start();
IIC_Write_Byte(0xEE); //devaddr+w
if( I2C_WaitAck() == 1 ) return 1;
IIC_Write_Byte(0x80|reg_addr); //reg addr
if( I2C_WaitAck() == 1 ) return 2;
IIC_Stop();
IIC_Start();
IIC_Write_Byte(0xEF); //addr+r
val = IIC_Read_Byte(); //read + nack
IIC_Send_Nack();
IIC_Stop();
return val;
}
/******************************************************************
* 函 数 名 称:HP203B_WriteReg
* 函 数 说 明:向某个寄存器写入一个值
* 函 数 形 参:reg_addr=要写入的地址 reg_val=要写入的值
* 函 数 返 回:1=未检测到设备 2=寄存器未响应 3=写入失败 0=写入成功
* 作 者:LC
* 备 注:无
******************************************************************/
char HP203B_WriteReg(unsigned char reg_addr, unsigned char reg_val)
{
IIC_Start();
IIC_Write_Byte(0xEE); //devaddr+w
if( I2C_WaitAck() == 1 ) return 1;
IIC_Write_Byte(0x80|reg_addr); //reg addr
if( I2C_WaitAck() == 1 ) return 2;
IIC_Write_Byte(reg_val);
if( I2C_WaitAck() == 1 ) return 3;
IIC_Stop();
return 0;
}
/******************************************************************
* 函 数 名 称:HP203B_ReadData
* 函 数 说 明:读取传感器数据
* 函 数 形 参:T=温度数据保存的地址 P=气压数据要保存的地址 A=海拔数据要保存的地址
* 函 数 返 回:1=未检测到设备 2=寄存器未响应 3=读取失败
* 作 者:LC
* 备 注:
******************************************************************/
char HP203B_ReadData(float *T, float *P, float *A)
{
uint8_t buf[6];
int data;
//read Pressure
IIC_Start();
IIC_Write_Byte(0xEE); //addr+w
if( I2C_WaitAck() == 1 ) return 1;
IIC_Write_Byte(0x30); //cmd read p
if( I2C_WaitAck() == 1 ) return 2;
IIC_Stop();
IIC_Start();
IIC_Write_Byte(0xEF); //addr+r
if( I2C_WaitAck() == 1 ) return 3;
buf[0] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[1] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[2] = IIC_Read_Byte(); //read + nack
IIC_Send_Nack();
IIC_Stop();
data = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) & 0xfffff;
if(data & 0x80000)
data |= 0xfff00000; //补码处理
*P = data/100.0; //单位 mbar
//read Temperature
IIC_Start();
IIC_Write_Byte(0xEE); //addr+w
if( I2C_WaitAck() == 1 ) return 4;
IIC_Write_Byte(0x32); //cmd read t
if( I2C_WaitAck() == 1 ) return 5;
IIC_Stop();
IIC_Start();
IIC_Write_Byte(0xEF); //addr+r
if( I2C_WaitAck() == 1 ) return 6;
buf[0] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[1] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[2] = IIC_Read_Byte(); //read + nack
IIC_Send_Nack();
IIC_Stop();
data = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) & 0xfffff;
if(data & 0x80000)
data |= 0xfff00000; //补码处理
*T = data/100.0; //单位 摄氏度
//read Altitude
IIC_Start();
IIC_Write_Byte(0xEE); //addr+w
if( I2C_WaitAck() == 1 ) return 7;
IIC_Write_Byte(0x31); //cmd read a
if( I2C_WaitAck() == 1 ) return 8;
IIC_Stop();
IIC_Start();
IIC_Write_Byte(0xEF); //addr+r
if( I2C_WaitAck() == 1 ) return 9;
buf[0] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[1] = IIC_Read_Byte(); //read + ack
IIC_Send_Ack();
buf[2] = IIC_Read_Byte(); //read + nack
IIC_Send_Nack();
IIC_Stop();
data = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) & 0xfffff;
if(data & 0x80000)
data |= 0xfff00000; //补码处理
*A = data/100.0; //单位 0.01m
return 0;
}
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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
在文件 bsp_hb203b.h 中,编写如下代码。
cpp
#ifndef _BSP_HB203B_H_
#define _BSP_HB203B_H_
#include "gd32f4xx.h"
//-----------------IIC端口移植----------------
//SCL - PA8 I2C2_SCL
//SDA - PC9 I2C2_SDA
#define RCU_IIC_SCL RCU_GPIOA//SCL
#define PORT_IIC_SCL GPIOA
#define GPIO_IIC_SCL GPIO_PIN_8
#define RCU_IIC_SDA RCU_GPIOC//SDA
#define PORT_IIC_SDA GPIOC
#define GPIO_IIC_SDA GPIO_PIN_9
//设置SDA输出模式
#define SDA_OUT() gpio_mode_set(PORT_IIC_SDA,GPIO_MODE_OUTPUT,GPIO_MODE_OUTPUT,GPIO_IIC_SDA)
//设置SDA输入模式
#define SDA_IN() gpio_mode_set(PORT_IIC_SDA,GPIO_MODE_INPUT,GPIO_MODE_OUTPUT,GPIO_IIC_SDA)
//获取SDA引脚的电平变化
#define SDA_GET() gpio_input_bit_get(PORT_IIC_SDA,GPIO_IIC_SDA)
//SDA与SCL输出
#define SDA(x) gpio_bit_write(PORT_IIC_SDA,GPIO_IIC_SDA, (x?SET:RESET))
#define SCL(x) gpio_bit_write(PORT_IIC_SCL,GPIO_IIC_SCL, (x?SET:RESET))
void IIC_Init(void);
char HP203B_Reset(void);
char HP203B_StartConv(void);
unsigned char HP203B_ReadReg(unsigned char reg_addr);
char HP203B_ReadData(float *T, float *P, float *A);
#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
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
2.43.4 移植验证
在自己工程中的 main 主函数中,编写如下。
cpp
#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "stdlib.h"
#include "bsp_hb203b.h"
int main(void)
{
float pressure, temperature, altitude;
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组
systick_config();//滴答定时器初始化 1ms
usart_gpio_config(115200);
printf("start run\r\n");
//硬件IIC初始化
IIC_Init();
HP203B_Reset();
delay_1ms(100);
HP203B_StartConv();
while(1)
{
//读取温度气压海拔数据
if(HP203B_ReadReg(0x0d) & 0x40)
{
HP203B_ReadData(&temperature, &pressure, &altitude);
HP203B_StartConv();
}
//显示HP203的温度数据
printf("TEMP = %.2f\r\n", temperature);
//显示HP203的气压数据
printf("PRES = %.2f\r\n", pressure );
//显示HP203的海拔数据
printf("ALTI = %.2f\r\n",altitude );
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
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
移植现象:输出温度、气压、海拔高度数据。
移植成功示例,见文件 2.43.4-1 。
文件 2.43.4-1 移植成功示例