HTU21D sıcaklık nem sensörü ile ölçüm yapmaya çalışıyorum.Fakat okuma kısmında tahmin edebileceğiniz üzere I2C donuyor :)
PIC12F1822 kullanıyorum.Kodlar aşağıda bir bakarsanız sevinirim.
/*
* File : I2C.C
* Author : Baran EKREM
* Description :
* Created :
*/
#include "I2C.h"
#include "TypeDef.h"
/*******************************************************************************
* Function Name : I2C_Init
* Description :
* Input : None
* Return : None
*******************************************************************************/
void I2C_Init(void) {
// R_nW write_noTX; P stopbit_notdetected; S startbit_notdetected; BF RCinprocess_TXcomplete; SMP Sample At Middle; UA dontupdate; CKE Idle to Active; D_nA lastbyte_address;
SSP1STAT = 0x00;
// SSPEN enabled; WCOL no_collision; CKP Idle:Low, Active:High; SSPM FOSC/4_SSPxADD; SSPOV no_overflow;
SSP1CON1 = 0x28;
// ACKTIM ackseq; SBCDE disabled; BOEN disabled; SCIE disabled; PCIE disabled; DHEN disabled; SDAHT 100ns; AHEN disabled;
SSP1CON3 = 0x00;
// Baud Rate Generator Value: SSPADD 79;
SSP1ADD = 0x4F;
}
/*******************************************************************************
* Function Name : I2C_Wait
* Description :
* Input : None
* Return : None
*******************************************************************************/
void I2C_Wait(void) {
while ((SSP1CON2 & 0x1F) || (SSPSTAT & 0x04));
}
/*******************************************************************************
* Function Name : I2C_Start
* Description :
* Input : None
* Return : None
*******************************************************************************/
void I2C_Start(void) {
I2C_Wait();
SEN=1;
}
/*******************************************************************************
* Function Name : I2C_Restart
* Description :
* Input : None
* Return : None
*******************************************************************************/
void I2C_Restart(void) {
I2C_Wait();
RSEN=1;
}
/*******************************************************************************
* Function Name : I2C_Stop
* Description :
* Input : None
* Return : None
*******************************************************************************/
void I2C_Stop(void) {
I2C_Wait();
PEN=1;
}
/*******************************************************************************
* Function Name : I2C_Write
* Description :
* Input : uint8_t
* Return : None
*******************************************************************************/
void I2C_Write(uint8_t data) {
I2C_Wait();
SSPBUF = data;
}
/*******************************************************************************
* Function Name : I2C_Address
* Description :
* Input : uint8_t
* Return : uint8_t
*******************************************************************************/
void I2C_Address(uint8_t address, uint8_t mode) {
uint8_t l_address;
l_address = (address << 1);
l_address += mode;
I2C_Wait();
SSPBUF = l_address;
}
/*******************************************************************************
* Function Name : I2C_ReadData
* Description :
* Input : uint8_t
* Return : uint8_t
*******************************************************************************/
uint8_t I2C_ReadData(uint8_t ack) {
uint8_t data;
I2C_Wait();
RCEN = 0b1;
I2C_Wait();
data = SSPBUF;
I2C_Wait();
if (ack)
ACKDT = 0b0;
else
ACKDT = 0b1;
ACKEN = 0b1;
return(data);
}
/*
* File : HTU21D.c
* Author : Baran EKREM
* Description :
* Created :
*/
#include "HTU21D.h"
#include "TypeDef.h"
#include "Delay.h"
#include "I2C.h"
/*******************************************************************************
* Function Name : HTU21D_Init
* Description :
* Input : None
* Return : None
*******************************************************************************/
void HTU21D_Init(void) {
I2C_Init();
}
/*******************************************************************************
* Function Name : HTU21D_SetResolution
* Description :
* Input : uint8_t resolution
* Return : None
*******************************************************************************/
/*
void HTU21D_SetResolution(uint8_t resolution) {
//Go get the current register state
uint8_t userRegister = read_user_register();
//Turn off the resolution bits
userRegister &= 0b01111110;
//Turn off all other bits but resolution bits
resolution &= 0b10000001;
//Mask in the requested resolution bits
userRegister |= resolution;
//Request a write to user register
Wire.beginTransmission(HTDU21D_ADDRESS);
//Write to the user register
Wire.write(WRITE_USER_REG);
//Write the new resolution bits
Wire.write(userRegister);
Wire.endTransmission();
}
*/
/*******************************************************************************
* Function Name : HTU21D_ReadHumidity
* Description :
* Input : None
* Return : float Humidity
*******************************************************************************/
float HTU21D_ReadHumidity(void) {
uint8_t msb, lsb, checksum;
I2C_Start();
I2C_Address(HTDU21D_ADDRESS, I2C_WRITE);
I2C_Write(TRIGGER_HUMD_MEASURE_HOLD);
I2C_Restart();
I2C_Address(HTDU21D_ADDRESS, I2C_READ);
msb = I2C_ReadData(0);
lsb = I2C_ReadData(0);
checksum = I2C_ReadData(0);
I2C_Stop();
uint16_t rawHumidity = ((uint16_t) msb << 8) | (uint16_t) lsb;
if(check_crc(rawHumidity, checksum) != 0)
return(999); //Error out
//sensorStatus = rawHumidity & 0x0003; //Grab only the right two bits
rawHumidity &= 0xFFFC; //Zero out the status bits but keep them in place
float rh = -6.0 + 125.0 * rawHumidity / 65536.0;
return(rh);
}
/*******************************************************************************
* Function Name : HTU21D_ReadTemperature
* Description :
* Input : None
* Return : float Temperature
*******************************************************************************/
float HTU21D_ReadTemperature(void) {
uint8_t msb, lsb, checksum;
I2C_Start();
I2C_Address(HTDU21D_ADDRESS, I2C_WRITE);
I2C_Write(TRIGGER_TEMP_MEASURE_HOLD);
I2C_Restart();
I2C_Address(HTDU21D_ADDRESS, I2C_READ);
msb = I2C_ReadData(0);
lsb = I2C_ReadData(0);
checksum = I2C_ReadData(0);
I2C_Stop();
uint16_t rawTemperature = ((uint16_t) msb << 8) | (uint16_t) lsb;
if(check_crc(rawTemperature, checksum) != 0)
return(999); //Error out
//sensorStatus = rawTemperature & 0x0003; //Grab only the right two bits
rawTemperature &= 0xFFFC; //Zero out the status bits but keep them in place
float temp = -46.85 + 175.72 * rawTemperature / 65536.0;
return(temp);
}
/*******************************************************************************
* Function Name : read_user_register
* Description :
* Input : None
* Return : uint8_t userReg
*******************************************************************************/
/*
uint8_t read_user_register(void) {
uint8_t userRegister;
//Request the user register
Wire.beginTransmission(HTDU21D_ADDRESS);
//Read the user register
I2C_Write(READ_USER_REG);
Wire.endTransmission();
//Read result
Wire.requestFrom(HTDU21D_ADDRESS, 1);
userRegister = I2C_ReadData(1);
return(userRegister);
}
*/
/*******************************************************************************
* Function Name : check_crc
* Description :
* Input : message_from_sensor, check_value_from_sensor
* Return : uint8_t
*******************************************************************************/
uint8_t check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor) {
//Test cases from datasheet:
//message = 0xDC, checkvalue is 0x79
//message = 0x683A, checkvalue is 0x7C
//message = 0x4E85, checkvalue is 0x6B
//Pad with 8 bits because we have to add in the check value
uint32_t remainder = (uint32_t)message_from_sensor << 8;
//Add on the check value
remainder |= check_value_from_sensor;
uint32_t divsor = (uint32_t)SHIFTED_DIVISOR;
//Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
for (int i = 0 ; i < 16 ; i++) {
if( remainder & (uint32_t)1<<(23 - i) ) //Check if there is a one in the left position
remainder ^= divsor;
divsor >>= 1; //Rotate the divsor max 16 times so that we have 8 bits left of a remainder
}
return ((uint8_t)remainder);
}
main
/*
* File : main.c
* Author : Baran EKREM
* Description :
* Created : 16/11/2015 22:10
*/
/* Includes */
#include "main.h"
#include "Delay.h"
#include "TypeDef.h"
#include "I2C.h"
#include "HTU21D.h"
#include "UART.h"
/* Macro Defines */
#define LED (PORTAbits.RA0)
#define LED_TRIS (TRISAbits.TRISA0)
/* Global Veriables */
/* Function Prototypes */
static void Clock_Init(void);
static void GPIO_Init(void);
/* Interrupts */
void interrupt ISR(void) {
}
/*******************************************************************************
* Function Name : main
* Description : main program
* Input : void
* Return : void
*******************************************************************************/
void main(void) {
Clock_Init();
GPIO_Init();
UART_Init();
HTU21D_Init();
LED = 1;
for(;;) {
float temp = HTU21D_ReadTemperature();
UART_SendData((uint8_t)temp);
Delay_ms(500);
} /* End for */
} /* End Main */
/*******************************************************************************
* Function Name : Clock_Init
* Description : 32MHz Internal OSC Configuration
* Input : void
* Return : void
*******************************************************************************/
static void Clock_Init(void) {
//8 MHz Internal OSC Selected
OSCCONbits.IRCF = 0b1110;
// PLL Enabled
OSCCONbits.SPLLEN = 0b1;
// Some Wait
Delay_ms(1000);
// Wait for PLL
while(!OSCSTATbits.PLLR);
// Wait for HFIOFR
while(!OSCSTATbits.HFIOFR);
}
/*******************************************************************************
* Function Name : GPIO_Init
* Description : GPIO Configuration
* Input : None
* Return : None
*******************************************************************************/
static void GPIO_Init(void) {
// No Analog Pin
ANSELA = 0x00;
// ALL pin Output
TRISA = 0x00;
// All pins Low
PORTA = 0x00;
//
LED_TRIS = 0;
}