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

📄 1.c

📁 测试18b20的程序
💻 C
字号:
/*  m818b20.c   2004-11-19   
  本程序为采用mega8 和18b20的温度采集程序 
  选用mega8内部8M RC震荡,18b20 数据线接pd6,数据线和vcc间接一4.7k上拉电阻 
  感谢dfgeoff 嗜血蜗牛提供的资料*/ 

#include <iom16v.h> //和单片机类型相对应的头文件,选择Atmega8做实验; 
#include <macros.h> 
#define uchar unsigned char 
#define uint unsigned int 
void init_1820(); 
write_1820(uchar x); 
uchar read_1820(); 
void send_byte(uchar x); 
void delay(uint x); 
void disp_led(uchar buffer,uchar control); 
uchar  disp_table[16] = { 
   0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 
   0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 
uchar dp; 
long count; 
#define LCD_EN_PORT    PORTA   //以下2个要设为同一个口
#define LCD_EN_DDR     DDRA
#define LCD_RS_PORT    PORTA   //以下2个要设为同一个口
#define LCD_RS_DDR     DDRA
#define LCD_DATA_PORT  PORTA   //以下3个要设为同一个口
#define LCD_DATA_DDR   DDRA    //一定要用高4位
#define LCD_DATA_PIN   PINA
#define LCD_RS         (1<<0) //   port0      out
#define LCD_EN         (1<<1) //  port1       out
#define LCD_DATA       ((1<<4)|(1<<5)|(1<<6)|(1<<7)) //0xf0 
/*函数说明
------------------------------------------------------------------------------*/
void LCD_init(void);
void LCD_en_write(void);
void LCD_write_command(unsigned  char command) ;
void LCD_write_data(unsigned char data);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data);
void delay_nus(unsigned int n);
void delay_nms(unsigned int n);
/*----------------------------------------------------------------------------*/
void delay_1us(void)                 //1us延时函数
  {
   asm("nop");
  }

void delay_nus(unsigned int n)       //N us延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1us();
  }
  
void delay_1ms(void)                 //1ms延时函数
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
  
void delay_nms(unsigned int n)       //N ms延时函数
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }


/*----------------------------------------------------------------------------*/
void LCD_init(void)         //液晶初始化
{
  LCD_DATA_DDR|=LCD_DATA;   //数据口方向为输出
  LCD_EN_DDR|=LCD_EN;       //设置EN方向为输出
  LCD_RS_DDR|=LCD_RS;       //设置RS方向为输出
  LCD_write_command(0x28); 
  LCD_en_write();
  delay_nus(40);
  LCD_write_command(0x28);  //4位显示
  LCD_write_command(0x0c);  //显示开
  LCD_write_command(0x01);  //清屏
  delay_nms(2);
}

/*----------------------------------------------------------------------------*/
void LCD_en_write(void)  //液晶使能
{
  LCD_EN_PORT|=LCD_EN;
  delay_nus(1);
  LCD_EN_PORT&=~LCD_EN;
}

/*----------------------------------------------------------------------------*/
void LCD_write_command(unsigned char command) //写指令
{
  delay_nus(16);
  LCD_RS_PORT&=~LCD_RS;        //RS=0
  LCD_DATA_PORT&=0X0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写高四位
  LCD_en_write();
  command=command<<4;          //低四位移到高四位
  LCD_DATA_PORT&=0x0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写低四位
  LCD_en_write();
  
}
/*----------------------------------------------------------------------------*/
void LCD_write_data(unsigned char data) //写数据
{
  delay_nus(16);
  LCD_RS_PORT|=LCD_RS;       //RS=1
  LCD_DATA_PORT&=0X0f;       //清高四位
  LCD_DATA_PORT|=data&0xf0;  //写高四位
  LCD_en_write();
  data=data<<4;               //低四位移到高四位
  LCD_DATA_PORT&=0X0f;        //清高四位
  LCD_DATA_PORT|=data&0xf0;   //写低四位
  LCD_en_write();
}
/*----------------------------------------------------------------------------*/
void LCD_set_xy( unsigned char x, unsigned char y )  //写地址函数
{
    unsigned char address;
    if (y == 0) address = 0x80 + x;
    else   address = 0xc0 + x;
    LCD_write_command( address);
}
/*----------------------------------------------------------------------------*/
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
{
    LCD_set_xy( X, Y ); //写地址    
    while (*s)  // 写显示字符
    {
      LCD_write_data( *s );
      s ++;
    }
      
}

/*----------------------------------------------------------------------------*/
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
{
  LCD_set_xy( X, Y ); //写地址
  LCD_write_data( data);
  
}







/////////////////////////////////////////
void delay(uint x)  //1.5us左右 
{ 
     while(x) 
    { 
       x--; 
    } 
} 
 
//////////////////////////////////////////
void init_1820() 
{ 
    PORTD|=(1<<6);    
    PORTD&=~(1<<6); 
    delay(3000);    //480us以上 
    PORTD|=(1<<6); 
    DDRD&=~(1<<6); 
    delay(40);     //15~60us 
    while(PIND&(1<<6)) 
    { 
      // disp_led(3,0); 
      // for(;;) 
       //{} 
   } 
    DDRD|=(1<<6); 
    PORTD|=(1<<6); 
    delay(150);   //60~240us 
}
///////////////////////////////////////////////////////
write_1820(uchar x) 
{    
     uchar m; 
    for(m=0;m<8;m++) 
    { 
         PORTD&=~(1<<6); 
       if(x&(1<<m))    //写数据,从低位开始 
       PORTD|=(1<<6); 
       else 
       PORTD&=~(1<<6); 
       delay(40);   //15~60us 
       PORTD|=(1<<6); 
    } 
     PORTD|=(1<<6); 
} 

//////////////////////////////////////////////
uchar read_1820() 
{     
    uchar temp,k,n; 
           temp=0; 
    for(n=0;n<8;n++) 
       { 
      PORTD&=~(1<<6); 
      //delay(2);       
      PORTD|=(1<<6); 
      //delay(3);     
      DDRD&=~(1<<6); 
      k=(PIND&(1<<6));    //读数据,从低位开始 
      if(k) 
      temp|=(1<<n); 
      else 
      temp&=~(1<<n); 
      delay(50); //60~120us     
      DDRD|=(1<<6); 
        } 
   return (temp); 
}  
////////////////////////////////////////////////
void send_byte(uchar x)    //以下为显示程序 
{ 
   uchar i; 
    for(i=0;i<8;i++) 
    { 
       PORTC&=~(1<<5);   // PC5为底  为164提供时钟信号 
      if((x&(1<<(7-i)))||((dp==1)&&(i==0))) //判断每位数据的电平,及小数点判断 
      PORTC|=(1<<4);                           //若为高着PC4输出高电平    
      else 
      PORTC&=~(1<<4);                           //若为低着输出低电平 
      PORTC|=(1<<5);   //PC5 提供始终信号 
   } 
   //PORTC|=((1<<0)|(1<<1)|(1<<2)); 
} 
////////////////////////////////////////////////
void main(void) //主函数 
{ 
 // disp_led(0,0); 
  delay(2000); 
  OSCCAL=0X9d;//系统时钟校准,不同的芯片和不同的频率, 
  DDRC=0xff; 
  DDRD=0XFF;
  DDRA=0XFF;
 PORTA=0XF3; 
  PORTD=0XFF; 
  WDR();       //看门狗计数清零 
  LCD_init();
  WDTCR=0x0F; 
  PORTC=0xff; 
  while(1) 
   { 
      uchar i,temh,teml; 
      init_1820();        //复位18b20 
      write_1820(0xcc);   //skip rom 
      write_1820(0x44); // 发出转换命令 convert T
      delay(400); 
      init_1820(); 
      WDR(); 
      write_1820(0xcc);  //发出读命令 
      write_1820(0xbe); 
      teml=read_1820();  //读数据 
      temh=read_1820(); 
	 
      //for(i=0;i<7;i++)    //测试用 
      //{ 
      //send_byte(0x40); 
      //send_byte(disp_table[0&0x0f]); 
                  //} 
      //send_byte(disp_table[temh>>4]); 
      //send_byte(disp_table[temh&0x0f]); 
                  //send_byte(disp_table[teml>>4]); 
      //send_byte(disp_table[teml&0x0f]); 
      count=(temh*256+teml)*6.25;  //计算具体温度 
      WDR(); 
                  //disp_led(0,1);     //显示温度 
      for(i=0;i<100;i++)   //每次转换需要延时200ms以上 
      delay(1000);  
	   LCD_write_string(0,0,count);    
        } 
} 




/*显示程序 CONTROL为控制显示 BUFFER为显示数据 
void disp_led(uchar buffer,uchar control) 
{ 
   uchar i,temp[6]; 
   uint tempcount; 
   dp=0; 
   switch(control) 
   { 
      case 0:      //CONTROL为零全部数码管显示buffer   
      { 
         for(i=0;i<11;i++) 
         send_byte(disp_table[buffer%10]);//显示数字 
         break; 
      } 
      case 1:      //control为1,显示count中的数据为6位 
      { 
         tempcount=count; 
         for(i=0;i<6;i++)   //取出每位中的数据 
         { 
            temp[i]=tempcount%10; 
            tempcount/=10; 
         } 
         send_byte(disp_table[buffer/10]);  //最开始显示buffer数据 
         send_byte(disp_table[buffer%10]); 
         send_byte(0x00);           
         send_byte(0x00); 
         send_byte(0x00); 
         for(i=0;i<6;i++) 
         {     
             if(i==3) 
            dp=1;       //小数点控制位 
             send_byte(disp_table[temp[5-i]]); 
            dp=0; 
         } 
         break; 
      } 
   } 
   PORTC|=(1<<4); 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -