This repository has been archived by the owner on Jan 8, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SHT1x.c
239 lines (218 loc) · 8.24 KB
/
SHT1x.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
***********************************************************************************************
* SHT1x digital temperature and humidity sensor Driver
* All Rights Reserved
* File name : SHT1x.c
* Programmer : John Leung, TechToys Co. Hong Kong
* Web presence : www.TechToys.com.hk
* Downloaded from www.microchipc.com - see site for more sample PIC C code
* Note :
* Language : C18 complier version 2.40, MPLAB v7.41
* Hardware : PIC18LF4550-STK1
* Date : 11 Oct 2006 Version 1.0
***********************************************************************************************
* DESCRIPTION
*
* This module provides an interface to Sensirion SHT10 digital temperature & humidity sensor
*
* pinout function summarized as below
* ---SHT1x MCU -----------------
* DATA - data RA2
* SCK - clock RA0
***********************************************************************************************
*/
#include <p18cxxx.h>
#include "SHT1x.h"
#include "delay.h"
/*
*********************************************************************************************************
* LOCAL DEFINITIONS
*********************************************************************************************************
*/
//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 RESET 0x1e //000 1111 0
#define noACK 0
#define ACK 1
/*
*********************************************************************************************************
* SOFT RESET THE SENSOR
*
* Description : Soft reset, resets the interface, clears the status register to default values
* Wait minimum 11 ms before next command
* Arguments : none
*
* Returns : 1 if no response from the sensor
* Notes :
*********************************************************************************************************
*/
char s_softreset(void)
{
unsigned char error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response from the sensor
}
/*
*********************************************************************************************************
* MAKE MEASUREMENT ON HUMIDITY AND TEMPERATURE IN 12BITS ADN 14BITS
*
* Description : Makes a measurement (humidity/temperature) with checksum
* Arguments :
*
* Returns :
* Notes : It takes approximately 11/55/210 ms for a 8/12/14bit measurement.
* Measurement data is stored until readout.
* Two bytes of measurement data and one byte of CRC checksum will then be transmitted.
* The uC must acknowledge each byte by pulling the DATA line low.
*********************************************************************************************************
*/
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
{
unsigned error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
(mode==HUMI)?DelayMs(55):DelayMs(210);
for (i=0;i<65535;i++) if(DATA_RD==0) break; //wait until sensor has finished the measurement
if(DATA_RD) error+=1; //or timeout (~2 sec.) is reached
*(p_value+1) = s_read_byte(ACK); //read the first byte (MSB)
*(p_value) = s_read_byte(ACK); //read the second byte (LSB)
*p_checksum = s_read_byte(noACK); //read checksum
return error;
}
/*
*********************************************************************************************************
* TRANSMISSION START SEQUENCE
*
* Description : To initiate a transmission, a “Transmission Start?sequence has to be issued.
* Arguments : none
*
* Returns : none
* Notes :
* generates a transmission start
* _____ ________
* DATA: |_______|
* ___ ___
* SCK : ___| |___| |______
*********************************************************************************************************
*/
void s_transstart(void)
{
SCK=0; //Initial state
DATA_TRIS = 1; //pullup resistor brings DATA pin high
DelayUs(1);
SCK=1;
DelayUs(1);
DATA_WR=0; DATA_TRIS=0;
DelayUs(1);
SCK=0;
DelayUs(5);
SCK=1;
DelayUs(1);
DATA_TRIS=1; //pullup resistor brings DATA pin high
DelayUs(1);
SCK=0;
}
/*
*********************************************************************************************************
* CONNECTION RESET SEQUENCE
*
* Description : This sequence resets the interface only. The status register preserves its content.
* Arguments : none
*
* Returns : none
* Notes :
* communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
* _____________________________________________________ ________
* DATA: |_______|
* _ _ _ _ _ _ _ _ _ ___ ___
* SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
*********************************************************************************************************
*/
void s_connectionreset(void)
{
unsigned char i;
DATA_WR = 1; //set data pin high
DATA_TRIS = 0; //set data pin an output
SCK = 0;
SCK_TRIS = 0; //set CLK pin an output low
for(i=0;i<9;i++) //9 SCK cycles for connection reset sequence
{ SCK=1;
DelayUs(1);
SCK=0;
DelayUs(1);
}
s_transstart(); //transmission start
}
/*
*********************************************************************************************************
* LOW LEVEL READ FUNCTION
*
* Description : Read a byte form the Sensibus and gives an acknowledge in case of "ack == ACK"
* Arguments : 'ack' ACK (1) if acknowledge required
* noACK (0) in case acknowledge NOT required
*
* Returns : return the byte read from the sensor
* Notes :
*********************************************************************************************************
*/
char s_read_byte(unsigned char ack)
{
unsigned char i,val=0;
DATA_TRIS = 1; //set DATA line an input
SCK = 0;
for (i=0x80;i>0;i/=2) //shift bit for masking
{ SCK=1; //clk for SENSI-BUS
DelayUs(2);
if (DATA_RD) val=(val | i); //read bit
SCK=0;
DelayUs(2);
}
if(ack==ACK)
{
DATA_TRIS = 0;
DATA_WR = 0;
}
SCK=1; //clk #9 for ack
DelayUs(5); //pulse-width approx. 5 us
SCK=0;
DATA_TRIS = 1; //release DATA-line
return val;
}
/*
*********************************************************************************************************
* LOW LEVEL WRITE FUNCTION
*
* Description : Write a byte on the Sensibus and checks the acknowledge
* Arguments : 'value' is the byte to write to the sensor
*
* Returns : 1 in case of an error (no acknowledge) from the sensor
* Notes :
*********************************************************************************************************
*/
char s_write_byte(unsigned char value)
{
unsigned char i,error=0;
DATA_TRIS = 0;
for (i=0x80;i>0;i/=2) //shift bit for masking
{ if (i & value) DATA_WR=1; //masking value with i , write to SENSI-BUS
else DATA_WR=0;
SCK=1; //clk for SENSI-BUS
DelayUs(5); //pulse-width approx. 5 us
SCK=0;
DelayUs(5);
}
DATA_TRIS=1; //release DATA-line, let SHT10 sensor controls DATA line
SCK=1; //clk #9 for ack
error=DATA_RD; //check ack (DATA will be pulled down by SHT11)
SCK=0;
return error; //error=1 in case of no acknowledge
}