📄 1820_1.c
字号:
// 1820_1.C, CCS - PCM (PIC16F84)
//
// Illustrates an implementation of Dallas 1-wire interface.
//
// Configuration. DS1820 on RB.0, RB.1, RB.2 and RB.3. Note a 4.7K
// pullup to +5V is required. DS1820s configured in parasite power mode.
// That is, VCC connected to ground.
//
// Reads and displays nine bytes from each device in turn and displays
// the result on serial LCD connected to RA.0.
//
// Bug. Temperature (first two bytes) is zero on RB.1, RB.2 and RB.3
//
// copyright, Peter H. Anderson, Baltimore, MD, April, '99
#include <16f84.h>
#include <string.h>
#include <defs_f84.h>
#define MAX_SENSORS 4
// 1-wire prototypes
void _1w_init(int sensor);
int _1w_in_byte(int sensor);
void _1w_out_byte(int d, int sensor);
void _1w_pin_hi(int sensor);
void _1w_pin_low(int sensor);
void _1w_strong_pull_up(int sensor); // not used in this routine
// delay routines
void delay_ms(long t);
void delay_10us(int t);
// LCD routines
void lcd_init(void);
void out_RAM_str(int *s);
void lcd_hex_byte(int val);
void lcd_dec_byte(int val, int digits);
int num_to_char(int val);
void lcd_char(int ch);
void lcd_new_line(void);
#define TxData 0 // output to serial LCD
void main(void)
{
int buff[9], sensor, n;
for (sensor=0; sensor<MAX_SENSORS; sensor++)
{
_1w_init(sensor);
_1w_out_byte(0xcc, sensor); // skip ROM
_1w_out_byte(0x44, sensor); // perform temperature conversion
_1w_strong_pull_up(sensor);
_1w_init(sensor);
_1w_out_byte(0xcc, sensor); // skip ROM
_1w_out_byte(0xbe, sensor); // read the result
for (n=0; n<9; n++)
{
buff[n]=_1w_in_byte(sensor);
}
lcd_init();
lcd_hex_byte(sensor); // display the sensor number
lcd_new_line();
for (n=0; n<4; n++) // display 4 bytes
{
lcd_hex_byte(buff[n]);
lcd_char(' ');
}
lcd_new_line();
for (n=4; n<9; n++) // displays the other 5 bytes
{
lcd_hex_byte(buff[n]);
lcd_char(' ');
}
lcd_new_line();
delay_ms(1000);
}
}
// The following are standard 1-Wire routines.
void _1w_init(int sensor)
{
_1w_pin_hi(sensor);
_1w_pin_low(sensor);
delay_10us(50);
_1w_pin_hi(sensor);
delay_10us(50);
}
int _1w_in_byte(int sensor)
{
int n, i_byte, temp, mask;
mask = 0xff & (~(0x01<<sensor));
for (n=0; n<8; n++)
{
PORTB=0x00;
TRISB=mask;
TRISB=0xff;
#asm
CLRWDT
NOP
NOP
#endasm
temp=PORTB;
if (temp & ~mask)
{
i_byte=(i_byte>>1) | 0x80; // least sig bit first
}
else
{
i_byte=i_byte >> 1;
}
delay_10us(6);
}
return(i_byte);
}
void _1w_out_byte(int d, int sensor)
{
int n, mask;
mask = 0xff & (~(0x01<<sensor));
for(n=0; n<8; n++)
{
if (d&0x01)
{
PORTB=0;
TRISB=mask; // momentary low
TRISB=0xff;
delay_10us(6);
}
else
{
PORTB=0;
TRISB=mask;
delay_10us(6);
TRISB=0xff;
}
d=d>>1;
}
}
void _1w_pin_hi(int sensor)
{
TRISB = 0xff;
}
void _1w_pin_low(int sensor)
{
PORTB = 0x00;
TRISB = 0xff & (~(0x01 << sensor));
}
void _1w_strong_pull_up(int sensor) // bring DQ to strong +5VDC
{
PORTB = 0x01 << sensor;
TRISB = 0xff & (~(0x01 << sensor));
delay_ms(250);
TRISB = 0xff;
}
// delay routines
void delay_10us(int t)
{
#asm
BCF STATUS, RP0
DELAY_10US_1:
CLRWDT
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ t, F
GOTO DELAY_10US_1
#endasm
}
void delay_ms(long t) // delays t millisecs
{
do
{
delay_10us(100);
} while(--t);
}
// LCD routines
int num_to_char(int val) // converts val to hex character
{
int ch;
if (val < 10)
{
ch=val+'0';
}
else
{
val=val-10;
ch=val + 'A';
}
return(ch);
}
void lcd_char(int ch) // serial output to PIC-n-LCD, 9600 baud
{
int n, dly;
// start bit + 8 data bits
#asm
BCF STATUS, RP0
MOVLW 9
MOVWF n
BCF STATUS, C
LCD_CHAR_1:
BTFSS STATUS, C
BSF PORTA, TxData
BTFSC STATUS, C
BCF PORTA, TxData
MOVLW 32
MOVWF dly
LCD_CHAR_2:
DECFSZ dly, F
GOTO LCD_CHAR_2
RRF ch, F
DECFSZ n, F
GOTO LCD_CHAR_1
BCF PORTA, TxData
CLRWDT
MOVLW 96
MOVWF dly
LCD_CHAR_3:
DECFSZ dly, F
GOTO LCD_CHAR_3
CLRWDT
#endasm
}
void lcd_init(void) // sets TxData in idle state and resets PIC-n-LCD
{
#asm
BCF STATUS, RP0
BCF PORTA, TxData
BSF STATUS, RP0
BCF TRISA, TxData
BCF STATUS, RP0
#endasm
lcd_char(0x0c);
delay_ms(250);
}
void lcd_new_line(void) // outputs 0x0d, 0x0a
{
lcd_char(0x0d);
delay_ms(10); // give the PIC-n-LCD time to perform the
lcd_char(0x0a); // new line function
delay_ms(10);
}
void out_RAM_str(int s)
{
while(*s)
{
lcd_char(*s);
++s;
}
}
void lcd_hex_byte(int val) // displays val in hex format
{
int ch;
ch = num_to_char((val>>4) & 0x0f);
lcd_char(ch);
ch = num_to_char(val&0x0f);
lcd_char(ch);
}
void lcd_dec_byte(int val, int digits)
// displays byte in decimal as either 1, 2 or 3 digits
{
int d;
int ch;
if (digits == 3)
{
d=val/100;
ch=num_to_char(d);
lcd_char(ch);
}
if (digits >1) // take the two lowest digits
{
val=val%100;
d=val/10;
ch=num_to_char(d);
lcd_char(ch);
}
if (digits == 1) // take the least significant digit
{
val = val%100;
}
d=val % 10;
ch=num_to_char(d);
lcd_char(ch);
}
--------------------------------------------------------------------------------
// Program 1820_2.C
//
// Reads 64-bit address from DS1820, saves to the 16F84's EEPROM
// and displays it on serial LCD.
//
// Uses 64-bit address to perform temperature measurement. Data is
// is displayed on serial LCD
//
//
// 16F84 DS1820
// PortB.0 (term 6) ------------------------------ DQ (term 2)
//
// PORTA, Bit 0 (terminal 17) ------ TX ----------> to RX on Serial LCD
//
//
// copyright, Peter H. Anderson, Baltimore, MD, Apr, 99
#case
#include <16f84.h>
#include <string.h>
#include <defs_f84.h>
void display_lcd(int *d, int num_vals);
void get_16f84_eeprom(int adr, int *d, int num_vals);
void put_16f84_eeprom(int adr, int *d, int num_vals);
void write_16f84_eeprom(int adr, int d);
int read_16f84_eeprom(int adr);
void ds1820_read_rom(int *d, int sensor);
void make_temperature_meas(int *adr, int *d, int sensor);
// 1-wire prototypes
void _1w_init(int sensor);
int _1w_in_byte(int sensor);
void _1w_out_byte(int d, int sensor);
void _1w_pin_hi(int sensor);
void _1w_pin_low(int sensor);
void _1w_strong_pull_up(int sensor); // not used in this routine
// delay routines
void delay_ms(long t);
void delay_10us(int t);
// LCD routines
void lcd_init(void);
void out_RAM_str(int *s);
void lcd_hex_byte(int val);
void lcd_dec_byte(int val, int digits);
int num_to_char(int val);
void lcd_char(int ch);
void lcd_new_line(void);
#define TxData 0
void main(void)
{
int dev_adr[8], t_dat[9]; // temporary storage
lcd_init();
ds1820_read_rom(dev_adr, 0); // read serial number from DS1820
display_lcd(dev_adr, 8); // display the result on LCD
put_16f84_eeprom(0x00, dev_adr, 8);
// save to eeprom, beginning at adr 0x00, 8 bytes
// now fetch the serial number, address and perform a temperature
// measurment
get_16f84_eeprom(0x00, dev_adr, 8);
// fetch from 16F84, 8 bytes and return in array d
make_temperature_meas(dev_adr, t_dat, 0);
display_lcd(t_dat, 9); // display the 9 byte result
#asm
DONE:
clrwdt
GOTO DONE
#endasm
}
void display_lcd(int *d, int num_vals)
{
int n;
for (n=0; n<num_vals; n++)
{
if ((n%4==0) && (n!=0))
{
lcd_new_line();
}
lcd_hex_byte(d[n]);
lcd_char(' ');
}
lcd_new_line();
}
void put_16f84_eeprom(int adr, int *d, int num_vals)
{
int n;
for(n=0; n<num_vals; n++, adr++)
{
write_16f84_eeprom(adr, d[n]);
}
}
void get_16f84_eeprom(int adr, int *d, int num_vals)
{
int n;
for(n=0; n<num_vals; n++, adr++)
{
d[n]=read_16f84_eeprom(adr);
}
}
void write_16f84_eeprom(int adr, int d)
{
EEADR = adr;
EEDATA = d;
wren = 1;
EECON2 = 0x55; // protection sequence
EECON2 = 0xaa;
wr = 1; // begin programming sequence
delay_ms(20);
wren = 0; // disable write enable
}
int read_16f84_eeprom(int adr)
{
EEADR=adr;
rd=1; // set the read bit
return(EEDATA);
}
void ds1820_read_rom(int *d, int sensor)
{
int n;
_1w_init(sensor);
_1w_out_byte(0x33, sensor);
for(n=0; n<8; n++)
{
d[n]=_1w_in_byte(sensor);
}
}
void make_temperature_meas(int *adr, int *d, int sensor)
{
int n;
_1w_init(sensor);
_1w_out_byte(0x55, sensor); // match ROM
for(n=0; n<8; n++) // followed by the 8-byte ROM address
{
_1w_out_byte(adr[n], sensor);
}
_1w_out_byte(0x44, sensor); // start temperature conversion
_1w_strong_pull_up(sensor);
_1w_init(sensor);
_1w_out_byte(0x55, sensor); // match ROM
for(n=0; n<8; n++) // followed by the 8-byte ROM address
{
_1w_out_byte(adr[n], sensor);
}
_1w_out_byte(0xbe, sensor);
for(n=0; n<9; n++)
{
d[n]=_1w_in_byte(sensor);
}
}
// 1-Wire, delay and LCD routines are the same as 1820_1.C
--------------------------------------------------------------------------------
// 1820_3.C
//
// Cyclic redudancy check (CRC).
//
// Makes measurement and displays the nine values on serial LCD.
// Then calculates CRC and displays.
//
// copyright, Peter H. Anderson, Baltimore, MD, Apr, '99
#case
#include <16f84.h>
#include <string.h>
#include <defs_f84.h>
int calc_crc(int *buff, int num_vals);
// 1-wire prototypes
void _1w_init(int sensor);
int _1w_in_byte(int sensor);
void _1w_out_byte(int d, int sensor);
void _1w_pin_hi(int sensor);
void _1w_pin_low(int sensor);
void _1w_strong_pull_up(int sensor);
// delay routines
void delay_ms(long t);
void delay_10us(int t);
// LCD routines
void lcd_init(void);
void out_RAM_str(int *s);
void lcd_hex_byte(int val);
void lcd_dec_byte(int val, int digits);
int num_to_char(int val);
void lcd_char(int ch);
void lcd_new_line(void);
#define TxData 0
void main(void)
{
int buff[9], sensor=0, crc, n;
_1w_init(sensor);
_1w_out_byte(0xcc, sensor); // skip ROM
_1w_out_byte(0x44, sensor); // perform temperature conversion
_1w_strong_pull_up(sensor);
_1w_init(sensor);
_1w_out_byte(0xcc, sensor); // skip ROM
_1w_out_byte(0xbe, sensor);
for (n=0; n<9; n++)
{
buff[n]=_1w_in_byte(sensor);
}
lcd_init();
for (n=0; n<4; n++)
{
lcd_hex_byte(buff[n]);
lcd_char(' ');
}
lcd_new_line();
for (n=4; n<9; n++)
{
lcd_hex_byte(buff[n]);
lcd_char(' ');
}
lcd_new_line();
crc = calc_crc(buff, 9);
lcd_hex_byte(crc);
lcd_new_line();
delay_ms(500);
}
int calc_crc(int *buff, int num_vals)
{
int shift_reg=0, data_bit, sr_lsb, fb_bit, i, j;
for (i=0; i<num_vals; i++) // for each byte
{
for(j=0; j<8; j++) // for each bit
{
data_bit = (buff[i]>>j)&0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
{
shift_reg = shift_reg ^ 0x8c;
}
}
}
return(shift_reg);
}
// 1_Wire, delay and LCD routines are the same as in 1820_1.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -