Created
April 28, 2020 09:03
-
-
Save Electronza/332ad183e9f3c189095b415d70e4f970 to your computer and use it in GitHub Desktop.
MPLAB Xpress: XC8 code for SHT1x click board
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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