AGS10是一款采用数字信号输出的MEMS TVOC传感器。配置了专用的数字模块采集技术和气体感应传感技术,确保了产品具有极高的可靠性与卓越的长期稳定性,同时具有低功耗、高灵敏度、快速响应、成本低、驱动电路简单等特点。
一、模块来源
采购链接:
二、规格参数
工作电压 : 3.0-6.0 V
典型功率 : 75mW
采样周期 : ≥2s
接口速率 :I2C从机模式(≤15kHz)
预热时间 : ≥120s
工作温度 : 0~50℃
工作湿度 : 0~95%RH
寿命 : >5年(25℃,清洁空气中)
输出单位 : ppb
测量范围 : 0~99999 ppb
典型精度( 25℃/50%RH): 25% 读数
标准测试气体 : 乙醇
模块尺寸:15*10.6mm
以上信息见厂家资料文件
三、移植过程
1、查看资料
工作原理
AGS10传感器采用标准I 2C通信协议,适应多种设备。IIC的物理接口包含串行数据信号(SDA)与串行时钟信号(SCL)两个接口。两个接口需通过1kΩ~10kΩ电阻上拉至VDD。SDA用于读、写传感器数据。SCL上电必须保持高电平直到进行IIC通信开始,否则会引起I 2C通讯不良。当I 2C通信时SCL用于主机与传感器之间的通讯同步。多个I2C设备可以共享总线,但是只能允许一个主机设备出现在总线上。既然采用的是IIC,那么我们需要知道它的IIC通信地址。
读取TVOC数据的步骤:
2、引脚选择
VCC | 3V3 |
GND | GND |
SCL | GPIO51 |
SDA | GPIO50 |
接下来我们配置 SYSCONFIG
- 双击 c2000.syscfg 文件,打开它。
- 点击ADD添加GPIO配置
- 配置GPIO
其他引脚一样的配置,除了引脚的编号和名字不一样
Ctrl + S
保存配置文件Ctrl + B
构建工一次工程(可能会报错,我们不用管!)然后我们所有设定的引脚和功能就会在 board.h 中定义。因为这个文件我们包含进了 tjx_init.h 所以我们只需要引用 tjx_init.h 即可。【这里的 tjx_init.h 就充当了芯片头文件的作用】
3、代码编写
我们在工程中新建 module_driver
,并在其中新建两个文件 bsp_ags10.c
和 bsp_ags10.h
,并且将头文件路径添加到编译器中。
在文件 bsp_ags10.c 中,编写如下代码。
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#include "bsp_ags10.h"
//起始信号
void AGS10_IIC_Start(void)
{
SDA_OUT();
SDA(1);
SCL(1);
delay_1us(5);
SDA(0);
delay_1us(5);
SCL(0);
delay_1us(5);
}
//停止信号
void AGS10_IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_1us(5);
SDA(1);
delay_1us(5);
}
//发送非应答
void AGS10_IIC_Send_Nack(void)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
SDA(1);
SCL(1);
delay_1us(5);
SCL(0);
SDA(1);
}
//发送应答
void AGS10_IIC_Send_Ack(void)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
SDA(0);
SCL(1);
delay_1us(5);
SCL(0);
SDA(1);
}
/**********************************************************
* 函 数 名 称:I2C_WaitAck
* 函 数 功 能:等待从机应答
* 传 入 参 数:无
* 函 数 返 回:1=非应答 0=应答
* 作 者:LCKFB
* 备 注:无
**********************************************************/
unsigned char AGS10_I2C_WaitAck(void)
{
char ack = 0;
unsigned char ack_flag = 100;
SDA_IN();
SDA(1);
delay_us(5);
SCL(1);
delay_us(5);
while( (SDA_GET()==1) && ( ack_flag ) )
{
ack_flag--;
delay_1us(5);
}
//非应答
if( ack_flag <= 0 )
{
AGS10_IIC_Stop();
return 1;
}
else//应答
{
SCL(0);
SDA_IN();
}
return ack;
}
//发送一个字节
void AGS10_IIC_Send_Byte(uint8_t dat)
{
int i = 0;
SDA_OUT();
SCL(0);
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
delay_1us(5);
SCL(1);
delay_1us(5);
SCL(0);
delay_1us(5);
dat<<=1;
}
}
//接收一个字节
unsigned char AGS10_IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL(0);
delay_1us(5);
SCL(1);
delay_1us(5);
receive<<=1;
if( SDA_GET() )
{
receive |= 1;
}
}
SCL(0);
return receive;
}
/**********************************************************
* 函 数 名 称:ags10_read
* 函 数 功 能:读取AGS10的TVOC浓度数据
* 传 入 参 数:无
* 函 数 返 回:0: 成功
* 1: 通信失败
* 2:发送失败
* 3:等待超时
* 4: 校验失败
* 作 者:LCKFB
* 备 注:
**********************************************************/
char ags10_read(uint32_t *tvoc_dat)
{
uint8_t timeout = 0;
uint8_t data[5] = {0};
AGS10_IIC_Start();
AGS10_IIC_Send_Byte(0X34);
if( AGS10_I2C_WaitAck() == 1 ) return 1;
AGS10_IIC_Send_Byte(0X00);
if( AGS10_I2C_WaitAck() == 1 ) return 2;
AGS10_IIC_Stop();
do{
delay_1ms(1);
timeout++;
AGS10_IIC_Start();
AGS10_IIC_Send_Byte(0X35);
}while( (AGS10_I2C_WaitAck() == 1) && (timeout < 50) );
//如果超时
if( timeout >= 50 ){
lc_printf("\ntimeout\r\n");
return 3;
}
data[0] = AGS10_IIC_Read_Byte();
AGS10_IIC_Send_Ack();
data[1] = AGS10_IIC_Read_Byte();
AGS10_IIC_Send_Ack();
data[2] = AGS10_IIC_Read_Byte();
AGS10_IIC_Send_Ack();
data[3] = AGS10_IIC_Read_Byte();
AGS10_IIC_Send_Ack();
data[4] = AGS10_IIC_Read_Byte();
AGS10_IIC_Send_Nack();
AGS10_IIC_Stop();
*tvoc_dat = ((uint32_t)data[1]<<16) | ((uint16_t)data[2]<<8) | data[3];
return 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
在文件 bsp_ags10.h 中,编写如下代码。
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#ifndef _BSP_AGS10_H_
#define _BSP_AGS10_H_
#include "tjx_init.h"
//设置SDA输出模式
#define SDA_OUT() GPIO_setDirectionMode(Module_SDA, GPIO_DIR_MODE_OUT)
//设置SDA输入模式
#define SDA_IN() GPIO_setDirectionMode(Module_SDA, GPIO_DIR_MODE_IN)
//获取SDA引脚的电平变化
#define SDA_GET() GPIO_readPin(Module_SDA)
//SDA与SCL输出
#define SDA(x) GPIO_writePin(Module_SDA, x)
#define SCL(x) GPIO_writePin(Module_SCL, x)
char ags10_read(uint32_t *tvoc_dat);
#endif
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
四、移植验证
在 empty_driverlib_main.c
中输入代码如下:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
#include "tjx_init.h"
#include "bsp_ags10.h"
void main(void)
{
/* The initialization code automatically generated by CCS [Start] */
Device_init();
Device_initGPIO();
Interrupt_initModule();
Interrupt_initVectorTable();
Board_init();
C2000Ware_libraries_init();
EINT;
ERTM;
/* The initialization code automatically generated by CCS [End] */
lc_printf("\r\n= = = = = = = = = = = = = = = = = = = = = = = = =\r\n");
lc_printf("\r\n=== Welcome to use the LC-TJX-TMS320F28P550 ====\r\n");
lc_printf("\r\n============== www.lckfb.com ===================\r\n");
lc_printf("\r\n============== wiki.lckfb.com ==================\r\n");
lc_printf("\r\n= = = = = = = = = = = = = = = = = = = = = = = = =\r\n");
while(1)
{
uint32_t tvoc_dat = 0;
int ret = ags10_read(&tvoc_dat);
if(!ret){
lc_printf("AGS10 TVOC = [ %d ppb ]\r\n", tvoc_dat);
}else{
lc_printf("AGS10 Read Failed!\r\n");
lc_printf("AGS10 Ret = %d\r\n",ret);
}
// RGB的B灯亮起,G灯熄灭
GPIO_writePin(RGB_B, 0);
GPIO_writePin(RGB_G, 1);
delay_ms(300);
// RGB的G灯亮起,B灯熄灭
GPIO_writePin(RGB_B, 1);
GPIO_writePin(RGB_G, 0);
delay_ms(300);
// RGB的B和G都熄灭
GPIO_writePin(RGB_B, 1);
GPIO_writePin(RGB_G, 1);
delay_ms(300);
}
}
__interrupt void INT_Debug_Serial_RX_ISR(void)
{
//清除接收中断标志位
SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);
//清除中断标志位
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
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
【代码下载】
- 跳转到
下载中心
去下载CCS模块移植代码:【点击跳转🚀】