一,材料准备
stc89c52rc(封装:pdid40)
ds18b20(封装:to-92-3)
16v10uf电容
10k电阻
lcd1602显示屏
轻触开关
10k可调电阻(电位器)
30pf电容(22pf的也可以)
11.0592mHz晶振(12mHz的也可以)
杜邦线若干
二,资料链接
点击链接“https://sunm.lanzouj.com/iAh13272ah4d”领取
三,外围电路架设
基础外围:
首先,基础外围有供电电路、复位电路和晶振(时钟)电路,具体做法如下:
1、复位:复位需要在单片机第9脚上提供2us以上的高电平。按照下图接法,可实现开机自动复位及手动复位。
2、晶振电路:stc89c系列单片机需要外接晶振提供时钟信号。频率一般选在8~12MHz之间,起振电容多为22皮法或30皮法。
其他外围
lcd1602接线如图。其中,vo脚需要用于调节对比度(后文再叙)。
至此,电路基本完成接线。完整接线如下图(同资料包内pcb文件)。
正面如图:
背面如图:
四,代码实现
main.c,一个文件实现内容
//writer:见闻山海1209
//date:24-8
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^7;//ds18b20
uint tvalue;
uchar tflag;
uchar code disp1[]="Temperature";
uchar code disp2[]="Now:";
sbit RS=P1^2;
sbit RW=P1^1;
sbit CS=P1^0;
#define LCDDATA P0
void Delay_xms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<112;j++);
}
void Delay_xus(uint x)//延时
{
while(x--);
}
//lcd
void LCD_en_write(void)
{
CS=1;//EN
Delay_xus(20);
CS=0;
Delay_xus(20);
}
//写
void Write_Instruction(uchar command)
{
RS=0;
RW=0;
CS=1;
LCDDATA=command;
LCD_en_write();//写入
}
//写数据
void Write_Data(uchar Wdata)
{
RS=1;
RW=0;
CS=1;
LCDDATA=Wdata;
LCD_en_write();//写入数据
}
//字符显示初始地址设置
void LCD_SET_XY(uchar X,uchar Y)
{
uchar address;
if(Y==0)
address=0x80+X;
else
address=0xc0+X;
Write_Instruction(address);//写
}
//在第X行Y列开始显示
void LCD_write_str(uchar X,uchar Y,uchar *s)
{
LCD_SET_XY(X,Y);//设置初始字符显示地址
while(*s)
{
Write_Data(*s);
s++;
}
}
//在第X行Y列开始显示Wdata所对应的单个字符
void LCD_write_char(uchar X,uchar Y,uchar Wdata)
{
LCD_SET_XY(X,Y);//写地址
Write_Data(Wdata);//写入当前字符并显示
}
//清屏函数
void LCD_clear(void)
{
Write_Instruction(0x01);
Delay_xms(5);
}
//显示屏初始化函数
void LCD_init(void)
{
Write_Instruction(0x38); //8bit interface,2line,5*7dots
Delay_xms(5);
Write_Instruction(0x38);
Delay_xms(5);
Write_Instruction(0x38);
Write_Instruction(0x08); //关显示,不显光标,光标不闪烁
Write_Instruction(0x01); //清屏
Delay_xms(5);
Write_Instruction(0x04); //写一字符,整屏显示不移动
//Write_Instruction(0x05); //写一字符,整屏右移
//Write_Instruction(0x06); //写一字符,整屏显示不移动
//Write_Instruction(0x07); //写一字符,整屏左移
Delay_xms(5);
//Write_Instruction(0x0B); //关闭显示(不显示字符,只有背光亮)
Write_Instruction(0x0C); //开显示,光标、闪烁都关闭
//Write_Instruction(0x0D); //开显示,不显示光标,但光标闪烁
//Write_Instruction(0x0E); //开显示,显示光标,但光标不闪烁
//Write_Instruction(0x0F); //开显示,光标、闪烁均显示
}
void ds1820rst()/*ds1820复位*/
{
uchar x=0;
DQ = 1; //DQ复位
Delay_xus(4); //延时
DQ = 0; //DQ拉低
Delay_xus(100); //精确延时大于480us
DQ = 1; //拉高
Delay_xus(40);
}
uchar ds1820rd()/*读数据*/
{
uchar i=0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 0; //给脉冲信号
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
Delay_xus(10);
}
return(dat);
}
void ds1820wr(uchar wdata)/*写数据*/
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = wdata&0x01;
Delay_xus(10);
DQ = 1;
wdata>>=1;
}
}
read_temp()/*读取温度值并转换*/
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//*启动温度转换*/
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0xbe);//*读取温度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{
tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue);
}
void main()
{
uchar temp1,temp2,temp3,temp4;
Delay_xms(50);//等待系统稳定
LCD_init(); //LCD初始化
LCD_clear(); //清屏
LCD_write_str(3,0,disp1);
LCD_write_str(0,1,disp2);
while(1)
{
read_temp(); //读取温度
temp1=(tvalue/1000)+'0'; //百位
temp2=(tvalue%1000/100)+'0'; //十位
temp3=(tvalue%100/10)+'0'; //个位
temp4=(tvalue%10)+'0'; //小数位
if(tflag)
LCD_write_char(4,1,'-');
else
LCD_write_char(4,1,'+');
LCD_write_char(5,1,temp1);
LCD_write_char(6,1,temp2);
LCD_write_char(7,1,temp3);
LCD_write_char(8,1,0x2e);//"."
LCD_write_char(9,1,temp4);
LCD_write_char(10,1,0xdf);
LCD_write_char(11,1,'C');
}
}
五,运行实例
正常情况下,没有调节lcd1602对比度前,屏幕没有可见显示。
调节对比度(调整10k电位器)后,显示效果: