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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
| #include "float2ascii.h"
#include "LCD_control.h"
#define POWERSUPPLY porta.f3
#define firstSensor 0x18
#define secondSensor 0x19
#define thirdSensor 0x1A
#define fourthSensor 0x1C
char Tempreadingchar[30];
char Tempreadingchar2[30];
unsigned int TimerRounds = 0;
// I2C functions
void i2c_init(void);
void i2c_start(void);
void i2c_repStart(void);
void i2c_stop(void);
unsigned char i2c_write( unsigned char i2cWriteData );
unsigned char i2c_read( unsigned char ack );
void Turnoffdisplay(){
POWERSUPPLY = 1; // Turn off display and I2C supply
porta.f0 = 0; // Turn off all display outputs
porta.f1 = 0; // before sleep
portb.f2 = 0;
portb.f3 = 0;
portb.f5 = 0;
portb.f6 = 0;
delay_ms(10);
}
void Interrupt(){
if (TMR0IF_bit){
TMR0IF_bit = 0;
TMR0 = 0;
if (TimerRounds > 950 ) { // 60 seconds to sleep
TimerRounds = 0;
Turnoffdisplay();
asm sleep;
} else TimerRounds ++;
}
}
/********************************************************************
* Function Name: i2c_init
* Return Value: void
* Parameters: Enable SSP
* Description: This function sets up the SSP1 module on a
* PIC18CXXX device for use with a Microchip I2C
********************************************************************/
void i2c_init(void) {
TRISB4_bit = 1; // Digital Output SCL
TRISB1_bit = 1; // Digital Output (make it input only when reading data) SDA
SSP1CON1 = 0x28; // enable I2C Master mode
SSP1CON2 = 0x00; // clear control bits
SSP1STAT = 0x80; // disable slew rate control; disable SMBus
SSP1ADD = 9; // set baud rate to 100 kHz (Fosc = 4 MHz)
PIR1.SSP1IF = 0;
PIR2.BCL1IF = 0;
SSP1CON2.SEN = 0;
}
/********************************************************************
* Function Name: i2c_start
* Return Value: void
* Parameters: void
* Description: Send I2C Start Command
********************************************************************/
void i2c_start(void) {
PIR1.SSP1IF = 0; //clear flag
while (SSP1STAT.BF); // wait for idle condition
SSP1CON2.SEN = 1; // initiate START condition
while (!PIR1.SSP1IF); // wait for a flag to be set
PIR1.SSP1IF = 0; // clear flag
}
/********************************************************************
* Function Name: i2c_repStart
* Return Value: void
* Parameters: void
* Description: Resend I2C Start Command
*
********************************************************************/
void i2c_repStart(void) {
PIR1.SSP1IF = 0; //clear flag
while (SSP1STAT.BF); // wait for idle condition
SSP1CON2.RSEN = 1; // initiate START condition
while (!PIR1.SSP1IF); // wait for a flag to be set
PIR1.SSP1IF = 0; // clear flag
}
/********************************************************************
* Function Name: i2c_stop
* Return Value: void
* Parameters: void
* Description: Send I2C Stop command
*
********************************************************************/
void i2c_stop(void) {
PIR1.SSP1IF = 0; //clear flag
while (SSP1STAT.BF); // wait for idle condition
SSP1CON2.PEN = 1; // initiate START condition
while (!PIR1.SSP1IF); // wait for a flag to be set
PIR1.SSP1IF = 0; // clear flag
}
/********************************************************************
* Function Name: i2c_write
* Return Value: Status byte for WCOL detection.
* Parameters: Single data byte for I2C2 bus.
* Description: This routine writes a single byte to the
* I2C2 bus.
********************************************************************/
unsigned char i2c_write( unsigned char i2cWriteData ) {
PIR1.SSP1IF = 0; //clear flag
while (SSP1STAT.BF); // wait for idle condition
SSP1BUF = i2cWriteData; // Load SSPBUF with i2cWriteData (the value to be transmitted
while (!PIR1.SSP1IF); // wait for a flag to be set
PIR1.SSP1IF = 0; // clear flag
return ( !ssp1con2.ACKSTAT ); // function returns '1' if transmission is acknowledged
}
/********************************************************************
* Function Name: i2c_read
* Return Value: contents of SSP2BUF register
* Parameters: ack = 1 and nak = 0
* Description: Read a byte from I2C bus and ACK/NAK device
********************************************************************/
unsigned char i2c_read( unsigned char ack ) {
unsigned char i2cReadData;
PIR1.SSP1IF = 0; //clear flag
while (SSP1STAT.BF); // wait for idle condition
SSP1CON2.RCEN = 1; // enable receive mode
while (!PIR1.SSP1IF); // wait for a flag to be set
PIR1.SSP1IF = 0; // clear flag
i2cReadData = SSP1BUF; // Read SSPBUF and put it in i2cReadData
if ( ack ) { // if ack=1
SSP1CON2.ACKDT = 0; // then transmit an Acknowledge
} else {
SSP1CON2.ACKDT = 1;
}
SSP1CON2.ACKEN = 1; // send acknowledge sequence
while (!PIR1.SSP1IF) ; // wait for a flag to be set
PIR1.SSP1IF = 0;// clear flag
return( i2cReadData ); // return the value read from SSPBUF
}
// End I2C functions
double DoTheReading(unsigned short Address)
{
unsigned short UpperByte;
unsigned short LowerByte;
double Temperature;
i2c_init();
i2c_start(); // send START command
i2c_write ((Address<<1) & 0xFE); //WRITE Command
i2c_write(0x05); // Write TA Register Address
i2c_repStart(); //Repeat START
i2c_write ((Address<<1) | 0x01); // READ Command
UpperByte = i2c_read(1); // READ 8 bits
//and Send ACK bit
LowerByte = i2c_read(0); // READ 8 bits
//and Send NAK bit
i2c_stop(); // send STOP command
//Convert the temperature data
//First Check flag bits
UpperByte = UpperByte & 0x1F; //Clear flag bits
if ((UpperByte & 0x10) == 0x10){ //TA < 0°C
UpperByte = UpperByte & 0x0F; //Clear SIGN
Temperature = 256 - ((double)UpperByte * 16 + (double)LowerByte / 16);
Temperature *= -1; // Make the value negative
}else
{ //TA ³ 0°C
Temperature = ( (double)UpperByte * 16 + (double)LowerByte / 16); //Temperature = Ambient Temperature (°C)
}
return Temperature;
}
void main() {
float Temperature;
DACCON0.b7 = 0; // DAC disabled
SRCON0.b7 = 0; // SR latch disabled
CM1CON0.b7 = 0; // Disable comparator 1
CM2CON0.b7 = 0; // Disable comparator 2
TRISA = 0b00110100; //Set RA2,4 & 5 as input, others are output 0 = output 1 = input
TRISB = 0b10000001; // Set all RB as output except RB7 & RB0
ANSELA = 0b00000000; // Set RA1 & RA2 as analog 0 = Digital 1 = analog
ANSELB = 0b00000000; // Set all B ports as digital
INTCON = 0b10100000; // Global, peripheral and timer0 interrupts enabled
OPTION_REG = 0b10000111;
TMR0 = 0;
Turnoffdisplay();
POWERSUPPLY = 0; // ground PNP transistor base / turn it on
delay_ms(10);
Lcd_Init(); // Initialize Lcd
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
while (1)
{
// Read first sensor
Temperature = DoTheReading(firstSensor);
Float2Ascii(Temperature, Tempreadingchar, 1); // Put float value to char and 2 decimal
Lcd_Out(1,1,Tempreadingchar);
Lcd_chr_cp(223);
Lcd_Out_Cp("C ");
// End first sensor
delay_ms(10);
// Read second sensor
Temperature = DoTheReading(secondSensor);
Float2Ascii(Temperature, Tempreadingchar, 1); // Put float value to char and 2 decimal
Lcd_Out(1,10,Tempreadingchar);
Lcd_chr_cp(223);
Lcd_Out_Cp("C ");
// End second sensor
delay_ms(10);
// Read third sensor
Temperature = DoTheReading(thirdSensor);
Float2Ascii(Temperature, Tempreadingchar, 1); // Put float value to char and 2 decimal
Lcd_Out(2,1,Tempreadingchar);
Lcd_chr_cp(223);
Lcd_Out_Cp("C ");
// End third sensor
delay_ms(10);
// Read fourth sensor
Temperature = DoTheReading(fourthSensor);
Float2Ascii(Temperature, Tempreadingchar, 1); // Put float value to char and 2 decimal
Lcd_Out(2,10,Tempreadingchar);
Lcd_chr_cp(223);
Lcd_Out_Cp("C ");
// End fourth sensor
Delay_ms(500);
}
} |