Skip to content

Instantly share code, notes, and snippets.

@Electronza
Created April 28, 2020 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Electronza/332ad183e9f3c189095b415d70e4f970 to your computer and use it in GitHub Desktop.
Save Electronza/332ad183e9f3c189095b415d70e4f970 to your computer and use it in GitHub Desktop.
MPLAB Xpress: XC8 code for SHT1x click board
// get/set SDA_pin aliases
#define SDA_pin_TRIS TRISC3
#define SDA_pin_LAT LATC3
#define SDA_pin_PORT RC3
#define SDA_pin_WPU WPUC3
#define SDA_pin_ANS ANSC3
#define SDA_pin_SetHigh() do { LATC3 = 1; } while(0)
#define SDA_pin_SetLow() do { LATC3 = 0; } while(0)
#define SDA_pin_Toggle() do { LATC3 = ~LATC3; } while(0)
#define SDA_pin_GetValue() RC3
#define SDA_pin_SetDigitalInput() do { TRISC3 = 1; } while(0)
#define SDA_pin_SetDigitalOutput() do { TRISC3 = 0; } while(0)
#define SDA_pin_SetPullup() do { WPUC3 = 1; } while(0)
#define SDA_pin_ResetPullup() do { WPUC3 = 0; } while(0)
#define SDA_pin_SetAnalogMode() do { ANSC3 = 1; } while(0)
#define SDA_pin_SetDigitalMode() do { ANSC3 = 0; } while(0)
// get/set SCL_pin aliases
#define SCL_pin_TRIS TRISC4
#define SCL_pin_LAT LATC4
#define SCL_pin_PORT RC4
#define SCL_pin_WPU WPUC4
#define SCL_pin_ANS ANSC4
#define SCL_pin_SetHigh() do { LATC4 = 1; } while(0)
#define SCL_pin_SetLow() do { LATC4 = 0; } while(0)
#define SCL_pin_Toggle() do { LATC4 = ~LATC4; } while(0)
#define SCL_pin_GetValue() RC4
#define SCL_pin_SetDigitalInput() do { TRISC4 = 1; } while(0)
#define SCL_pin_SetDigitalOutput() do { TRISC4 = 0; } while(0)
#define SCL_pin_SetPullup() do { WPUC4 = 1; } while(0)
#define SCL_pin_ResetPullup() do { WPUC4 = 0; } while(0)
#define SCL_pin_SetAnalogMode() do { ANSC4 = 1; } while(0)
#define SCL_pin_SetDigitalMode() do { ANSC4 = 0; } while(0)
To comunicate with the SHT1x sensor one must change SDA_pin as an output to send data to the sensor, and to change it as an input to receive data. This is done by the SDA_pin_SetDigitalInput() and SDA_pin_SetDigitalOutput() functions.
Setting SDA_pin to a value of logical “1” is done by SDA_pin_SetHigh(), while setting SDA_pin to a value of logical “0” is done by SDA_pin_SetLow(). Similarly, SCL_pin_SetHigh() and SCL_pin_SetLow() are used to generate the clock signal for SHT1x communication.
Reading the state of the SDA_pin is done by the SDA_pin_GetValue() function.
With the above considerations, here’s the listing of main.c code:
/**
Generated Main Source File
Company:
Microchip Technology Inc.
File Name:
main.c
Summary:
This is the main file generated using MPLAB(c) Code Configurator
Description:
This header file provides implementations for driver APIs for all modules selected in the GUI.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - v3.00
Device : PIC16F18855
Driver Version : 2.00
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.20
*/
/*
Copyright (c) 2013 - 2015 released Microchip Technology Inc. All rights reserved.
Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).
You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.
SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*/
#include "mcc_generated_files/mcc.h"
// Global variables
float temperature;
float rel_humidity;
// Module constants, see SHT1x datasheet for more information ------------------------------------
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
const float T2=+0.00008; // for 14 Bit
// SHT1x definitions
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define SHT_RESET 0x1e //000 1111 0
//- Module variables -------------------------------------------------------------------------------
unsigned char ucSens_Error;
int iSHT_Temp;
int iSHT_Humi;
/**************************************************************************************************
* SHT11 Functions
**************************************************************************************************/
/**************************************************************************************************
* Generates a transmission start
* _____ ________
* DATA: |_______|
* ___ ___
* SCK : ___| |___| |______
**************************************************************************************************/
void s_transstart()
{
//Initial state
//release DATA-line
SDA_pin_SetDigitalInput();
SDA_pin_SetHigh();
SCL_pin_SetLow(); // SCL Low
__delay_us(1);
SCL_pin_SetHigh();
__delay_us(1);
SDA_pin_SetDigitalOutput(); // define SDA as output
SDA_pin_SetLow(); // SDA low
__delay_us(1);
SCL_pin_SetLow();
__delay_us(3);
SCL_pin_SetHigh();
__delay_us(1);
SDA_pin_SetDigitalInput();
__delay_us(1);
SCL_pin_SetLow();
}
/**************************************************************************************************
* Reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
**************************************************************************************************/
unsigned char s_read_byte(unsigned char ack)
{
unsigned char i=0x80;
unsigned char val=0;
//Initial state
SDA_pin_SetDigitalInput(); //release DATA-line
SDA_pin_SetHigh();
SCL_pin_SetLow(); // SCL Low
while(i) //shift bit for masking
{
SCL_pin_SetHigh(); //clk for SENSI-BUS
__delay_us(1);
if (SDA_pin_GetValue() == 1)
{
val=(val | i); //read bit
}
SCL_pin_SetLow();
__delay_us(1);
i=(i>>1);
}
SDA_pin_SetDigitalOutput();
if (ack)
{
//in case of "ack==1" pull down DATA-Line
SDA_pin_SetLow();
}
else
{
SDA_pin_SetHigh();
}
SCL_pin_SetHigh(); //clk #9 for ack
__delay_us(3);
SCL_pin_SetLow();
__delay_us(1);
SDA_pin_SetDigitalInput(); //release DATA-line
SDA_pin_SetHigh();
return (val);
}
/**************************************************************************************************
* Writes a byte on the Sensibus and checks the acknowledge.
**************************************************************************************************/
unsigned char s_write_byte(unsigned char value)
{
unsigned char i=0x80;
unsigned char error=0;
SDA_pin_SetDigitalOutput();
while(i)
{ //shift bit for masking
if (i & value)
{
SDA_pin_SetHigh(); //masking value with i , write to SENSI-BUS
}
else
{
SDA_pin_SetLow();
}
SCL_pin_SetHigh(); //clk for SENSI-BUS
__delay_us(3);
SCL_pin_SetLow();
__delay_us(3);
i=(i>>1);
}
SDA_pin_SetDigitalInput(); //release DATA-line
SDA_pin_SetHigh();
SCL_pin_SetHigh(); //clk #9 for ack
__delay_us(3);
if (SDA_pin_GetValue() == 1) error = 1; //check ack (DATA will be pulled down by SHT11)
__delay_us(1);
SCL_pin_SetLow();
return(error); //error=1 in case of no acknowledge
}
/**************************************************************************************************
* makes a measurement (humidity/temperature) with checksum
* p_value returns 2 bytes
* mode: 1=humidity 0=temperature
* return value: 0=ok, 1=write error, 2=timeout
**************************************************************************************************/
unsigned char s_measure(unsigned int *p_value, unsigned char mode)
{
unsigned char i=0;
unsigned char msb,lsb;
unsigned char checksum;
*p_value=0;
s_transstart(); //transmission start
if(mode)
{
mode = MEASURE_HUMI;
}
else
{
mode = MEASURE_TEMP;
}
if (s_write_byte(mode)) return(1);
// normal delays: temp i=70, humi i=20
SDA_pin_SetDigitalInput();;
while(i<240)
{
__delay_ms(1);
__delay_ms(1);
__delay_ms(1);
if (SDA_pin_GetValue() == 0)
{
i=0;
break;
}
i++;
}
// or timeout
if(i) return(2);
msb=s_read_byte(ACK); //read the first byte (MSB)
lsb=s_read_byte(ACK); //read the second byte (LSB)
checksum=s_read_byte(noACK); //read checksum (8-bit)
*p_value=(msb<<8)|(lsb);
return(0);
}
/**************************************************************************************************
* calculates temperature [C]
* input : temp [Ticks] (14 bit)
* output: temp [C] times 10 (e.g 253 = 25.3'C)
**************************************************************************************************/
float calc_sth11_temp(unsigned int t)
{
float t_out;
t_out = t*0.01 - 40;
return t_out;
}
/**************************************************************************************************
* calculates humidity [%RH] with temperature compensation
* input : humi [Ticks] (12 bit), temperature in 'C * 100 (e.g 253 for 25.3'C)
* output: humi [%RH] (=integer value from 0 to 100)
**************************************************************************************************/
float calc_sth11_humi(unsigned int h, int t)
{
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [°C]
t_C=t*0.01 - 40; //calc. temperature from ticks to [°C]
rh_lin=C3*h*h + C2*h + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*h)+rh_lin; //calc. temperature compensated humidity
// now calc. Temperature compensated humidity [%RH]
// the correct formula is:
// rh_true=(t/10-25)*(0.01+0.00008*(sensor_val))+rh;
// sensor_val ~= rh*30
// we use:
// rh_true=(t/10-25) * 1/8;
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
return rh_true;
}
/**************************************************************************************************
* reads temperature and humidity
**************************************************************************************************/
void Read_SHT11(float *fT, float *fRH)
{
unsigned int t;
unsigned int h;
float value;
ucSens_Error = 0;
ucSens_Error = s_measure(&t, 0);
iSHT_Temp = (int)(calc_sth11_temp(t) * 10);
ucSens_Error = s_measure(&h, 1);
iSHT_Humi = (int)(calc_sth11_humi(h, t) * 10);
value = (float)iSHT_Temp;
*fT = value / 10;
value = (float)iSHT_Humi;
*fRH = value / 10;
}
/**************************************************************************************************
* reads the status register with checksum (8-bit)
**************************************************************************************************/
char s_read_statusreg(unsigned char *p_value)
{
unsigned char checksum = 0;
s_transstart(); //transmission start
if(s_write_byte(STATUS_REG_R)) return 1; //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
checksum=s_read_byte(noACK); //read checksum (8-bit)
return 0;
}
/**************************************************************************************************
* writes the status register with checksum (8-bit)
* input: status register value
* return value: 0=ok, 1=write error
**************************************************************************************************/
char s_write_statusreg(unsigned char value)
{
s_transstart(); //transmission start
if(s_write_byte(STATUS_REG_W)) return 1; //send command to sensor
if(s_write_byte(value)) return 1; //send value of status register
return 0;
}
/**************************************************************************************************
* communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
* _____________________________________________________ ________
* DATA: |_______|
* _ _ _ _ _ _ _ _ _ ___ ___
* SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
**************************************************************************************************/
void s_connectionreset()
{
unsigned char i;
//Initial state
SDA_pin_GetValue(); //release DATA-line
SDA_pin_SetHigh();
SCL_pin_SetLow(); // SCL Low
for(i=0; i<9; i++) //9 SCK cycles
{
SCL_pin_SetHigh();
__delay_us(3);
SCL_pin_SetLow();
__delay_us(3);
}
s_transstart(); //transmission start
}
/**************************************************************************************************
* Resets the sensor by a softreset
**************************************************************************************************/
unsigned char s_softreset(void)
{
s_connectionreset(); //reset communication
//send RESET-command to sensor
return (s_write_byte(SHT_RESET)); //return=1 in case of no response form the sensor
}
/**************************************************************************************************
* End of File
**************************************************************************************************/
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
printf("XC8 SHT1x Click Demo \r\n");
__delay_ms(5000);
while (1)
{
// Add your application code
Read_SHT11(&temperature, &rel_humidity);
printf("Temperature %7.4f deg C\r\n",temperature);
printf("Humidity %7.4f pct RH\r\n",rel_humidity);
__delay_ms(1000);
}
}
/**
End of File
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment