Picproje Elektronik Sitesi

DERLEYİCİLER => Microchip XC Serisi => Microchip XC8 => Konuyu başlatan: baran123 - 19 Ocak 2016, 21:41:49

Başlık: HTU21D I2C kitleniyor
Gönderen: baran123 - 19 Ocak 2016, 21:41:49
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;
}