做设计选了单片机 做了LCD1602的温控风扇 焊好了 实物没法运行 LCD屏只显示一排格子 几个调速按钮按下好像也没什么反应 是我的焊接图有问题吗 焊接图贴了
原理图跟程序
#include<reg51.h>
#include<intrins.h> //包含头文件
#define LCD1602 P0
#define uchar unsigned char
#define uint unsigned int //宏定义
////////////////////
sbit dj=P1^0;//电机控制端接口
sbit DQ=P1^6;//温度传感器接口
sbit SN=P1^1;//使能继电器动作
//////////按键接口/////////////////////////////////
sbit key1=P3^5;//设置温度
sbit key2=P3^6;//温度加
sbit key3=P3^7;//温度减
//////////////////////////////////////////////////////
sbit RS = P2^7;
sbit EN = P2^6;
uint wen_du; //温度变量
uint shang,xia; //对比温度暂存变量
uchar dang;//档位显示
uchar Mode=0;
uchar d1,d2,d3;//显示数据暂存变量
uchar code tab1[]={" P: T: . C "};
uchar code tab2[]={"TH: C TL: C"};
void delay(uint ms) //延时函数,大约延时
{
uchar x;
for(ms;ms>0;ms--)
for(x=50;x>0;x--);
}
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(uint i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20()
{
uchar x=0;
DQ=1; //DQ复位
delay_18B20(8); //稍做延时
DQ=0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ=1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
/***********ds18b20读一个字节**************/
uchar ReadOneChar()
{
uchar i=0;
uchar dat=0;
for (i=8;i>0;i--)
{
DQ=0; // 给脉冲信号
dat>>=1;
DQ=1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay_18B20(5);
DQ=1;
dat>>=1;
}
}
/**************读取ds18b20当前温度************/
void ReadTemperature()
{
uchar a=0;
uchar b=0;
uint t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
delay_18B20(100);
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
t=b; //将高8位数据存入t
t<<=8; //t左移8位
t=t|a; //将t|a得到一个16位的温度数据
tt=t*0.0625; //一个最低位代表0.0625°C,所以要*0.0625得到实际温度,因为有小数运算,所以定义的tt是float浮点型变量
wen_du= tt*10+0.5; //放大10倍输出并四舍五入(将温度放大10倍可以得到小数部分)
}
/********液晶写入指令函数与写入数据函数,以后可调用**************/
void write_1602com(uchar com)//****液晶写入指令函数****
{
RS=0;//数据/指令选择置为指令
// rw=0; //读写选择置为写
LCD1602=com;//送入数据
// delay(10);
EN=1;//拉高使能端,为制造有效的下降沿做准备
delay(10);
EN=0;//en由高变低,产生下降沿,液晶执行命令
}
void write_1602dat(uchar dat)//***液晶写入数据函数****
{
RS=1;//数据/指令选择置为数据
// rw=0; //读写选择置为写
LCD1602=dat;//送入数据
// delay(10);
EN=1; //en置高电平,为制造下降沿做准备
delay(10);
EN=0; //en由高变低,产生下降沿,液晶执行命令
}
void lcd_init()//***液晶初始化函数****
{
uchar a;
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
//
write_1602com(0x80);//日历显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写日历显示的固定符号部分
// delay(3);
}
write_1602com(0x80+0x40);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
// delay(3);
}
}
void display()
{
if(Mode==0)
{
write_1602com(0x80+3);
write_1602dat(dang+0x30);
write_1602com(0x80+8);
write_1602dat(wen_du/1000+0x30);
write_1602dat(wen_du%1000/100+0x30);
write_1602dat(wen_du%100/10+0x30);
write_1602com(0x80+12);
write_1602dat(wen_du%10+0x30);
write_1602dat(0xdf);
write_1602com(0x80+0x40+3);
write_1602dat(shang/10+0x30);
write_1602dat(shang%10+0x30);
write_1602dat(0xdf);
write_1602com(0x80+0x40+12);
write_1602dat(xia/10+0x30);
write_1602dat(xia%10+0x30);
write_1602dat(0xdf);
}
}
void KEY()
{
//功能键
if(key1==0)
{
delay(10);
if(key1==0)
{
Mode++;
if(Mode==3)
Mode=0;
}
while(key1==0)
{
if(Mode==0)
{
// write_1602com(0x80+0x40+6);
write_1602com(0x0c);
}
else if(Mode==1)
{
write_1602com(0x80+0x40+4);
write_1602com(0x0f);
}
else
{
write_1602com(0x80+0x40+13);
write_1602com(0x0f);
}
}
}
//增加
if(key2==0&&Mode==1)
{
delay(10);
if(key2==0)
{
shang++;
if(shang>=99)
shang=99;
write_1602com(0x80+0x40+3);
write_1602dat(shang/10+0x30);
write_1602dat(shang%10+0x30);
write_1602com(0x80+0x40+4);
}
while(key2==0);
}
//减少
if(key3==0&&Mode==1)
{
delay(10);
if(key3==0)
{
shang--;
if(shang==xia)
shang=xia+1;
write_1602com(0x80+0x40+3);
write_1602dat(shang/10+0x30);
write_1602dat(shang%10+0x30);
write_1602com(0x80+0x40+4);
}
while(key3==0);
}
if(key2==0&&Mode==2)
{
delay(10);
if(key2==0)
{
xia++;
if(xia==shang)
xia=shang-1;
write_1602com(0x80+0x40+12);
write_1602dat(xia/10+0x30);
write_1602dat(xia%10+0x30);
write_1602com(0x80+0x40+13);
}
while(key2==0);
}
//减少
if(key3==0&&Mode==2)
{
delay(10);
if(key3==0)
{
xia--;
if(xia<=0)
xia=0;
write_1602com(0x80+0x40+12);
write_1602dat(xia/10+0x30);
write_1602dat(xia%10+0x30);
write_1602com(0x80+0x40+13);
}
while(key3==0);
}
}
void zi_dong()//自动温控模式
{
if(wen_du<(xia*10)){dj=0;dang=0;SN=0;TR0=0;}//低于下限 档位为0 电机停止
if((wen_du>=(xia*10))&&(wen_du<=(shang*10)))//温度大于下限,小于上限 1挡
{
dang=1;
SN=1; //档位置1
TR0=1;
}
if(wen_du>(shang*10)){dj=1;dang=2;SN=1;TR0=0;}//高温全速
}
void init()
{
TMOD=0x01;
TH0=0xec;
TL0=0x78;
ET0=1;
TR0=0;
EA=1;
}
void main() //主函数
{
uchar j;
dj=0; //电机
for(j=0;j<80;j++) //先读取温度值,防止开机显示85
ReadTemperature();
delay(500);
shang=30;
xia=20; //初始上下限值
ReadTemperature();
lcd_init();
init();
while(1) //进入while循环
{
ReadTemperature(); //读取温度值
KEY();//按键扫描函数
display(); //调用显示函数
zi_dong();
}
}
void T0_time() interrupt 1
{
TH0=0xec;
TL0=0x78;
dj=!dj;
}
|