I am using the EasyPIC6 dev board & MikroC to program a 16F887 to scan the DS18S20 temp. sensor and display it on a 4X16 LCD. I then modified the code to drive the LCD from PORTD on a 18F4685 MCU and it compiled and ran OK on the EasyPIC6 board. I then put the 18F4685 into a prototype board I built and the LCD displays the temperaure and 000.0000 text OK, but the temp. from the DS18S20 never comes up on the display. The RE2 PORTE pin is used to scan and control the sensor and I have tried other PORT pins with no luck. I feel the PORT latch function may be where I am coding it wrong. I have checked & double checked my prototype board wiring & it all looks OK. At wits end on this one. Thanks HD
Rich (BB code):
/*
* Project name: Modified from 18F8520 to 18F4685
OneWire (Interfacing the DS1820 temperature sensor - all versions)
* Copyright:
(c) mikroElektronika, 2008.
* Revision History:
20081218:
- initial release;
* Description:
This code demonstrates one-wire communication with temperature sensor
DS18x20 connected to RE5 pin.
MCU reads temperature from the sensor and prints it on the LCD.
The display format of the temperature is 'xxx.xxxx°C'. To obtain correct
results, the 18x20's temperature resolution has to be adjusted (constant
TEMP_RESOLUTION).
* Test configuration:
MCU: P18F4685
http://ww1.microchip.com/downloads/en/DeviceDoc/39609b.pdf
Dev.Board: EasyPIC6
http://www.mikroe.com/en/tools/bigpic6/
Oscillator: HS, 8.0 MHz
Ext. Modules: DS18S20, LCD_2x16
SW: mikroC PRO for PIC
http://www.mikroe.com/en/compilers/mikroc/pro/pic/
* NOTES:
- //Turn on DS1820 switch SW12.8
-// Pull up(jumper J5) and turning off diode (switch SW10) on pin RE5
// ( board specific) used for one wire bus may be required.
*/
// ******************** Code for using PORTB for LCD ************************
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// LCD module connections
//sbit LCD_RS at LATD2_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_EN at LATD3_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_D4 at LATD4_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_D5 at LATD5_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_D6 at LATD6_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_D7 at LATD7_bit; // for writing to output pin always use latch (PIC18)
//sbit LCD_RS_Direction at TRISD2_bit;
//sbit LCD_EN_Direction at TRISD3_bit;
//sbit LCD_D4_Direction at TRISD4_bit;
//sbit LCD_D5_Direction at TRISD5_bit;
//sbit LCD_D6_Direction at TRISD6_bit;
//sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12
const unsigned short TEMP_RESOLUTION = 9;
char *text = "000.0000";
unsigned temp;
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}
// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;
else
text[0] = '0';
text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
// extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// convert temp_fraction to characters
text[4] = temp_fraction/1000 + 48; // Extract thousands digit
text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
text[7] = temp_fraction%10 + 48; // Extract ones digit
// print temperature on LCD
Lcd_Out(2, 5, text);
}
void main() {
ADCON1 |= 0x0F; // Configure AN pins as digital
CMCON |= 7; // Disable comparators
TRISD =0;
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,178); // different LCD displays have different char code for deg.
// if you see greek alpha letter try typing 178 instead of 223
Lcd_Chr(2,14,'C');
//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTE, 2); // Onewire reset signal
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0x44); // Issue command CONVERT_T
Delay_us(120);
Ow_Reset(&PORTE, 2);
Ow_Write(&PORTE, 2, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE, 2, 0xBE); // Issue command READ_SCRATCHPAD
Delay_ms(400);
temp = Ow_Read(&PORTE, 2);
temp = (Ow_Read(&PORTE, 2) << 8) + temp ;
PORTD = 1;
//--- Format and display result on Lcd
Display_Temperature(temp);
Delay_ms(3000);
PORTD = 0;
} while (1);
}
Last edited by a moderator: