【前言】
我提交的计划为冷链监控系统,因此采集温湿度是首要步骤。这篇将分享如何采集sht30并实现手动上报数据,在接收端打印出接收到的数据。
【硬件】
1、TKB-620开发板*2
2、sht30温湿度计
【实现步骤】
1、查找开发板的原理图,获取IIC的接口,从厂家提供的原理图中,有温湿度计的接口J14:

他的接口为PB10(I2C_SCL)、PB11(I2C_SDA)。
由于没有焊接转接坐,因此需要自己焊好插座。
2、在keil工程中添加sht3x.c/h文件并且将其添加到工程中:

sht3x.c的源代码如下:
#include "stm32f10x.h"
#include <stdio.h>
#define SHT30_I2C_SCL_PIN GPIO_Pin_10
#define SHT30_I2C_SDA_PIN GPIO_Pin_11
#define SHT30_I2C_GPIO_PORT GPIOB
#define SHT30_I2C RCC_APB1Periph_I2C2
#define SHT30_ADDR 0x44 << 1
void SHT30_I2C_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(SHT30_I2C, ENABLE);
GPIO_InitStructure.GPIO_Pin = SHT30_I2C_SCL_PIN | SHT30_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SHT30_I2C_GPIO_PORT, &GPIO_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C2, &I2C_InitStructure);
I2C_Cmd(I2C2, ENABLE);
}
void SHT30_SendCommand(uint8_t cmd[2]) {
while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C2, ENABLE);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2, SHT30_ADDR, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2, cmd[0]);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C2, cmd[1]);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C2, ENABLE);
}
void SHT30_ReadData(uint8_t *data, uint8_t length) {
while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C2, ENABLE);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2, SHT30_ADDR, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
for (uint8_t i = 0; i < length; i++) {
if (i == length - 1) {
I2C_AcknowledgeConfig(I2C2, DISABLE);
}
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED));
data[i] = I2C_ReceiveData(I2C2);
}
I2C_AcknowledgeConfig(I2C2, ENABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
}
void SHT30_ReadTemperatureAndHumidity(float *temperature, float *humidity) {
uint8_t cmd[2] = {0x2C, 0x06};
uint8_t data[6];
SHT30_SendCommand(cmd);
for (volatile uint32_t i = 0; i < 100000; i++);
SHT30_ReadData(data, 6);
uint16_t rawTemp = (data[0] << 8) | data[1];
uint16_t rawHumidity = (data[3] << 8) | data[4];
*temperature = -45 + (175 * (float)rawTemp / 65535);
*humidity = 100 * (float)rawHumidity / 65535;
}
sht3x.h主要是开放sht3x的初始以及读取数据的函数:
#ifndef __SHT3X_H__
#define __SHT3X_H__
void SHT30_I2C_Init(void);
void SHT30_ReadTemperatureAndHumidity(float *temperature, float *humidity);
#endif
3、添加测试信息,我将读取函数放到按键发送的函数中,他在user.c的RF_SendDataOnce中,修改后的发送函数如下:
void RF_SendDataOnce(void)
{
float temperature, humidity;
char cmd[50];
SHT30_ReadTemperatureAndHumidity(&temperature, &humidity);
printf("Temperature: %.2f C, Humidity: %.2f %%\n", temperature, humidity);
sys_param.txSentCnt++;
// sprintf(cmd, "AT+SENDB=0001020304%04x\r\n", sys_param.txSentCnt);
sprintf(cmd, "AT+SENDB=000100%02d%02d%02d%02d\r\n", (int)temperature,((int)(temperature*100))%100,(int)humidity,((int)(humidity*100))%100);
Send_AtCmd(cmd);
}
在此函数中,我先获取sht3x的温湿度,并通过sprintf组装成字符串,通过senc_Atcmd发送出去。
【实验效果】
将sht30连接到开发板,按下send键,在另一块开发板上就收到数据了:

【小结】
通过上述代码的修改,就简单的实现了数据采集功能,下一步,我将修改状态机,来实现定时发送,或者是上位机发送指令后,采集上报。