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

📄 ds18b20lcd.c

📁 单片机对温度传感器DS1820的控制 ?テ晕露却衅鱀S1820的控制
💻 C
字号:
#include <reg51.h>
#include <absacc.h>

#define uchar   unsigned char
#define uint    unsigned int

#define LCD_COMMAND			XBYTE[0x7fff]   //LCD命令地址码
#define LCD_DATA			XBYTE[0x7eff]	//LCD数据地址码
//指针设置指令
/*
#define	POINTER_SET			XBYTE[0x20]		//主指令
#define	CURSOR_POINTER		XBYTE[0x01]		//以下三个为辅助参数,三选一
#define	CGRAM_POINTER		XBYTE[0x02]
#define	ADDR_POINTER		XBYTE[0x03]
//显示区域设置
#define	VIEW_ARIAL_SET		XBYTE[0x40]		//主指令
#define	TEXT_FIRST_ADDR		XBYTE[0x00]		//以下三个为辅助参数,
#define	TEXT_WIDTH			XBYTE[0x01]
#define	GRAPH_FIRST_ADDR	XBYTE[0x02]
#define	GRAPH_WIDTH			XBYTE[0x03]

#define	DISP_MODE			XBYTE[0x80]
#define	CHARA_ON			XBYTE[0x40]

#define	DISP_SWICH			XBYTE[0x90]
#define	CURSOR_FLICER_ON	XBYTE[0x01]
#define	CURSOR_ON			XBYTE[0x02]
#define	TEXT_DISP_ON		XBYTE[0x04]
#define	GRAPH_DISP_ON		XBYTE[0x08]

#define	AUTO_RW				XBYTE[0xb0]
#define	WRITE				XBYTE[0x00]
#define	READ				XBYTE[0x01]
#define	STOP_INSTRUCT		XBYTE[0x02]

#define	ONCE_RW				XBYTE[0xX0]
#define	W_INC_ADDR			XBYTE[0x00]
#define	R_INC_ADDR			XBYTE[0x01]
#define	W_DEC_ADDR			XBYTE[0x02]
#define	R_DEC_ADDR			XBYTE[0x03]
#define	W_UNCHANLGE_ADDR	XBYTE[0x04]
#define	R_UNCHANLGE_ADDR	XBYTE[0x05]*/

sbit	DQ = P1^0;

struct CHANNAL
{
   float   t;
   uchar   month;
   uchar   day;
   uchar   hour;
   uchar   minute;
   uchar   second;
};


uchar code ZIMO[]={
/*--  文字:  0  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:0
0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,

/*--  文字:  1  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:16
0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,

/*--  文字:  2  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:32
0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,

/*--  文字:  3  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:48
0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,

/*--  文字:  4  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:64
0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,

/*--  文字:  5  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:80
0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,

/*--  文字:  6  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:96
0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,

/*--  文字:  7  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:112
0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,

/*--  文字:  8  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:128
0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,

/*--  文字:  9  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:144
0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,

/*--  文字:  :  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:160
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,

/*--  文字: (blank)    --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
//调用下标:176
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  文字:  月  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=16x16   --*/
//调用下标:192
0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,
0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0x50,0x40,0x20,0x00,0x00,

/*--  文字:  日  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=16x16   --*/
//调用下标:  224
0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00,0x00,0x00,

/*--  文字:  通  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=16x16   --*/
//调用下标: 256
0x40,0x00,0x27,0xF8,0x20,0x90,0x00,0x60,0x07,0xF8,0x04,0x48,0xE7,0xF8,0x24,0x48,
0x24,0x48,0x27,0xF8,0x24,0x48,0x24,0x68,0x24,0x50,0x50,0x00,0x8F,0xFE,0x00,0x00,

/*--  文字:  道  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=16x16   --*/
//调用下标:288
0x02,0x10,0x41,0x20,0x2F,0xFC,0x20,0x80,0x01,0x00,0x03,0xF0,0xE2,0x10,0x23,0xF0,
0x22,0x10,0x23,0xF0,0x22,0x10,0x23,0xF0,0x22,0x10,0x50,0x00,0x8F,0xFE,0x00,0x00,

/*--  文字:  T  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
// 调用下标:320
0x00,0x00,0x00,0xFE,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,

/*--  文字:  =  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
// 调用下标:336
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,

/*--  调入了一幅图像:.C --*/
/*--  宽度x高度=8x16  --*/
// 调用下标:352
0x40,0xA0,0xA1,0x41,0x0F,0x13,0x21,0x20,0x20,0x20,0x20,0x21,0x21,0x11,0x0E,0x00,

/*--  文字:  .  --*/
/*--  Arial Black12;  此字体下对应的点阵为:宽x高=8x16   --*/
// 调用下标:368
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,

};

void clear_ram(void);
void init_lcd(void);
void write_c_1(uchar dat1,uchar com);
void write_c(uchar com);
void test3(void);
void test01(void);
void DISP_MESSAGE(struct CHANNAL channal1, struct CHANNAL channal2);

void test01(void)
{
  again1:
   ACC=LCD_COMMAND;
   if(ACC&0x03!=0x03)
     goto again1;
}
void test3(void)
{
  again2:                 //自动写是否准备好
    ACC=LCD_COMMAND;
    if(ACC&0x08!=0x08)
      goto again2;
}
//写无参数指令
void write_c(uchar com)
{
   test01();
   LCD_COMMAND = com;
}

//写单参数指令
void write_c_1(uchar dat1,uchar com)
{
   test01();
   LCD_DATA = dat1;
   LCD_COMMAND = com;
}

//写双参数指令
void write_c_2(uchar dat1,uchar dat2,uchar com)
{
   test01();
   LCD_DATA = dat1;
   LCD_DATA = dat2;
   LCD_COMMAND = com;
}

void init_lcd(void)
{
   write_c_2(0x00,0x00,0x40);
   write_c_2(0x10,0x00,0x41);
   write_c_2(0x00,0x08,0x42);
   write_c_2(0x10,0x00,0x43);
   write_c(0xa7);
   write_c(0x80);
   write_c(0x98);
}

void clear_ram(void)  //清掉屏幕上的所有亮点
{
    uint i;
    //write_c_2(0x03,0x00,0x22);
    write_c_2(0x00,0x00,0x24);
    write_c(0xb0);
    for(i=8192;i>0;i--)
    {
         test3();
         LCD_DATA = 0x00;
    }
    write_c(0xb2);
}

void SHOW_8P16(uchar o_x,uchar o_y,uint AddofZimo)   //  SHOW_16P16(4,2,528);//年
{
   uint add,num;
   uchar dat1,dat2,i;

   add=o_y<<4;
   add=add+o_x+0x0800;

   num=AddofZimo;

   for(i=16;i>0;i--)
   {
     dat1=(uchar)add&0xff;
     dat2=(uchar)((add>>8)&0xff);
     write_c_2(dat1,dat2,0x24);
     write_c_1(ZIMO[num],0xc0);

     num++;
     add+=16;
   }
}

//  16※16
void SHOW_16P16(uchar o_x,uchar o_y,uint AddofZimo)
{
   uint add,num;
   uchar dat1,dat2,i;

   add=o_y<<4;
   add=add+o_x+0x0800;

   num=AddofZimo;

   for(i=16;i>0;i--)
   {
     dat1=(uchar)add&0xff;
     dat2=(uchar)((add>>8)&0xff);
     write_c_2(dat1,dat2,0x24);

     write_c_1(ZIMO[num],0xc0);
     write_c_1(ZIMO[num+1],0xc0);

	 num+=2;
	 add+=16;
   }
}


void DISP_MESSAGE(struct CHANNAL channal1, struct CHANNAL channal2)
{
    double  tt;
    uchar   i,dat;

    //第一行
    SHOW_16P16(0,0,256);//通
    SHOW_16P16(2,0,288);//道
    SHOW_8P16(4,0,16);//1
    SHOW_8P16(5,0,176);//空格
    SHOW_8P16(6,0,320);//T
    SHOW_8P16(7,0,336);//=

    tt=channal1.t;
    i = tt/10;
    tt = tt - i*10;
    SHOW_8P16(8,0,i*16);//温度的十位
    i = (uchar)tt/1;
    tt = tt - i;
    SHOW_8P16(9,0,i*16);////温度的个位
    SHOW_8P16(10,0,368);//.
    tt = tt * 1000;
    i = tt/100;
    tt = tt - i*100;
    SHOW_8P16(11,0,i*16);//温度的小数第一位
    i = tt/10;
    tt = tt - i*10;
    SHOW_8P16(12,0,i*16);//温度的小数第二位
    i = tt/1;
    tt = tt - i;
    SHOW_8P16(13,0,i*16); //温度的小数第三位
    SHOW_8P16(14,0,352);//度的符号
    ////////////////////////
    //下面为第二行
    dat = channal1.month;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(0,16,i*16);//0
    SHOW_8P16(1,16,dat*16);//8
	SHOW_16P16(2,16,192);//月
    dat = channal1.day;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(4,16,i*16);//1
	SHOW_8P16(5,16,dat*16);//7
	SHOW_16P16(6,16,224);//日
    dat = channal1.hour;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(8,16,i*16);
	SHOW_8P16(9,16,dat*16);
    SHOW_8P16(10,16,160);//:
    dat = channal1.minute;
    i = dat/10;
    dat = dat - i*10;
    SHOW_8P16(11,16,i*16);
    SHOW_8P16(12,16,dat*16);
    SHOW_8P16(13,16,160); //:
    dat = channal1.second;
    i = dat/10;
    dat = dat - i*10;
    SHOW_8P16(14,16,i*16);
    SHOW_8P16(15,16,dat*16);

    //以下为通道二
    SHOW_16P16(0,32,256);//通
    SHOW_16P16(2,32,288);//道
    SHOW_8P16(4,32,32);//1
    SHOW_8P16(5,32,176);//空格
    SHOW_8P16(6,32,320);//T
    SHOW_8P16(7,32,336);//=

    tt=channal2.t;
    i = tt/10;
    tt = tt - i*10;
    SHOW_8P16(8,32,i*16);//温度的十位
    i = (uchar)tt/1;
    tt = tt - i;
    SHOW_8P16(9,32,i*16);////温度的个位
    SHOW_8P16(10,32,368);//.
    tt = tt * 1000;
    i = tt/100;
    tt = tt - i*100;
    SHOW_8P16(11,32,i*16);//温度的小数第一位
    i = tt/10;
    tt = tt - i*10;
    SHOW_8P16(12,32,i*16);//温度的小数第二位
    i = tt/1;
    tt = tt - i;
    SHOW_8P16(13,32,i*16); //温度的小数第三位
    SHOW_8P16(14,32,352);//度的符号
    ////////////////////////
    //下面为第二行
    dat = channal2.month;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(0,48,i*16);//0
    SHOW_8P16(1,48,dat*16);//8
	SHOW_16P16(2,48,192);//月
    dat = channal2.day;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(4,48,i*16);//1
	SHOW_8P16(5,48,dat*16);//7
	SHOW_16P16(6,48,224);//日
    dat = channal2.hour;
    i = dat/10;
    dat = dat - i*10;
	SHOW_8P16(8,48,i*16);
	SHOW_8P16(9,48,dat*16);
    SHOW_8P16(10,48,160);//:
    dat = channal2.minute;
    i = dat/10;
    dat = dat - i*10;
    SHOW_8P16(11,48,i*16);
    SHOW_8P16(12,48,dat*16);
    SHOW_8P16(13,48,160); //:
    dat = channal2.second;
    i = dat/10;
    dat = dat - i*10;
    SHOW_8P16(14,48,i*16);
    SHOW_8P16(15,48,dat*16);
}





// 以下是读取温度


//延时
void delay(unsigned int useconds)
{
	for(;useconds>0;useconds--);
}

//复位
unsigned char ow_reset(void)
{
	unsigned char presence;

	DQ = 0;					//pull DQ line low
	delay(45);				// leave it low for 480us
	DQ = 1;					// allow line to return high
	delay(1);				// wait for presence
	presence = DQ;			// get presence signal
	delay(23);				// wait for end of timeslot

	return(presence);		// presence signal returned
}							// 0=presence, 1 = no part

unsigned char read_byte(void)
{
	unsigned char	i,data1,j;

	data1 = 0x00;
	j = 1;

	for(i=1;i<=8;i++)
	{
		DQ = 0;
		j++;
		DQ = 1;
		j++;j++;j++;
        j++;j++;j++;
        j++;j++;j++;
		if(DQ == 0)
			j = 0x00;
		else
            j = 0x01;
		j<<=(i-1);
		data1 = data1 | j;
        j=3;while(j>0)j--;
	}

	return data1;
}

void write_byte(unsigned char data1)
{
	unsigned int	i,k;
	unsigned char	j;

	for(j=1;j<=8;j++)
	{
		k = data1 & 0x01;
		data1 >>= 1;
		if(k==1)
		{
			DQ = 0;
			i++;i++;
			DQ = 1;
			i=4;while(i>0) i--;
            i++;i++;
		}
		else
		{
			DQ = 0;
			i = 5;while(i>0)i--;
			DQ = 1;
			i++;
		}
	}
}

//读取温度
unsigned int Read_Temperature(void)
{
    int     i,j;
	union
	{
		unsigned char c[2];
		int x;
	}temp;

	ow_reset();
    i=i;
	write_byte(0xcc); //Skip ROM
    i=i;
	write_byte(0x44); // Start Conversion
    DQ = 1;
	for(j=0;j<100;j++)
    {     
      delay(900);
    }
	ow_reset();
    i=i ;
	write_byte(0xcc); // Skip ROM
    i=i;
	write_byte(0xbe); // Read Scratch Pad
    i=i;
	temp.c[1]=read_byte();
    i=i;
	temp.c[0]=read_byte();
    ow_reset();

	return temp.x;
}

float convert_t()
{
    unsigned int temp,k,m;
    float j,t;
    char  i;

    t=0;
    j=64.0;
    temp = Read_Temperature();
    k=0x0400;

    for(i=11;i>0;i--)
    {
       m=k&temp;
       if(m!=0)
          t=t+j;
       j/=2.0;
       k>>=1;
    }

    return t;
}

void main()
{
	int i,j;
    struct CHANNAL ch1,ch2;
      
    ch1.month = 8;
    ch1.day = 17;
    ch1.hour = 14;
    ch1.minute = 34;
    ch1.second = 50;

	for(i=0;i<2;i++)
	{
		for(j=0;j<30000;j++)
			;
	}

	init_lcd();
	for(j=0;j<30000;j++)
			;

    clear_ram();
	DISP_MESSAGE(ch1,ch2);
    ch1.t = convert_t();
    
    delay(100);
    
	while(1)
    {   
       	for(i=0;i<4;i++)
			for(j=0;j<30000;j++)
                 ;
         
       ch1.t = convert_t();
			DISP_MESSAGE(ch1,ch2);      
    }
}

⌨️ 快捷键说明

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