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

📄 1820._c

📁 利用AVRM16和DX18B20温度传感器通信
💻 _C
字号:

 #include <iom16v.h>
    #include <macros.h>

#define LCD_RS_PORT    PORTA  //以下2个要设为同一个口,4脚
#define LCD_RS_DDR     DDRA
#define LCD_RW_PORT    PORTA //以下2个要设为同一个口,5脚
#define LCD_RW_DDR     DDRA
#define LCD_EN_PORT    PORTA //以下2个要设为同一个口,6脚
#define LCD_EN_DDR     DDRA


#define LCD_DATA_PORT  PORTA  //以下3个要设为同一个口
#define LCD_DATA_DDR   DDRA    //一定要用高4位
#define LCD_DATA_PIN   PINA


#define LCD_RS         (1<<PA1) //
#define LCD_RW         (1<<PA2)
#define LCD_EN         (1<<PA3) //
#define LCD_DATA       ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7)) //


/*--------------------------------------------------------------------------------------------------
                                  液晶函数说明
--------------------------------------------------------------------------------------------------*/
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 LCD_init(void)         //液晶初始化
{
  LCD_DATA_DDR|=LCD_DATA;   //数据口方向为输出
  LCD_EN_DDR|=LCD_EN;       //设置EN方向为输出
  LCD_RS_DDR|=LCD_RS;       //设置RS方向为输出
  
  LCD_RW_DDR|=LCD_RW;////////////////////////////////////
  LCD_RW_PORT&=~LCD_RW;/////////////////////////////////
  
  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(10);
 
}

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

void LCD_write_command(unsigned char command) 
//_write_command(0x0b)不显示
//LCD_write_command(0x0c)开显示
//LCD_write_command(0x0d)开显示闪且闪
//LCD_write_command(0x0e)开显示闪且不闪
{
  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);
   
}

/*--------------------------------------------------------------------------------------------------
                                  液晶驱动程序
--------------------------------------------------------------------------------------------------*/







#define uchar	unsigned char
#define uint	unsigned int
#define ulong	unsigned long
/******************************************************************************
                         //全局变量
******************************************************************************/



/******************************************************************************
                          DS18B20驱动程序
******************************************************************************/

/********************************************************************************/
//                           下面为DS18B20温度传感模块                                     //
/********************************************************************************/
/********************************************************************************
                            	位变量操作宏定义
********************************************************************************/
#define		BIT_SET(a,b)	a|=BIT(b)
#define		BIT_CLR(a,b)	a&=~BIT(b)
#define		BIT_INV(a,b)   	a^=BIT(b)
#define		BIT_STATUS(a,b) a&BIT(b)
/********************************************************************************
                            	DS18B20操作定义
********************************************************************************/
#define		CLR_DS18B20		BIT_CLR(PORTB,PB1)		//数据线强制拉低
#define		SET_DS18B20		BIT_SET(PORTB,PB1)		//数据线强制拉高,上拉
#define		HLD_DS18B20		BIT_SET(DDRB,PB1)		//Mega16控制总线
#define		RLS_DS18B20		BIT_CLR(DDRB,PB1)   	 	//释放总线
#define		STU_DS18B20		BIT_STATUS(PINB,PB1)		//数据线的状态


/**********************************************************************
functionName: void delayUs(BYTE temp)
description :延时函数 晶振频率:7.3728MHZ
delayUs(1);	 	//2.71us
delayUs(2);	 	//3.53us
delayUs(4);	 	//5.15us
delayUs(8);	 	//8.41us
delayUs(16);	 	//14.92us
delayUs(32);	 	//27.94us
delayUs(64);	 	//53.98us
delayUs(128);	 	//106.07us
delayUs(255);		//209.42us
delayUs(18);	 	//16.55us
delayUs(34);	 	//29.57us
delayUs(35);	 	//30.38us
delayUs(100);	 	//83.28
_NOP();			//0.14us  
**********************************************************************/
void delayUs(unsigned char temp)
{
 	 while(temp--);
}

/**********************************************************************
functionName: BYTE resetDS18B20(void)
description :DS18B20初始化1
**********************************************************************/
unsigned char resetDS18B20(void)
{
	unsigned char errTime=0;
	RLS_DS18B20;		//释放总线
	_NOP();
	HLD_DS18B20;		//Maga16控制总线
	CLR_DS18B20;		//强制拉低
	delayUs(255);		//209.42us
	delayUs(255);		//209.42us
	delayUs(255);		//83.28us
	//以上的三个延时大于480us
	RLS_DS18B20;		//释放总线,总线自动上拉
	_NOP();			
	while(STU_DS18B20)	
	{
		delayUs(5); 	//5.15us
		errTime++;
		if(errTime>20)
		return(0x00);		//如果等带大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)
	}
	errTime=0;
	while(!(STU_DS18B20))	
	{   
		delayUs(5);	 	//5.15us
		errTime++;
		if(errTime>50)
		return(0x00);		//如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)
	}
	return(0xff);
}


/**********************************************************************
functionName: BYTE readByteDS18B20(void)
description :读DS18B20一个字节2
**********************************************************************/
unsigned char readByteDS18B20(void)
{
	unsigned char i;
	unsigned char retVal=0;
	RLS_DS18B20;		//释放总线
	for(i=8;i>0;i--)
	{
	 	retVal>>=1;
	    HLD_DS18B20;	//Maga16控制总线
		CLR_DS18B20;	//强制拉低
		NOP();
	   	NOP();
	   	NOP();
	   	NOP();
	   	NOP();
		NOP();
		NOP();	
		NOP();			//延时大于1us	
		RLS_DS18B20;		//释放总线,DS18B20会将总线强制拉低
		NOP();
		NOP();
		NOP();
		if(STU_DS18B20)
		retVal|=0x80;
	
		
		delayUs(20);	 	//14.92us
	    delayUs(30);	 	//14.92us
		RLS_DS18B20;		//释放总线
		delayUs(45);	 	//30.38us
		
	}
	delayUs(1);	 		//2.71us(大于1us就行了)
	return(retVal);
}


/**********************************************************************
functionName: BYTE readByteDS18B20(void)
description :写DS18B20一个字节
**********************************************************************/
void writeByteDS18B20(unsigned char wb)
{
	unsigned char i;
	unsigned char temp;
	RLS_DS18B20;		//释放总线
	for(i=0;i<8;i++)
	{
		HLD_DS18B20;		//Maga16控制总线
		CLR_DS18B20;		//强制拉低
		delayUs(16);	 	//14.92us
		temp=wb>>i;
		temp&=0x01;
		if(temp)
		RLS_DS18B20;		//释放总线
		else
		CLR_DS18B20;		//强制拉低
		delayUs(16);	 	//14.92us
		delayUs(35);	 	//30.38us
		RLS_DS18B20;		//释放总线
		delayUs(1);	 		//2.71us(大于1us就行了)
	}
}


/**********************************************************************
functionName: unsigned int readTempDS18B20(void)
description :读DS18B20温度
**********************************************************************/
unsigned int readTempDS18B20(void)
{
	unsigned char tempL,tempH;
	unsigned int x;
	resetDS18B20();
	writeByteDS18B20(0xcc); 	//跳过ROM
	writeByteDS18B20(0x44);		//启动温度转换
	delayUs(1);
	tempL=resetDS18B20();
	writeByteDS18B20(0xcc);		//跳过ROM
	writeByteDS18B20(0xbe);		//读数据
	tempL=readByteDS18B20();
	tempH=readByteDS18B20();
	x=(tempH<<8)|tempL;
	return(x);
} 


/******************************************************************************
* 名称:float realTemp(void)
* 说明:倍率为0.0625
* 功能:计算真实温度值
* 调用:unsigned int readTempDS18B20(void)
* 输入:无
* 返回值:真实温度值(浮点数)
*******************************************************************************/
float realTemp(void)
{
float Temp= readTempDS18B20()*0.0625;
return Temp;
}


/******************************************************************************
* 名称:displayTemp
* 说明:num为真实温度值,i列.j为行,
* 功能:显示温度值
* 调用:LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
* 输入:真实温度值
* 返回值:无
*******************************************************************************/
displayTemp( unsigned char i,unsigned char j, float num)//LCD显示
{unsigned char T[15];
 unsigned int temp=num*100;
 T[0]='0'+temp/1000;
 temp=temp%1000;
 T[1]='0'+temp/100;
 temp=temp%100;
  T[2]='.';
 T[3]='0'+temp/10;
 temp=temp%10;
 T[4]='0'+temp/1;
 LCD_write_string(i,j,T);
 
}
/*void displayTemp(char x,char y,float num)
{
/*uint Tempp=num*10;
char s[3],i;
for(i=0;i<3;i++)
{
s[i]= Tempp%10;
Tempp=Tempp/10;
}
for(i=0;i<4;i++)
{
if(i<2)
LCD_write_char(x++,y,s[2-i]+'0'); 
if(i==2)
LCD_write_char(x++, y,'.');
if(i==3)
LCD_write_char(x++,y,s[0]+'0'); 
}
}*/
/******************************************************************************
                          DS18B20驱动程序
******************************************************************************/



//********************延时函数
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 port_init(void)
{
 PORTA = 0xff;
 DDRA  = 0xff;
 PORTB = 0x00;
 DDRB  = 0xff;
 PORTD = 0xff;
 DDRD  = 0xe0;
}
  
//主函数  
main()
{ 
float i=0;
//port_init();
LCD_init();

LCD_write_string(0,0 ,"welcome");

   while(1)
   {i=realTemp();//真实温度
	////i= readTempDS18B20()*0.0625;
	displayTemp( 0,1,i);//LCD显示
    delay_nms(1500);
	/*;i=realTemp();
 displayTemp(0,1,i);*/
   }
}


⌨️ 快捷键说明

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