#include "shtxx.h"
void shtxx_init(void)
{
shtxx_temp = shtxx_humi = 0;
SHTXX_SCK_LOW();
SHTXX_DAT_1();
shtxx_reconnect();
}
void shtxx_reconnect(void)
{
SHTXX_DAT_1();
SHTXX_SCK_LOW();
for(uint8 i=0; i<9; i++)
{
SHTXX_SCK_HIGH(); SHTXX_SCK_LOW();
}
SHTXX_START();
}
uint8 shtxx_SOFtrst(void)
{
uint8 error = 0;
shtxx_reconnect();
error += shtxx_write_byte(SHTXX_SOFT_RST);
return error;
}
//写命令函数
//参数:命令类型
//返回:0成功,1失败
uint8 shtxx_write_byte(uint8 cmd)
{
uint8 ack;
for (uint8 i=8; i>0; i--)
{
if (BITCHK(cmd, (i-1))) //trans ’1’
{
SHTXX_DAT_1();
SHTXX_SCK_HIGH(); SHTXX_SCK_LOW();
}
else //trans ’0’
{
SHTXX_DAT_0();
SHTXX_SCK_HIGH(); SHTXX_SCK_LOW();
}
}
//SHTxx 会以下述方式表示已正确地接收到指令:
//在第8 个SCK 时钟的下降沿之后,将DATA 下拉为低电平(ACK 位)。
//在第9 个SCK 时钟的下降沿之后,释放DATA(恢复高电平)。
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
SHTXX_SCK_HIGH();
ack = BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT);
SHTXX_SCK_LOW();
return ack;
}
uint8 shtxx_read_byte(uint8 dat_crc)
{
uint8 dat8 = 0;
for (uint8 i=8; i>0; i--)
{
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
c4680504cSHTXX_SCK_HIGH();
if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))
BITSET(dat8, (i-1));
SHTXX_SCK_LOW();
}
if (dat_crc)
{
SHTXX_DAT_0();
SHTXX_SCK_HIGH(); SHTXX_SCK_LOW();
}
else
{
SHTXX_DAT_1();
SHTXX_SCK_HIGH(); SHTXX_SCK_LOW();
}
SHTXX_DAT_1();
return dat8;
}
int8 shtxx_measure(uint8 mode)
{
uint8 error = 0;
SHTXX_START();
switch (mode)
{
case SHTXX_MODE_TEMP:
error = shtxx_write_byte(SHTXX_CMD_TEMPTURE);
for(uint16 i=0; i<65535; i++)
{
_delay_us(5);
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
if (!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))) break;
}
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)) error += 1;
shtxx_temp = shtxx_read_byte(1);
shtxx_temp = (shtxx_temp << 8) + shtxx_read_byte(1);
shtxx_crc = shtxx_read_byte(0);
break;
case SHTXX_MODE_HUMI:
error = shtxx_write_byte(SHTXX_CMD_HUMIDITY);
for(uint16 i=0; i<65535; i++)
{
_delay_us(5);
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
if (!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT))) break;
}
BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT);
if (BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)) error += 1;
shtxx_humi = shtxx_read_byte(1);
shtxx_humi = (shtxx_humi<<8) + shtxx_read_byte(1);
shtxx_crc = shtxx_read_byte(0);
break;
default:
break;
}
return error;
}
void shtxx_calc(void)
{
uint32 rh_line = 0;
//所有湿度常量放大10000000
const uint32 C1 = 40000000;
const uint32 C2 = 405000;
const uint32 C3 = 28;
const uint32 T1 = 100000;
const uint32 T2 = 8000;
//温度常量放大100
t_c = shtxx_temp - 4000; //结果除以100
rh_line = C2*shtxx_humi - C3*shtxx_humi*shtxx_humi - C1;
rh_true = (t_c/100-25)*(T1+T2*shtxx_humi) + rh_line;
if (rh_true>1000000000) rh_true = 1000000000; //cut if the value is outside of
if (rh_true<1000000) rh_true = 1000000; //the physICal possible range
}
void hex_bcd(uint32 hex32)
{
MEMSet(bcd32, ’\0’, 10);
while (hex32 >= 1000000000) //
{
bcd32[9]++;
hex32 = hex32 - 1000000000;
}
while (hex32 >= 100000000) //
{
bcd32[8]++;
hex32 = hex32 - 100000000;
}
while (hex32 >= 10000000) //
{
bcd32[7]++;
hex32 = hex32 - 10000000;
}
while (hex32 >= 1000000) //
{
bcd32[6]++;
hex32 = hex32 - 1000000;
}
while (hex32 >= 100000) //
{
bcd32[5]++;
hex32 = hex32 - 100000;
}
while (hex32 >= 10000) //
{
bcd32[4]++;
hex32 = hex32 - 10000;
}
while (hex32 >= 1000) //
{
bcd32[3]++;
hex32 = hex32 - 1000;
}
while (hex32 >= 100) //
{
bcd32[2]++;
hex32 = hex32 - 100;
}
while (hex32 >= 10) //
{
bcd32[1]++;
hex32 = hex32 - 10;
}
bcd32[0] = hex32;
}
void shtxx_disp(void)
{
if (!shtxx_measure(SHTXX_MODE_TEMP))
{
shtxx_calc();
hex_bcd(t_c);
LCD_print_str(2, 1, "温度: ");
if(bcd32[4] != 0)
lcd_write_dat(bcd32[4]+0x30);
lcd_write_dat(bcd32[3]+0x30);
lcd_write_dat(bcd32[2]+0x30);
lcd_write_dat(’.’);
lcd_write_dat(bcd32[1]+0x30);
lcd_write_dat(bcd32[0]+0x30);
}
if (!shtxx_measure(SHTXX_MODE_HUMI))
{
shtxx_calc();
hex_bcd(rh_true);
lcd_print_str(3, 1, "湿度: ");
if(bcd32[9] != 0)
lcd_write_dat(bcd32[9]+0x30);
lcd_write_dat(bcd32[8]+0x30);
lcd_write_dat(bcd32[7]+0x30);
lcd_write_dat(’.’);
lcd_write_dat(bcd32[6]+0x30);
lcd_write_dat(bcd32[5]+0x30);
}
}
shtxx.H
#ifndef _SHTXX_H
#define _SHTXX_H
#include "config.h"
#define SHTXX_SCK_DDR DDRC
#define SHTXX_SCK_PORT PORTC
#define SHTXX_SCK_BIT (0)
#define SHTXX_DAT_DDR DDRC
#define SHTXX_DAT_PORT PORTC
#define SHTXX_DAT_PIN PINC
#define SHTXX_DAT_BIT (1)
#define SHTXX_SCK_HIGH() {BITSET(SHTXX_SCK_DDR, SHTXX_SCK_BIT); BITSET(SHTXX_SCK_PORT, SHTXX_SCK_BIT); _delay_us(10);}
#define SHTXX_SCK_LOW() {BITSET(SHTXX_SCK_DDR, SHTXX_SCK_BIT); BITCLR(SHTXX_SCK_PORT, SHTXX_SCK_BIT); _delay_us(10);}
#define SHTXX_DAT_1() {BITSET(SHTXX_DAT_DDR, SHTXX_DAT_BIT); _delay_us(1); BITSET(SHTXX_DAT_PORT, SHTXX_DAT_BIT); _delay_us(5);}
#define SHTXX_DAT_0() {BITSET(SHTXX_DAT_DDR, SHTXX_DAT_BIT); _delay_us(1); BITCLR(SHTXX_DAT_PORT, SHTXX_DAT_BIT); _delay_us(5);}
#define SHTXX_START() {SHTXX_DAT_1(); SHTXX_SCK_LOW(); SHTXX_SCK_HIGH(); SHTXX_DAT_0(); SHTXX_SCK_LOW(); _delay_us(2); SHTXX_SCK_HIGH(); SHTXX_DAT_1(); SHTXX_SCK_LOW();}
#define SHTXX_ACK() {BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); if(!(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT)));}
#define SHTXX_WAIT() {BITCLR(SHTXX_DAT_DDR, SHTXX_DAT_BIT); while(BITCHK(SHTXX_DAT_PIN, SHTXX_DAT_BIT));}
#define SHTXX_CMD_TEMPTURE 0b00000011
#define SHTXX_CMD_HUMIDITY 0b00000101
#define SHTXX_RD_STATE_REG 0b00000111
#define SHTXX_WR_STATE_REG 0b00000110
#define SHTXX_SOFT_RST 0b00011110
#define SHTXX_MODE_TEMP 0x01
#define SHTXX_MODE_HUMI 0x02
uint16 shtxx_temp, shtxx_humi;
uint8 shtxx_crc;
uint32 t_c, rh_true;
uint8 bcd32[10];
void shtxx_init(void);
void shtxx_reconnect(void);
uint8 shtxx_write_byte(uint8 cmd);
uint8 shtxx_softrst(void);
uint8 shtxx_read_byte(uint8 dat_crc);
#endif
上一篇:AVR定时器T1中断示例程序
下一篇:DS1302的AVR单片机C程序
推荐阅读最新更新时间:2024-03-16 15:49