HTU21D I2C kitleniyor

Başlatan baran123, 19 Ocak 2016, 21:41:49

baran123

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;
}