Zdravim, nemůžu dostat informace z cidla teploty a vlhkosti SHT11. Mám ho připojen na piny PC0 (SCL) a PC1 (SDA) na ATMEGA32, kterou mám ve vývojovém kitu EvB 4.3. Poraďte prosím, co tam mám špatně. Vypisuje mi to hodnotu u teploty 615. Zapojení EvB 4.3 je zde:http://www.hw.cz/…ry-atmel-avr
Zde je můj program:
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>
#include <avr/wdt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "lcd_h.h"
#include "SHT11.h"
unsigned int i_tempr[2], i_humi[2];
void led()
{
PORTB=~(PORTB);
_delay_ms( 10000 ) ;
}
int main(void)
{
char tmp[32];
unsigned char *p_value;
float humidity,temperature; // premenne pre teplotu a vhlkost v desatinnom tvare
// -------- toto staci nastavit iba raz cize pojde pred while (1) --------
/*adc_init(); // prevodnik init
// timery
Timer0_int();
Timer1_int();
Timer2_int();*/
lcd_init();
lcd_clrscr();
lcd_puts("Test");
//sei(); // povoleni preruseni
// nastaveni blikatka
DDRB=0b11110000;
PORTB=0x00;
_delay_ms( 10000 ) ;
while(1)
{
//write_statusreg(0x00);
temperature= (float) SHT_measure_tempr(); //zmeraj teplotu
humidity= (float) SHT_measure_hum(); //zmeraj vlhkost
calc_sth71(&humidity,&temperature);
i_tempr[0]=temperature; //ulozenie celociselnej casti
i_tempr[1]=(temperature-i_tempr[0])*100;
i_humi[0]=humidity; //ulozenie celociselnej casti nameranej vlhkosti
i_humi[1]=(humidity-i_humi[0])*100;
//led(); // blikatko
sprintf(tmp, "test %d", i_tempr[0]);
lcd_clrscr();
lcd_puts(tmp);
_delay_ms( 10000 ) ;
}
}
A zde knihovna SHT11:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
#include <stdlib.h>
#include <inttypes.h>
#include "SHT11.h"
//----------------------------------------------------------------------------------
unsigned char SHT_start(void) // generuje start __ __
{ // CLK ___/ \___/ \___
// ____ ____
// DATA \______/
SHT_DDR |= SHT_DATA|SHT_SCK; // Nastavenie datoveho pinu ako vystup
SHT_PORT &= ~SHT_SCK; // SCK=0
for(int i = 0; i < 10; i++)
{
SHT_PORT |= SHT_SCK; //SCK=1
SHT_Delay();
SHT_PORT &= ~SHT_SCK; // SCK=0
SHT_Delay();
}
_delay_ms(12);
SHT_PORT |= SHT_DATA|SHT_SCK; // DATA=1
SHT_PORT &= ~SHT_SCK; // SCK=0
SHT_Delay();
SHT_PORT |= SHT_SCK; //SCK=1
SHT_Delay();
SHT_PORT &= ~SHT_DATA; //DATA=0
SHT_Delay();
SHT_PORT &= ~SHT_SCK; //SCK=0
SHT_Delay();
SHT_PORT |= SHT_SCK; //SCK=1
SHT_Delay();
SHT_PORT |= SHT_DATA; //DATA=1
SHT_Delay();
SHT_PORT &= ~SHT_SCK; //SCK=0
SHT_Delay();
}
void SHT_Delay(void)
{
int i;
//for (i=0;i<40;i++); // kratka casova slucka
_delay_ms(1);
}
unsigned char SHT_write( unsigned char data )
{
unsigned char i;
SHT_DDR |= SHT_DATA; //DATA pin - vystup
for (i=0x80;i>0;i/=2) // posuvanie bitu pre odmaskovanie
{
if (i & data) SHT_PORT |= SHT_DATA; // logicka maska a porovnanie hodnot. V pripade, ze sa hodnoty rovnaju vysledok operacie bude "1" - vykona sa kod v if-e
else SHT_PORT &= ~SHT_DATA; // v pripade, ze sa nerovnaju vykona sa kod v else
SHT_Delay();
SHT_PORT |= SHT_SCK; // synchronizacny impulz
SHT_Delay();
SHT_PORT &= ~SHT_SCK;
SHT_Delay();
}
SHT_Delay();
SHT_PORT |= SHT_DATA; //uvolnenie DATA-line
SHT_DDR &= ~SHT_DATA; //DATA-line ako vstup (pull-up pripojeny)
SHT_Delay();
SHT_PORT |= SHT_SCK; //clk #9 ako ack
SHT_Delay();
if (SHT_PIN & SHT_DATA)
HumiError = TRUE;
SHT_PORT &= ~SHT_SCK;
SHT_Delay();
}/* i2c_write */
unsigned char SHT_read( unsigned char ack)
{
unsigned char i,val=0;
SHT_PORT |= SHT_DATA; //uvolnenie DATA-line
SHT_DDR &= ~SHT_DATA; //DATA-line in input
for (i=0x80;i>0;i/=2) //bitovy posuv
{
SHT_Delay();
SHT_PORT |= SHT_SCK; //clk na zbernicu snimaca SENSI-BUS
SHT_Delay();
if (SHT_PIN & SHT_DATA) val=(val | i); //precitanie bitu
SHT_PORT &= ~SHT_SCK;
}
if (ack == 1)
{
SHT_DDR |= SHT_DATA; //DATA-line ako vystup
SHT_PORT &= ~SHT_DATA; //"ack==1"
SHT_Delay();
SHT_PORT |= SHT_SCK;
SHT_Delay();
SHT_PORT &= ~SHT_SCK;
}
else
{
SHT_Delay();
SHT_PORT |= SHT_SCK;
SHT_Delay();
SHT_PORT &= ~SHT_SCK;
}
return val;
}/* i2c_readAck */
//----------------------------------------------------------------------------------
char read_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// precita status register
{
unsigned char status=0;
unsigned char p_checksum=0;
SHT_start(); //zaciatok komunikace
SHT_write(STATUS_REG_R); //odoslanie prikazu do snimaca pre citanie status registra
*p_value=SHT_read(ACK); //precita status register (8-bit)
p_checksum=SHT_read(ACK); //precita checksum (8-bit)
return SHT_read(noACK); //error=1 v pripadnem, ze snimac neodpoveda
}
//----------------------------------------------------------------------------------
char write_statusreg(unsigned char p_value)
//----------------------------------------------------------------------------------
//zapise do status registra snimaca + checksum (8-bit)
{
unsigned char error=0;
SHT_start(); //spustenie komunikacie
error+= SHT_write(STATUS_REG_W); //poslanie prikazu do snimaca
error+= SHT_write(p_value); //precita checksum
return error; //error=1 v pripadnem, ze snimac neodpoveda
}
//----------------------------------------------------------------------------------
unsigned int SHT_measure_tempr(void)
//----------------------------------------------------------------------------------
// Meria teplotu (temperature) bez checksum. Pozn. Staci odkomentovat SHT_read(); a mozeme prijat checksum
{
unsigned int temperature=0;
unsigned char temperature_H=0;
unsigned char temperature_L=0;
SHT_start();
_delay_ms(12);
SHT_write(MEASURE_TEMP); // pošli príkaz
_delay_ms(321); // čakaj 320ms na dokončenie merania
temperature_H=SHT_read(ACK); // prijatie horneho bytu
temperature_L=SHT_read(noACK); // prijatie dolneho bytu
//SHT_read(); // nemusí sa prijimat
//snimac by mal automaticky prejst do rezimu spanku. Prebudi sa po prikaze start
temperature=temperature_H; //ulozenie hodnoty do jedneho registra. Najskor ulozime horny byte
temperature=(temperature<<8); //posunieme ho
temperature|=temperature_L; //a ulozime spodny byte
return temperature;
}
//----------------------------------------------------------------------------------
unsigned int SHT_measure_hum(void)
//----------------------------------------------------------------------------------
// Meria vlhkost (humidity) bez checksum. Pozn. Staci odkomentovat SHT_read(); a mozeme prijat checksum
{
unsigned int humidity = 0;
unsigned char humidity_H=0;
unsigned char humidity_L=0;
SHT_start();
SHT_write(MEASURE_HUMI);
_delay_ms(100); // čakaj 80ms na dokončenie merania
humidity_H=SHT_read(ACK); // prijatie horneho bytu
humidity_L=SHT_read(noACK); // prijatie dolneho bytu
//SHT_read(); // nemusí sa prijimat
//snimac by mal automaticky prejst do rezimu spanku. Prebudi sa po prikaze start
humidity=humidity_H; //ulozenie hodnoty do jedneho registra. Najskor ulozime horny byte
humidity=(humidity<<8); //posunieme ho
humidity|=humidity_L; //a ulozime spodny byte
return humidity;
}
void calc_sth71(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// vykonava vypocet teploty [°C] a vlhkosti [%RH]
// vstup : p_humidity [Ticks] (12 bit)
// p_temperature [Ticks] (14 bit)
// vystup: p_humidity [%RH]
// p_temperature [°C]
{
/*
const float C1=-2.0468; // Konstanty pre prepocet vlhksoti pre 12bitove rozlisenie
const float C2=+0.0367;
const float C3=-0.0000015955;
const float T1=+0.01;
const float T2=+0.00008; */
const float C1 = -4.0; // for 12 Bit
const float C2 = 0.0405; // for 12 Bit
const float C3 = -0.0000028; // for 12 Bit
const float T1 = 0.01; // for 14 Bit @ 5V
const float T2 = 0.00008; // for 14 Bit @ 5V
float rh=*p_humidity; // rh: Vlhkost 12 Bit
float t=*p_temperature; // t: Teplota 14 Bit
float rh_lin; // rh_lin: Vlhkost linearizovana
float rh_true; // rh_true: Teplotne kompenzovana vlhkost
float t_C; // t_C: Teplota v [°C]
t_C=t*0.01 - 40.1; //vypocet teploty [°C] v 14 bit rozsahu @ 5V
rh_lin=C3*rh*rh + C2*rh + C1; //vypocet vlhkosti/linearizaca vlhkosti [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //ypocet pre vlhkosti pre teplotnu kompenzaciu [%RH]
if(rh_true>100)rh_true=100; //orezanie hodnoty an fyzicky mozny rozsah
if(rh_true<0.1)rh_true=0.1; //orezanie hodnoty na fyzicky mozny rozsah
*p_temperature=t_C; //ulozenie teploty [°C]
*p_humidity=rh_true; //ulozenie vlhkosti[%RH]
}
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// Vypocet rosneho bodu
// vstup: h-humidity [%RH], f-temperature [°C]
// vystup: rosny bod - dew point [°C]
{
float dew_point ;
double k;
k = (log10(h)-2)/0.4343 + (17.62*t)/(243.12+t);
dew_point = 243.12*k/(17.62-k);
return dew_point;
}