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

📄 18b20.c

📁 AVR单片机 用的是ICC开发环境 DS18B20温度采集,LCD1602B显示 MCU : Atmeag16
💻 C
字号:
/***********************************************
****    DS18B20温度采集,LCD1602B显示         ***

****    MCU :   Atmeag16                     ***
	
****    作者:  XueTwins                     ***

****  	时间	20007.02.17                  ***
注:DS18B20的数据口接PA0
***********************************************/
#include <iom16v.h>
#include <macros.h>

/*******************************************************************************
                       定义MCU与LCD的接口
接线:EN-PD3、RS-PD2、DATA-PD4,5,6,7   
*******************************************************************************/
#define LCD_EN_PORT   PORTD    //PD3使能LCD
#define LCD_RS_PORT   PORTD    //PD2
#define LCD_DATA_PORT PORTD

#define LCD_EN 0x08   //PD3 out
#define LCD_RS 0x02   //PD2 out
#define LCD_DATA 0xF0 //PD4,5,6,7
        
/*******************************************************************************
                           函数原型声明
*******************************************************************************/
void LCD_init(void);//LCD初始化
void LCD_en_write(void);//LCD写
void LCD_set_xy(unsigned char x,unsigned char y);//写X,Y地址
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *string);
void LCD_write_char(unsigned command,unsigned data);
void LCD_write_data_variable(unsigned char x,unsigned char y,
                             unsigned char Z,unsigned long  S);

/*******************************************************************************
                           延时函数
                         系统时钟:8M
*******************************************************************************/
void delay_1us(void)                 //1us延时函数
{
    asm("nop");
    asm("nop");
    asm("nop");
    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<1142;i++);
}
  
void delay(unsigned int n)       //N ms延时函数
{
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
}

/*******************************************************************************
                      上面声明各函数的实现
*******************************************************************************/
void LCD_init(void)
{
   LCD_write_char(0x28,0); 
   LCD_en_write();
   delay(15);//延时15ms
   LCD_write_char(0x28,0);//四位数据接口,二行显示,5*7点阵字符
   LCD_write_char(0x0C,0);//显示开
   LCD_write_char(0x01,0);//清屏
   delay(2);
   LCD_write_char(0x06,0);//显示光标移动设置  
}
void LCD_en_write(void)//液晶使能
{
   LCD_EN_PORT|=LCD_EN;
   delay(1);
   LCD_EN_PORT&=~LCD_EN;
}
/*******************************************************************************
                         写数据
*******************************************************************************/
void LCD_write_char(unsigned command,unsigned data) 
{
 unsigned command_temp,data_temp;
 command_temp=command;
 data_temp=data;
 delay(16);
 if(command==0)
 {
  LCD_RS_PORT|=LCD_RS;               //RS=1
  LCD_DATA_PORT&=0X0f;
  LCD_DATA_PORT|=data_temp&0xf0;     //写高四位
  LCD_en_write();
  data_temp=data_temp<<4;  
  LCD_DATA_PORT&=0X0f;
  LCD_DATA_PORT|=data_temp&0xf0;     //写低四位
  LCD_en_write();
 }
 else
 {
  LCD_RS_PORT&=~LCD_RS;              //RS=0
  LCD_DATA_PORT&=0X0f;
  LCD_DATA_PORT|=command_temp&0xf0;  //写高四位
  LCD_en_write();
  command_temp=command_temp<<4;
  LCD_DATA_PORT&=0x0f;
  LCD_DATA_PORT|=command_temp&0xf0;  //写低四位
  LCD_en_write();
  }
}
/*******************************************************************************
                         写地址
 //设置LCD显示的起始位置,显示字符串的位置,X:0-15,Y:0-1
 // LCD第一行显示寄存器地址:0X80-0X8F
 // LCD第一行显示寄存器地址:0XC0-0XCF
*******************************************************************************/
void LCD_set_xy(unsigned char x,unsigned char y)
{
   unsigned char address;
	if(y==0)
	    address=0x80 + x;
    else              //即y==1
	    address=0xC0 + x;
	LCD_write_char(address,0);
}
/*******************************************************************************
                       英文字符串显示函数
*******************************************************************************/
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *string)
{
   LCD_set_xy(x,y);//写地址
   while (*string)  // 写显示字符
    {
      LCD_write_char(0,*string);
      string ++;
    }
} 	
/*******************************************************************************
                        显示数字变量函数
	Z为S变量共几位数   //最大变量显示为99999;
*******************************************************************************/
void LCD_write_data_variable(unsigned char x,unsigned char y,
                     unsigned char Z,unsigned long  S)  
					  
{
    unsigned char k;
    unsigned char p[6]="0";
    unsigned char i=0;                    
	LCD_set_xy( x, y );
     for(i=0;i<Z;i++)
       {
	     p[i]=S%10;
	     S=S/10;
	    }	
	   while(!(p[i]))
		 { 
		  if(i==0)
		   {
		     LCD_write_char( 0, 0x30 );
		     i--;
		   }
		  else
		   {
		    i--;
		    LCD_write_char( 0, 0x80 );
		   }		
		 }

		 for(;i<255;i--)
		 {		
          LCD_write_char( 0, p[i]+0x30 );
	     }
  }

///////////////////////数字温度传感器////////////////////////////////////
////////////////////////DS18B20//////////////////////////////////////////
#define DS18B20_PORT PORTA
#define DS18B20_DDR  DDRA
#define DS18B20_PIN  PINA
#define DS18B2_IO   BIT(0)//0x01

/*******************************************************************************
                     函数原型声明
*******************************************************************************/
unsigned char DS18B20_reset(void);     // 复位程序
unsigned char DS18B20_read(void);      //从单总线读1字节
void DS18B20_write(unsigned char CMD); //向单总线写1字节

long count;

/*******************************************************************************
                     复位程序
	  检查DS18B20是否存在:不存在返回1,存在返回0
*******************************************************************************/
unsigned char DS18B20_reset(void)
{
	unsigned char online;
	DS18B20_DDR |= DS18B2_IO;    //PORTA.0输出
	DS18B20_PORT &=~DS18B2_IO;   //PORTA&=0xFE;//输出低电平
	delay_nus(500);              //480us~960us
	DS18B20_PORT |=DS18B2_IO;    //输出高电平
	DS18B20_DDR &=~DS18B2_IO;    //PORTA.0输入
	delay_nus(45);               //16-60us等待响应
	online=DS18B20_PORT & DS18B2_IO;//响应信号,读出online的值
	delay_nus(100);   //60-240us
	return (online);
}
/*******************************************************************************
                     从DS18B20读1字节数据(从单总线读1字节)
*******************************************************************************/
unsigned char DS18B20_read(void)
{
    unsigned char i,temp;
	unsigned char byte=0;//byte=0x00;
	for(i=0;i<8;i++)
	{
	    DS18B20_DDR|=DS18B2_IO;     //PORTA.0输出
	    DS18B20_PORT&=~DS18B2_IO;   //PORTA&=0xFE;//输出低电平,产生读起始信号
	    delay_nus(3);               //延时1us~15us
	    DS18B20_PORT|=DS18B2_IO;    //输出高电平
	    DS18B20_DDR&=~DS18B2_IO;    //PORTA.0输入,接收数据
	    delay_nus(10);              //要在15us内完成读数
	    temp=(DS18B20_PIN & DS18B2_IO);//读数据,从低位开始 
	    if(temp!=0x00)
		byte|=0x80;
	    if(i<7)
		byte=byte>>1;
            delay_nus(100);             //60~120us   
	    DS18B20_DDR|=DS18B2_IO;     //PORTA.0输出
	    delay_nus(5);
	}
	return byte;
}
/*******************************************************************************
                     写ROM或存储器命令到DS18B20(向单总线写1字节)
*******************************************************************************/
void DS18B20_write(unsigned char CMD)
{
        unsigned char i,value;
	DS18B20_DDR|=DS18B2_IO;  //PORTA.0输出
	for(i=0;i<8;i++)
	{
	    value=CMD&DS18B2_IO;
		if(value==0x01)
		{
		        delay_nus(1);             //延时>1us
			DS18B20_PORT&=~DS18B2_IO; //产生写起始信号
			delay_nus(10);            //延时1us~15us
			DS18B20_PORT|=DS18B2_IO;  //数据线电平拉高
			delay_nus(100);           //延时60us~120us 
		}
		else
		{
		        delay_nus(1);             //延时>1us
			DS18B20_PORT&=~DS18B2_IO; //产生写起始信号
			delay_nus(100);           //18B20采样要60us到120us
			DS18B20_PORT|=DS18B2_IO;  //数据线电平拉高
			delay_nus(10);
		}
		CMD=CMD>>1;                        //右移一位
	}
}
/*******************************************************************************
                        主函数
*******************************************************************************/
void main(void)
{
   unsigned char i,temh,teml; 
   unsigned char errortrue;
 
   
   DDRD|=LCD_EN | LCD_RS | LCD_DATA;//EN方向,RS方向,数据口方向为输出   
   LCD_EN_PORT &= ~LCD_EN;      //EN=0
   LCD_init();                  //液晶初始化
   
   delay_nus(2000); 
   OSCCAL=0X9d;     //系统时钟校准,不同的芯片和不同的频率, 

  
   WDR();            //看门狗计数清零 
   WDTCR=0x0F; 

      

   for(;;)
   {
      
	  LCD_write_char(0x01,0);//清屏

	  errortrue=DS18B20_reset();        //复位18b20   
	  if(errortrue==0x01)
	  {
           LCD_write_string(0,1,"wrong"); //初始化失败
	  }
	  else
	  {
           LCD_write_string(0,0,"Temperature:");//初始化成功
	  } 

      DS18B20_write(0xcc);  // 发出转换命令
      DS18B20_write(0x44);  //启动18B20温度开始转换
      delay_nus(400);       //每次转换需要延时200ms以上 
      DS18B20_reset(); 
      WDR(); 
      DS18B20_write(0xcc);  //发出读命令 ,搜索ROM
      DS18B20_write(0xbe);  //读闪存器,读CRC冗余校验
      teml=DS18B20_read();  //读低字节数据 
      temh=DS18B20_read();  //读高字节数据 
      count=(temh*256+teml)*6.25;  //计算具体温度 
      WDR();
	  LCD_write_data_variable(0,1,2,count); 
	  LCD_write_string(14,1,"`C");  
      delay(300); 
   }
}

⌨️ 快捷键说明

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