使用F28069驱动温湿度传感器HDC1010

 HDC1010是德州仪器公司的一款高精度数字温湿度传感器,本文将介绍如何使用C2000中F28069驱动该芯片。因为篇幅限制,本文给出重要但非完整实现过程,同时有一定优化空间。

传感器主要特性

HDC1010是一款低功耗、高精度的数字温湿度传感器。该传感器的主要特性如下:

  • 相对湿度精度为±2%,温度精度为±0.2度;
  • 14位测量分辨率;
  • 睡眠模式的电流为100nA;
  • 电源电压为2.7V至5V;
  • I2C接口;

物理连接

HDC1010引脚

 芯片的引脚图如下:

  • ADR设置:ADR1与ADR0用于设置I2C地址,当2个引脚都下拉到GND时,HDC1010的7位地址为1000000;
  • SCL与SDA:为I2C管脚的时钟线与数据线,为开漏输出;
  • DRDYn:数据ready标志位,低电平有效,为开漏输出。

控制器硬件连接

 HDC1010的物理连接如下所示:

 本次使用的MCU为德州仪器公司的TMS320F28069,连接图如上图所示。HDC1010的SCL、SDA与DRDYn需要进行上拉。其中SCL与SDA使用F28069的硬件I2C-A,DRDYn使用一个GPIO输入端口即可。

初始化软件流程与底层配置

 本节将按照初始化软件流程、硬件底层配置的流程介绍。

初始化软件流程

 初始化流程代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
//I2C-A initialize
InitI2CGpio();
I2CA_Init();
//HDC DRDY PIN initialize
HDC_DRDY_Pin_Init();
ManufacturerID = HDC_GetData(Manufacturer_ID);
DeviceID = HDC_GetData(Device_ID);
HDC_GetConfig();
DELAY_US(40);
HDC_Config = HDC_GetData(ConfigADDR);

 初始化代码主要功能如下:

  • 初始化I2C-A:用于与HDC1010通讯;
  • 初始化DRDY PIN:用于判断data ready;
  • 读取ManufacturerID与DeviceID:用于判断I2C通讯是否成功;
  • 配置HDC1010:按照需求配置HDC1010;

I2C-A初始化

  • GPIO初始化:初始化I2C GPIO,尽管硬件上已经进行上拉操作,此处I2C IO依旧进行了上拉操作;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void InitI2CGpio()
{
EALLOW;
/* Enable internal pull-up for the selected pins */
GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0; // Enable pull-up for GPIO32 (SDAA)
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0; // Enable pull-up for GPIO33 (SCLA)
/* Set qualification for selected pins to asynch only */
GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // Asynch input GPIO32 (SDAA)
GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // Asynch input GPIO33 (SCLA)
/* Configure I2C pins using GPIO regs*/
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // Configure GPIO32 for SDAA operation
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // Configure GPIO33 for SCLA operation
EDIS;
}
  • 时钟设置:HDC1010支持的I2C最高时钟频率为400kHz,本次设置理论值为327kHz,具体计算过程请自行查阅F28069手册确定(也许我开心了就会写一篇介绍I2C的小文😄);
1
2
3
4
5
6
7
// Initialize I2C
I2caRegs.I2CMDR.all = 0x0000;
I2caRegs.I2CSAR = 0; // Slave address
I2caRegs.I2CPSC.all = 10; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
  • I2C中断设置:使能STOP与ARDY中断;
1
2
3
4
5
6
7
8
//I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts 0010 0100
I2caRegs.I2CIER.bit.AAS = 0; // Addressed as slave interrupt enable bit
I2caRegs.I2CIER.bit.SCD = 1; // Stop condition detected interrupt enable bit
I2caRegs.I2CIER.bit.XRDY = 0; // Transmit-data-ready interrupt enable bit
I2caRegs.I2CIER.bit.XRDY = 0; // Receive-data-ready interrupt enable bit
I2caRegs.I2CIER.bit.ARDY = 1; // Register-access-ready interrupt enable bit
I2caRegs.I2CIER.bit.NACK = 0; // No-acknowledgment interrupt enable bit
I2caRegs.I2CIER.bit.ARBL = 0; // Arbitration-lost interrupt enable bit
  • 模式与FIFO设置:使能I2C模块,使能FIFO功能;
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
//I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset,Stop I2C when suspended
I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit
I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended
I2caRegs.I2CMDR.bit.STT = 0; // START condition bit
I2caRegs.I2CMDR.bit.STP = 0; // STOP condition bit
I2caRegs.I2CMDR.bit.MST = 0; // Slave mode
I2caRegs.I2CMDR.bit.TRX = 0; // Receiver mode
I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode
I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode
I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled
I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled
I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode
I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled
I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte
//I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFTX.bit.I2CFFEN = 1; // Enable the I2C FIFO mode
I2caRegs.I2CFFTX.bit.TXFFRST = 1; // Enable the transmit FIFO operation
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 0; // Clear the TXFFINT flag
I2caRegs.I2CFFTX.bit.TXFFIENA = 0; // TXFFINT flag does not generate an interrupt when set
I2caRegs.I2CFFTX.bit.TXFFIL = 0; // Transmit FIFO interrupt level
//I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT
I2caRegs.I2CFFRX.bit.RXFFRST = 1; // Enable the receive FIFO operation
I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1; // Clear the RXFFINT flag
I2caRegs.I2CFFRX.bit.RXFFIENA = 0; // RXFFINT flag does generate an interrupt when set
I2caRegs.I2CFFRX.bit.RXFFIL = 0; // Receive FIFO interrupt level

DRDYn PIN初始化

 设置一个GPIO输入端口。

1
2
3
4
5
6
7
8
9
10
11
12
void HDC_DRDY_Pin_Init(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;
EDIS;
}
uint8 HDC_DRDY_Read(void)
{
return GpioDataRegs.GPADAT.bit.GPIO12;
}

至此,底层初始化完成。

传感器信息读取

设备信息读取

 ManufacturerID与DeviceID为传感器的固有信息,可以读取该信息确认I2C通讯有效性。

 HDC1010手册提供了Configuration寄存器的读写操作,可以类推到ManufacturerID与DeviceID寄存器的读取方法,如下图所示。注意ManufacturerID与DeviceID寄存器均为只读寄存器。

I2C读取寄存器的代码如下:

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
uint16 HDC_GetData(char REG_Address)
{
I2CA_ReadData(HDC1010_ADDR, REG_Address, 2, HDC_buffer);
return (HDC_buffer[0]<<8) + HDC_buffer[1];
}
void I2CA_ReadData(uint16 addr, uint16 reg, uint16 readCount, uint8 *buffer)
{
uint16 i;
I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C
// Make sure I2C is not busy and has stopped
while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop
I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit)
//while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop
I2caRegs.I2CSAR = addr; // I2C slave address
while (I2caRegs.I2CSTR.bit.BB == 1); // still busy?
I2caRegs.I2CMDR.all = 0x2620; // start, no stop bit, master, tx, reset I2C 00100110
// I2caRegs.I2CMDR.bit.NACKMOD = 0; // 15:NACK mode bit
// I2caRegs.I2CMDR.bit.FREE = 0; // 14:Stop I2C when suspended
// I2caRegs.I2CMDR.bit.STT = 1; // 13:START condition bit
// I2caRegs.I2CMDR.bit.STP = 0; // 11:STOP condition bit
// I2caRegs.I2CMDR.bit.MST = 1; // 10:Master mode
// I2caRegs.I2CMDR.bit.TRX = 1; // 9:Transmitter mode
// I2caRegs.I2CMDR.bit.XA = 0; // 8:7-bit addressing mode
// I2caRegs.I2CMDR.bit.RM = 0; // 7:Nonrepeat mode
// I2caRegs.I2CMDR.bit.DLB = 0; // 6:Digital loopback mode is disabled
// I2caRegs.I2CMDR.bit.IRS = 1; // 5:The I2C module is enabled
// I2caRegs.I2CMDR.bit.STB = 0; // 4:The I2C module is not in the START byte mode
// I2caRegs.I2CMDR.bit.FDF = 0; // 3:Free data format mode is disabled
// I2caRegs.I2CMDR.bit.BC = 0; // 2-0:8 bits per data byte
I2caRegs.I2CCNT = 1; // assume register address is one byte
I2caRegs.I2CDXR = reg; // register address of the sensor (1 byte)
while(!I2caRegs.I2CSTR.bit.ARDY); // all ready?
I2caRegs.I2CMDR.all = 0x2C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100
// I2caRegs.I2CMDR.bit.NACKMOD = 0; // 15:NACK mode bit
// I2caRegs.I2CMDR.bit.FREE = 0; // 14:Stop I2C when suspended
// I2caRegs.I2CMDR.bit.STT = 1; // 13:START condition bit
// I2caRegs.I2CMDR.bit.STP = 1; // 11:STOP condition bit
// I2caRegs.I2CMDR.bit.MST = 1; // 10:Master mode
// I2caRegs.I2CMDR.bit.TRX = 0; // 9:Transmitter mode
// I2caRegs.I2CMDR.bit.XA = 0; // 8:7-bit addressing mode
// I2caRegs.I2CMDR.bit.RM = 0; // 7:Nonrepeat mode
// I2caRegs.I2CMDR.bit.DLB = 0; // 6:Digital loopback mode is disabled
// I2caRegs.I2CMDR.bit.IRS = 1; // 5:The I2C module is enabled
// I2caRegs.I2CMDR.bit.STB = 0; // 4:The I2C module is not in the START byte mode
// I2caRegs.I2CMDR.bit.FDF = 0; // 3:Free data format mode is disabled
// I2caRegs.I2CMDR.bit.BC = 0; // 2-0:8 bits per data byte
I2caRegs.I2CCNT = readCount; // only read one byte data
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT; // 0x0002
}
I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0
while(!I2caRegs.I2CSTR.bit.SCD); // stop bit detected?
for (i = 0; i < readCount; i++)
{
buffer[i] = I2caRegs.I2CDRR; // read one byte data
}
}

 以读取ManufacturerID与DeviceID为例,使用逻辑分析仪得到的时序图如下所示。

 可见ManufacturerID与DeviceID寄存器读取到的值分别为0x5449、0x1000,与数据手册描述一致,读取正确。

Configuration寄存器

 对Configuration寄存器进行配置并读取确保写入已生效。Configuration寄存器的说明如下图所示。

 这里可以将Configuration设置为0x00,即关闭heater、温湿度独立读取、温湿度均为14位分辨率。

 逻辑分析仪得到的时序图如下图所示。

温湿度寄存器

 HDC1010中温湿度数据获取流程如下:触发采样-等待采样结束-读取采样信息。当采样未结束时读取数据将获得到一个NACK。数据手册中时序图如下图所示。

 代码实现如下所示:

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
uint16 HDC_GetTemperature(void)
{
int32 temp;
HDC_GetSensor(HDC1010_ADDR, TemperatureA, 2, temperature_buffer);
//HDC_GetSensor(HDC1010_ADDR, TemperatureA, 2, humidity_buffer);
temp = (temperature_buffer[0]<<8) + temperature_buffer[1];
return (temp * 1650>>16) - 400;
}
uint16 HDC_GetHumidity(void)
{
int32 humi;
HDC_GetSensor(HDC1010_ADDR, HumidityA, 2, humidity_buffer);
humi = (humidity_buffer[0]<<8) + humidity_buffer[1];
return humi * 1000 >> 16;
}
void HDC_GetSensor(uint16 addr, uint16 reg, uint16 readCount, uint8 *buffer)
{
uint16 i;
I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C
// Make sure I2C is not busy and has stopped
while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop
I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit)
//while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop
I2caRegs.I2CSAR = addr; // I2C slave address
while (I2caRegs.I2CSTR.bit.BB == 1); // still busy?
I2caRegs.I2CMDR.all = 0x2620; // start, no stop bit, master, tx, reset I2C 00100110
// I2caRegs.I2CMDR.bit.NACKMOD = 0; // 15:NACK mode bit
// I2caRegs.I2CMDR.bit.FREE = 0; // 14:Stop I2C when suspended
// I2caRegs.I2CMDR.bit.STT = 1; // 13:START condition bit
// I2caRegs.I2CMDR.bit.STP = 0; // 11:STOP condition bit
// I2caRegs.I2CMDR.bit.MST = 1; // 10:Master mode
// I2caRegs.I2CMDR.bit.TRX = 1; // 9:Transmitter mode
// I2caRegs.I2CMDR.bit.XA = 0; // 8:7-bit addressing mode
// I2caRegs.I2CMDR.bit.RM = 0; // 7:Nonrepeat mode
// I2caRegs.I2CMDR.bit.DLB = 0; // 6:Digital loopback mode is disabled
// I2caRegs.I2CMDR.bit.IRS = 1; // 5:The I2C module is enabled
// I2caRegs.I2CMDR.bit.STB = 0; // 4:The I2C module is not in the START byte mode
// I2caRegs.I2CMDR.bit.FDF = 0; // 3:Free data format mode is disabled
// I2caRegs.I2CMDR.bit.BC = 0; // 2-0:8 bits per data byte
I2caRegs.I2CCNT = 1; // assume register address is one byte
I2caRegs.I2CDXR = reg; // register address of the sensor (1 byte)
while(!I2caRegs.I2CSTR.bit.ARDY); // all ready?
//while (HDC_DRDY_Read() != HDC_Ready);
// first read and should return a NACK
I2caRegs.I2CMDR.all = 0x2C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100
I2caRegs.I2CCNT = readCount; // only read one byte data
while (HDC_DRDY_Read() != HDC_Ready);
I2caRegs.I2CMDR.all = 0x2C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100
I2caRegs.I2CCNT = readCount; // only read one byte data
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT; // 0x0002
}
I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0
while(!I2caRegs.I2CSTR.bit.SCD); // stop bit detected?
for (i = 0; i < readCount; i++)
{
buffer[i] = I2caRegs.I2CDRR; // read one byte data
}
}

 使用逻辑分析仪获取的时序图分为2部分展示:1是触发采样,尝试读取结果得到一个NACK,同时DRDYn变为高电平,表示采样进行中;2是DRDYn出现下降沿代表采样完成,控制器读取采样结果。

总结

 至此,初步说明了HDC1010传感器的基本使用原则。由于篇幅限制,其中例如寄存器原始数据转化为温湿度值等过程这里不再叙述。😄

文章目录
  1. 1. 传感器主要特性
  2. 2. 物理连接
    1. 2.1. HDC1010引脚
    2. 2.2. 控制器硬件连接
  3. 3. 初始化软件流程与底层配置
    1. 3.1. 初始化软件流程
    2. 3.2. I2C-A初始化
    3. 3.3. DRDYn PIN初始化
  4. 4. 传感器信息读取
    1. 4.1. 设备信息读取
    2. 4.2. Configuration寄存器
    3. 4.3. 温湿度寄存器
  5. 5. 总结
|