做設計選了單片機 做了LCD1602的溫控風扇 焊好了 實物沒法運行 LCD屏只顯示一排格子 幾個調速按鈕按下好像也沒什么反應 是我的焊接圖有問題嗎 焊接圖貼了
IMG_20210604_182430.jpg (3.72 MB, 下載次數: 35)
下載附件
2021-6-4 18:25 上傳
IMG_20210604_182440.jpg (3.36 MB, 下載次數: 38)
下載附件
2021-6-4 18:26 上傳
ZVXD%CWRI~BY]X{3Z$VNOUX.png (23.04 KB, 下載次數: 39)
下載附件
2021-6-4 18:27 上傳
原理圖跟程序
#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;
}
|