📄 arm_sht.c
字号:
/***************************************************
2007/2/10
Liu Guobing
****************************************************/
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [癈]
// 4. calculate dew point [癈]
// 5. print temperature, humidity, dew point
#include "ARM_SHT.h"
fp32 Temp_Value,Humi_Value; //温湿度值,可与外围接口
uint32 SHT_Step=0; //温湿度测量步骤控制
//-----------------------------------------------------------------------------------------
//温度,湿度测量部分
//-----------------------------------------------------------------------------------
uint8 s_write_byte(uint8 value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
uint8 i,error=0;
for (i=0x80;i>0;i/=2) { //shift bit for masking
if (i & value) { //masking value with i , write to SENSI-BUS
SHT_DATA_SET();
}
else {
SHT_DATA_CLR();
}
SHT_SCK_SET(); //clk for SENSI-BUS
Delay_us(_SHT_Shout_Time_); //pulswith approx. 5 us
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
SHT_DATA_SET(); //release SHT_DATA-line
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET(); //clk #9 for ack
Delay_us(_SHT_Shout_Time_);
//error=SHT_DATA; //check ack (SHT_DATA will be pulled down by SHT11)
SHT_DATA_In();
if(Read_SHT_DATA()) {
error=true;
}
else {
error=false;
}
SHT_DATA_Out();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
return error; //error=1 in case of no acknowledge
Delay_us(_SHT_Shout_Time_);
}
//----------------------------------------------------------------------------------
uint8 s_read_byte(uint8 ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
uint8 i,val=0;
SHT_DATA_SET(); //release SHT_DATA-line
SHT_DATA_In(); //SHT_DATA input
Delay_us(_SHT_Shout_Time_);
for (i=0x80;i>0;i/=2) { //shift bit for masking
SHT_SCK_SET(); //clk for SENSI-BUS
Delay_us(_SHT_Shout_Time_);
if (Read_SHT_DATA()) {
val=(val | i); //read bit
}
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
//SHT_DATA=!ack; //in case of "ack==1" pull down SHT_DATA-Line
if(ack) {
SHT_DATA_CLR();
}
else {
SHT_DATA_SET();
}
SHT_DATA_Out();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET(); //clk #9 for ack
Delay_us(_SHT_Shout_Time_); //pulswith approx. 5 us
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_SET(); //release SHT_DATA-line
return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// SHT_DATA: |_______|
// ___ ___
// SHT_SCK : ___| |___| |______
{
SHT_DATA_SET(); //Initial state
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_DATA_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: SHT_DATA-line=1 and at least 9 SHT_SCK cycles followed by transstart
// _____________________________________________________ ________
// SHT_DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SHT_SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
uint8 i;
SHT_DATA_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR(); //Initial state
Delay_us(_SHT_Shout_Time_);
for(i=0;i<9;i++) { //9 SHT_SCK cycles
SHT_SCK_SET();
Delay_us(_SHT_Shout_Time_);
SHT_SCK_CLR();
Delay_us(_SHT_Shout_Time_);
}
s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
uint8 s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
uint8 error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uint8 s_read_statusreg(uint8 *p_value, uint8 *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
uint8 error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uint8 s_write_statusreg(uint8 *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
uint8 error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------------
void calc_sth11(fp32 *p_humidity ,fp32 *p_temperature) {
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [癈]
// 温湿度转换公式
//Temperature = d1+d2 * temp[Ticks]
//RH_lin = c1 + c2*SO + c3 * humi[Ticks]
//RH_true = (T - 25)*(t + t * humi[Ticks] ) + RH_lin
const fp32 C1=-4.0; // for 12 Bit
const fp32 C2=+0.0405; // for 12 Bit
const fp32 C3=-0.0000028; // for 12 Bit
const fp32 T1=+0.01; // for 14 Bit @ 5V
const fp32 T2=+0.00008; // for 14 Bit @ 5V
fp32 rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
fp32 t=*p_temperature; // t: Temperature [Ticks] 14 Bit
fp32 rh_lin; // rh_lin: Humidity linear
fp32 rh_true; // rh_true: Temperature compensated humidity
fp32 t_C; // t_C : Temperature [癈]
t_C=t*0.01 - 40; //calc. temperature from ticks to [癈]
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [癈]
*p_humidity=rh_true; //return humidity[%RH]
}
//清除与温湿度有关的所有显示
void SHT_Display_Disable(void) //关闭温湿度显示
{
LCD_Show_Logo(L_RH, false); //关闭与体温显示相关的Logo
LCD_Show_Logo(L_P4, false); //温度显示小数点
LCD_Show_Logo(L_P5, false); //温度符号显示
LCD_Show_Logo(L_P6, false);
LCD_Show_Logo(L_P7, false);
LCD_Show_Logo(L_29A, false);
LCD_Show_Number(N_C1, 10); //关闭与体温显示相关的数字位
LCD_Show_Number(N_C2, 10);
LCD_Show_Number(N_C3, 10);
LCD_Show_Number(N_R1, 10);
LCD_Show_Number(N_R2, 10);
return;
}
//显示温湿度函数
//--------------------------------------------------------------------
void SHT_Display(fp32 * SHT_RH, fp32 * SHT_TC)
{
if((*SHT_TC >= 100)||(*SHT_TC <= -10)) return; //数据过滤,不可大于100或小于-10
if(*SHT_TC >= 0.1) {
LCD_Show_Number(N_C1, (uint8)(*SHT_TC/10));
LCD_Show_Number(N_C2, ((uint8)(*SHT_TC))%10);
LCD_Show_Number(N_C3, ((uint8)((*SHT_TC)*10))%10);
}
else if(*SHT_TC <= -0.1) { //当前温度小于0度时
LCD_Show_Number(N_C1, LCD_N_Bar);//显示 "-"
LCD_Show_Number(N_C2, (uint8)(*SHT_TC));
LCD_Show_Number(N_C3, ((uint8)((*SHT_TC)*10)));
}
else { //当前温度为0度时
LCD_Show_Number(N_C1, 10); //第一位不显示,即最终显示 0.0 C
LCD_Show_Number(N_C2, 0);
LCD_Show_Number(N_C3, 0);
}
LCD_Show_Logo(L_P4, true); //温度显示小数点
LCD_Show_Logo(L_P5, true); //温度符号显示
if((*SHT_RH>=100)||(*SHT_RH<0)) return; //湿度数据过滤,应该可以不用
LCD_Show_Number(N_R1, (uint8)(*SHT_RH/10));
LCD_Show_Number(N_R2, ((uint8)(*SHT_RH))%10);
if(*SHT_RH>0.5) { //判断是否显示小数位 ".5"
LCD_Show_Logo(L_29A, true);
}
else {
LCD_Show_Logo(L_29A, false);
}
LCD_Show_Logo(L_RH, true); //湿度 “RH ” Logo
LCD_Show_Logo(L_P6, true); //湿度显示小数点
LCD_Show_Logo(L_P7, true); //湿度 "%" Logo
return;
}
//温湿度测量主函数
void SHT_Measure(void)
{
uint32 error=0;
uint32 Temp_CheckSum,Humi_CheckSum;
switch(SHT_Step) //温湿度测量步聚控制
{
case 0: { //发送测量温度命令
SHT_SCK_Out();
SHT_DATA_Out();
Delay_us(_SHT_Shout_Time_);
s_transstart(); //transmission start
error+=s_write_byte(MEASURE_TEMP); //send command to sensor
SHT_Overtime_Time=_SHT_Overtime_Time_;
SHT_DATA_In();
SHT_Step+=10;
break;
}
case 10: { //等待温度测量结束发送湿度测量命令
if(!Read_SHT_DATA()) {
Temp_Value = s_read_byte(ACK)<<8; //读取温度数字值
Temp_Value += s_read_byte(ACK);
Temp_CheckSum = s_read_byte(noACK);
SHT_DATA_Out();
s_transstart(); //transmission start
error+=s_write_byte(MEASURE_HUMI); //send command to sensor
SHT_Overtime_Time=_SHT_Overtime_Time_;
SHT_DATA_In();
SHT_Step+=10;
}
else { //判断接收温度是否超时
if(!SHT_Overtime_Time) {
COM_PutCR(); //串口输出超时字符,调试用
UART0_SendByte('S');
UART0_SendByte('H');
UART0_SendByte('T');
UART0_SendByte(' ');
UART0_SendByte('O');
UART0_SendByte('T');
SHT_Step=0;
SHT_Measure_Time=_SHT_Measure_Time_;
//...
}
}
break;
}
case 20: { //等待湿度测量结束,并计算显示温湿度值
if(!Read_SHT_DATA()) {
Humi_Value = s_read_byte(ACK)<<8; //读取温度数字值
Humi_Value += s_read_byte(ACK);
Humi_CheckSum = s_read_byte(noACK);
SHT_SCK_In(); //数字端口恢复初始状态
SHT_DATA_In();
calc_sth11(&Humi_Value,&Temp_Value);//calculate humidity, temperature
SHT_Display(&Humi_Value,&Temp_Value);
SHT_Step=0;
SHT_Measure_Time=_SHT_Measure_Time_;
}
else { //超时判断
if(!SHT_Overtime_Time) {
COM_PutCR(); //串口输出超时字符,调试用
UART0_SendByte('S');
UART0_SendByte('H');
UART0_SendByte('T');
UART0_SendByte(' ');
UART0_SendByte('O');
UART0_SendByte('T');
SHT_Step=0;
SHT_Measure_Time=_SHT_Measure_Time_;
//...
}
}
break;
}
}
if(error!=0) { //如前面出现通信错误则发关软复位指令
SHT_SCK_Out();
SHT_DATA_Out();
s_connectionreset();
SHT_SCK_In();
SHT_DATA_In();
SHT_Step=0;
SHT_Measure_Time=_SHT_Measure_Time_;
error=0;
}
return;
}
#if 0
const fp32 C1=-4.0; // for 12 Bit
const fp32 C2=+0.0405; // for 12 Bit
const fp32 C3=-0.0000028; // for 12 Bit
const fp32 T1=+0.01; // for 14 Bit @ 5V
const fp32 T2=+0.00008; // for 14 Bit @ 5V
fp32 rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
fp32 t=*p_temperature; // t: Temperature [Ticks] 14 Bit
fp32 rh_lin; // rh_lin: Humidity linear
fp32 rh_true; // rh_true: Temperature compensated humidity
fp32 t_C; // t_C : Temperature [癈]
t_C=t*0.01 - 40; //calc. temperature from ticks to [癈]
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [癈]
*p_humidity=rh_true; //return humidity[%RH]
#endif
#if 0
const uint32 C1=40000000; //-4.0 * 10000000
const uint32 C2=405000;
const uint32 C3=28;
const uint32 T1=0.01;
const uint32 T2=0.00008;
//const uint32 T1=100000;
//const uint32 T2=800;
uint32 t,t_C;
uint32 rh,rh_lin_high,rh_lin_low,rh_true;
t=Temp_Value*10000-40*100;
Temp_Value = t/100;
Temp_Value_Decimal = t%100;
rh=Humi_Value*C2-Humi_Value*Humi_Value*C3-C1;
rh_true=(Temp_Value-25)*()
rh_lin_high = rh/10000000;
rh_lin_low = rh%10000000;
#endif
#if 0
//--------------------------------------------------------------------
fp32 calc_dewpoint(fp32 h,fp32 t) {
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [癈]
// output: dew point [癈]
fp32 logEx,dew_point;
logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
return dew_point;
}
#endif
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -