#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit a=P1^0;
sbit CS1=P3^4;//片选1,低电平有效,CS1=0开左屏幕,CS1=1关左屏幕
sbit CS2=P3^3;//片选2,低电平有效,CS2=0开右屏幕,CS2=1关右屏幕
sbit RS=P3^7;//数据,指令选择信号,RS=1为数据操作,RS=0为写指令或读状态(一般为读忙标志)
sbit RW=P3^6;//读写选择信号,RW=1为读选通,RW=0为写选通
sbit EN=P3^5;//读写使能信号
sbit DQ = P1^1; // DS18B20传感器的引脚定义
void show(uchar screen,uchar page,uchar column,uchar *p);
unsigned char code dang[]=
{
0x00,0x40,0x42,0x44,0x58,0x40,0x40,0x7F,0x40,0x40,0x50,0x48,0xC6,0x00,0x00,0x00,
0x00,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFF,0x00,0x00,0x00
};
unsigned char code qian[]=
{
0x08,0x08,0xE8,0x29,0x2E,0x28,0xE8,0x08,0x08,0xC8,0x0C,0x0B,0xE8,0x08,0x08,0x00,
0x00,0x00,0xFF,0x09,0x49,0x89,0x7F,0x00,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00,0x00
};
unsigned char code wen[]=
{
0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00
};
unsigned char code t[]=
{
0x06,0x09,0x09,0xE6,0xF8,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
0x00,0x00,0x00,0x07,0x1F,0x30,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00
};
unsigned char code du[]=
{
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00
};
unsigned char code t1[][32]={
{0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x18,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0x02,0x12,0x12,0x1F,0x12,0x12,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x84,0x04,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x0C,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00,0x00,0x00,0x00,0x00},
};
void Delay15us(void)
{
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
nop();
}
void uartinit()
{
SCON=0x50; //设定串口工作方式
PCON=0x00; //波特率不倍增
TMOD|=0x20; //定时器1工作于8位自动重载模式, 用于产生波特率
EA=1;
ES = 1; //允许串口中断
TL1=0xfd;
TH1=0xfd; //波特率9600
TR1=1;
}
//温度------------------------------------------------------------
/*********************************************************/
// 复位DS18B20(初始化)
/*********************************************************/
void DS18B20_ReSet(void)
{
uchar i;
a=0;
DQ=0;
i=240;
while(--i);
DQ=1;
i=30;
while(--i);
while(~DQ);
i=4;
while(--i);
a=1;
}
/*********************************************************/
// 向DS18B20写入一个字节
/*********************************************************/
void DS18B20_WriteByte(uchar dat)
{
uchar j;
uchar btmp;
for(j=0;j<8;j++)
{
btmp=0x01;
btmp=btmp<<j;
btmp=btmp&dat;
if(btmp>0) // 写1
{
DQ=0;
Delay15us();
DQ=1;
Delay15us();
Delay15us();
Delay15us();
Delay15us();
}
else // 写0
{
DQ=0;
Delay15us();
Delay15us();
Delay15us();
Delay15us();
DQ=1;
Delay15us();
}
}
}
void delay (uchar z)
{
uchar i,j;
for(i=z;i>0;i--)
for(j=114;j>0;j--);
}
/*********************************************************/
// 读取温度值
/*********************************************************/
int DS18B20_ReadTemp(void)
{
uchar j;
int b,temp=0;
DS18B20_ReSet(); // 产生复位脉
DS18B20_WriteByte(0xcc); // 忽略ROM指令
DS18B20_WriteByte(0x44); // 启动温度转换指令
DS18B20_ReSet(); // 产生复位脉
DS18B20_WriteByte(0xcc); // 忽略ROM指令
DS18B20_WriteByte(0xbe); // 读取温度指令
for(j=0;j<16;j++) // 读取温度数量
{
DQ=0;
_nop_();
_nop_();
DQ=1;
Delay15us();
b=DQ;
Delay15us();
Delay15us();
Delay15us();
b=b<<j;
temp=temp|b;
}
temp=temp*0.0625*10; // 合成温度值并放大10倍
return (temp); // 返回检测到的温度值
}
/*********************************************************/
// 温度值的显示
/*********************************************************/
void LcdPrintTemp(int temp)
{
if(temp<0)
{
temp=0-temp; // 负数转为正数
}
else
{
show(3,1,0*16,t1[temp/1000+0x30]); // 显示百位show(2,2,2*16,t1[flag/100+0x30]);
}
show(2,2,0*16,t1[temp%1000/100+0x30]); // 显示十位
show(2,2,1*16,t1[temp%100/10+0x30]); // 显示个位
//show('.'); // 显示小数点
show(2,2,2*16,t1[temp%10+0x30]); // 显示小数后一位小数
}
void busy()
{P0=0X00;
RS=0;
RW=1;
EN=1;
while(P0&0X80);//P0&0X80结果为真则一直执行空操作,也就是说P0&0X80为0则结束循环
EN=0;
}
void wcmd(uchar cmd)
{busy(); //每次写入指令或数据之前都进行忙检测
RS=0;
RW=0;
P0=cmd;
EN=1;_nop_();_nop_();//在EN下降沿写入数据和指令
EN=0;
}
void wdata(uchar dat) //写命令和写数据只在RS=0或RS=1上不同,其余都相同
{busy();
RS=1;
RW=0;
P0=dat;
EN=1;_nop_();_nop_();//在EN下降沿写入数据和指令
EN=0;
}
void set_page(uchar page)//设置页,12864LCD共有8页,每页有8行点阵点。
{page=0xb8|page; //首页地址为0XB8
wcmd(page); //page取值范围为0~7,表示第1到8页
}
void set_line(uchar line)//设置显示的起始行,共有0——63行,一般从0行开始显示
{line=0xc0|line; //起始行地址0XC0
wcmd(line); //line取值范围为0~63,表示第1到64行
}
void set_column(uchar column)//设置显示的列
{//column=column&0x3f; //列的最大值为0X3F,即64
column=0x40|column; //列的首地址为0X40,
wcmd(column); //column的取值范围为0~63,共64列
}
void set_onoff(uchar onoff)//设置显示开关,onoff取值为0或1
{onoff|=0x3e;//0X3E是关显示,0X3F是开显示
wcmd(onoff);//所以若onoff为0,则表示关显示,onoff为1,则表示开显示
}
void select_screen(uchar screen)//选屏,screen取值范围为0,1,2
{switch(screen)
{case 0:CS1=0;CS2=0;break; //全屏
case 1:CS1=0;CS2=1;break; //左半屏
case 2:CS1=1;CS2=0;break; //右半屏
default:break;
}
}
void clear_screen(uchar screen)//清屏
{uchar i,j;
select_screen(screen);//先选屏
for(i=0;i<8;i++)//控制页数0——7,共8页
{set_page(i);//设置页
set_column(0); //设置列,每页都从第1列开始,共64列
for(j=0;j<64;j++)//控制列数0——63,共64列
wdata(0x00);//写入0,列地址指针会自动加1
}
}
void init() //LCD初始化
{busy(); //忙检测
select_screen(0);//选屏,全屏
set_onoff(0); //关显示
select_screen(0); //选屏,全屏
set_onoff(1); //开显示
select_screen(0); //选屏,全屏
clear_screen(0); //清屏
set_line(0); //起始行:0
}
void show(uchar screen,uchar page,uchar column,uchar *p)//显示一个汉字,一个汉字有32字节数据
{uchar i; //screen表示选择屏幕,page表示页,column表示列,*p表示汉字的数组
select_screen(screen); //选屏
set_page(page); //设置页,写上半页
set_column(column);//设置列
for(i=0;i<16;i++) //控制16列的数据输出
wdata(p[i]); //汉字的上半部分
set_page(page+1); //写下半页
set_column(column); //控制列
for(i=0;i<16;i++) //控制16列的数据输出
wdata(p[i+16]); //汉字的下半部分
}
void uart_init()
{
TMOD = 0x20;
TH1 = 0XFd;
TL1 = 0XFd;
SCON = 0x50;
PCON = 0X00;
TR1 = 1;
EA = 1;
ES = 1;
}
void DelayMs(uint time)
{
uint i,j;
for(i=0;i<time;i++)
for(j=0;j<112;j++);
}
//------------------------------------------------------------------
void main()
{
int temp;
init();
clear_screen(0);
uart_init() ;
set_line(0);
while(1)
{
show(1,0,2*16,dang);
show(1,0,3*16,qian);
show(2,0,0*16,wen);
show(2,0,1*16,du );
show(2,3,3*16,t);
temp=DS18B20_ReadTemp();
LcdPrintTemp(temp); // 显示测量结果
}
}