⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1820_1.c

📁 18b20的pic单片机驱动原代码,工作稳定.
💻 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 + -