Jag har inte testat det själv än, men med EasyPIC 2 följer det med två exempel i C där man använder DS1820, en för 16F877A och en för 18F452.
Koden med temp-avläsning är identisk mellan dem.
De här exemplena finns inte på MikroElektronikas hemsida, så du kanske inte har haft möjlighet att testa just den här koden.
Kod: Markera allt
//******************************************************************************
// microcontroller : P16F877A
//
// Project: onewire
// This project is designed to work with PIC 16F877A;
// with minor adjustments, it should work with any other PIC MCU
//
// The code demonstrates one-wire communication with temperature sensor DS1820
// connected to RA5 pin.
// After reset, PIC obtaines temperature from sensor and prints it on LCD.
//******************************************************************************
// Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
// 18S20: 9
// 18B20: 12 (default setting; can be 9,10,11,or 12)
const unsigned short TEMP_RESOLUTION = 12;
const int RES_FACTOR_1[4] = {5000, 2500, 1250, 625};
const unsigned int RES_FACTOR_2[4] = {0x0001, 0x0003, 0x0007, 0x000F};
const unsigned int RES_FACTOR_3[4] = {0x8000, 0xC000, 0xE000, 0xF000};
unsigned temp;
unsigned short j, RES_SHIFT;
void Display_Temperature(unsigned int temp) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
unsigned int temp_whole, temp_fraction;
unsigned short i;
char text[8];
// Isolate the fraction and make it a 4-digit decimal integer (for display)
temp_fraction = temp & RES_FACTOR_2[RES_SHIFT - 1];
temp_fraction = temp_fraction * RES_FACTOR_1[RES_SHIFT - 1];
//portc = temp_fraction;
// Handle the whole part of temperature value
temp_whole = temp;
// Is temperature negative?
if ((temp_whole & 0x8000) != 0u) i = 1; // Yes, i = 1
else i = 0; // No, i = 0
portc = i;
// Remove the fractional part
temp_whole >>= RES_SHIFT;
// Correct the sign if necessary
if (i) temp_whole |= RES_FACTOR_3[RES_SHIFT - 1];
//portd = temp_whole;
IntToStr(temp_whole, text); // Convert whole part to string
LCD_Out(2, 6, text); // Print whole part on LCD
LCD_Chr_CP('.'); // Print dot to separate fractional part
IntToStr(temp_fraction, text); // Convert fractional part to string
// Add leading zeroes (we display 4 digits fractional part)
if (temp_fraction < 1000u) LCD_Chr_CP('0');
if (temp_fraction < 100u) LCD_Chr_CP('0');
if (temp_fraction < 10u) LCD_Chr_CP('0');
LCD_Out_CP(text); // Print fractional part on LCD
LCD_Chr_CP(223); // Print degree character
LCD_Chr_CP('C'); // Print 'C' for Centigrades
}//~
void main() {
ADCON1 = 0xFF; // Configure RA5 pin as digital I/O
PORTE = 0xFF;
TRISE = 0x0F; // PORTE is input
PORTB = 0;
TRISB = 0; // PORTB is output
TRISD = 0 ;
TRISC = 0 ;
// Initialize LCD on PORTB and prepare for output
LCD_Init(&PORTB);
LCD_Cmd(LCD_CURSOR_OFF);
LCD_Out(1, 1, " Temperature: ");
do { // main loop
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);
j = OW_Read(&PORTE,2); // Get temperature LSB
temp = OW_Read(&PORTE,2); // Get temperature MSB
//portc = temp;
//portd = j;
temp <<= 8; temp += j; // Form the result
Display_Temperature(temp); // Format and display result on LCD
Delay_ms(500);
} while (1);
}//~!