#include <reg51.h>
#include <intrins.h>
#include "ADC0832.h"
#include <DS18B20.h>
#define uint unsigned int
#define uchar unsigned char
#define LCDDATA P1
uint BJ_temp=0,BJ_yw=0;
unsigned char TempBuffer[4];
unsigned char dispbuf[3]=0;
unsigned int getdata;
long uint i,ADC_num,adres_num=0;
int flag_start=0,flag_BJ=0;
int time_over=0;
uint pwm_compare=100,time1=0;
int timenum=0;
char time[6]="00:00";
char f='0',f1='0',g='0',g1='0';
unsigned char t[2],*pt; //用來存放溫度值,測溫程序就是通過這個數組與主函數通信的
unsigned char TempBuffer1[9]={0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0x43,'\0'};
unsigned char TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20,
0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,0x43,'\0'};
unsigned char code dotcode[4]={0,25,50,75};
sbit K1=P3^0; //時間+
sbit K2=P3^1;//時間-
sbit K3=P3^2;//開始清洗
sbit K4=P0^0;//電機+
sbit K5=P0^1;//電機-
sbit PWM_OUT=P3^7;
sbit sing=P2^4;
//LCD1602引腳定義
//采用8位并行方式,DB0~DB7連接至LCDDATA0~LCDDATA7
sbit RS=P3^5;
sbit CS=P3^6;
void DelayMS(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<100;j++);
}
void Delay_xms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1000;j++);
}
void Delay_xus(uint t)
{
for(;t>0;t--)
{
_nop_();_nop_(); _nop_(); _nop_();
_nop_();_nop_(); _nop_(); _nop_();
}
}
void covert1(void) //將溫度轉換為LCD顯示的數據
{
unsigned char x=0x00,y=0x00;
t[0]=*pt;
pt++;
t[1]=*pt;
if(t[1]>0x07) //判斷正負溫度
{
TempBuffer1[0]=0x2d; //0x2d為"-"的ASCII碼
t[1]=~t[1]; /*下面幾句把負數的補碼*/
t[0]=~t[0]; /* 換算成絕對值*********/
x=t[0]+1; /***********************/
t[0]=x; /***********************/
if(x>255) /**********************/
t[1]++; /*********************/
}
else TempBuffer1[0]=0x2b; //0xfe為變"+"的ASCII碼
t[1]<<=4; //將高字節左移4位
t[1]=t[1]&0x70; //取出高字節的3個有效數字位
x=t[0]; //將t[0]暫存到X,因為取小數部分還要用到它
x>>=4; //右移4位
x=x&0x0f; //和前面兩句就是取出t[0]的高四位
t[1]=t[1]|x; //將高低字節的有效值的整數部分拼成一個字節
TempBuffer1[1]=t[1]/100+0x30; //+0x30 為變 0~9 ASCII碼
if( TempBuffer1[1]==0x30) TempBuffer1[1]=0xfe; //百位數消隱
TempBuffer1[2]=(t[1]%100)/10+0x30; //分離出十位
TempBuffer1[3]=(t[1]%100)%10+0x30; //分離出個位
t[0]=t[0]&0x0c; //取有效的兩位小數
t[0]>>=2; //左移兩位,以便查表
x=t[0];
y=dotcode[x]; //查表換算成實際的小數
TempBuffer1[5]=y/10+0x30; //分離出十分位
TempBuffer1[6]=y%10+0x30; //分離出百分位
if((TempBuffer1[2]!='0')&&(TempBuffer1[3]!='0'))
{
BJ_temp=(TempBuffer1[2]-'0')*10+TempBuffer1[3]-'0';
TempBuffer[0]=TempBuffer1[2];
TempBuffer[1]=TempBuffer1[3];
}
TempBuffer[2]='C';
TempBuffer[3]='\0';
}
void timer_Init()
{
TMOD=0X11; //定時器0 工作1 定時器1 工作1
TH0= (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
TR0 = 1; //定時器1開始計時
ET0=1;
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
TR1 = 1; //定時器1開始計時
ET1=1;
EA=0;
}
//控制LCD寫時序
void LCD_en_write(void)
{
CS=1;
Delay_xus(20);
CS=0;
Delay_xus(20);
}
//寫指令函數
void Write_Instruction(uchar command)
{
RS=0;
CS=1;
LCDDATA=command;
LCD_en_write();//寫入指令數據
}
//寫數據函數
void Write_Data(uchar Wdata)
{
RS=1;
CS=1;
LCDDATA=Wdata;
LCD_en_write();//寫入數據
}
//字符顯示初始地址設置
void LCD_SET_XY(uchar X,uchar Y)
{
uchar address;
if(Y==0)
address=0x80+X;//Y=0,表示在第一行顯示,地址基數為0x80
else
address=0xc0+X;//Y非0時,表時在第二行顯示,地址基數為0xC0
Write_Instruction(address);//寫指令,設置顯示初始地址
}
//在第X行Y列開始顯示Wdata所對應的單個字符
void LCD_write_char(uchar X,uchar Y,uchar Wdata)
{
LCD_SET_XY(X,Y);//寫地址
Write_Data(Wdata);//寫入當前字符并顯示
}
/*********************************************************************
*名 稱: LCD_write_str()
*功 能:使 LCD1602 顯示一個字符串
*入口參數: y:行 0 或 1 x:列, 0~15, str[]: 待顯示的字符串
*出口參數:無
*********************************************************************/
void LCD_write_str(uchar X,uchar Y,char str[])
{
uint i=0;
LCD_SET_XY(X,Y);//寫地址
while(str[i] != '\0')
{
Write_Data(str[i]);
++i;
Delay_xms(5);
}
}
//清屏函數
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 ADC()
{
float adc_num=0;
long unsigned int v = 0;
getdata=read0832();
adc_num=(float)(getdata*19.5);
adc_num=(float)(adc_num*0.02); //0--5000 0--100%
i=(int)adc_num;
if(i>=98)
i=100;
BJ_yw=i;
dispbuf[0]=i/100+'0';
dispbuf[1]=i/10%10+'0';
dispbuf[2]=i%10+'0';
LCD_write_str(10,0,dispbuf);
LCD_write_char(13,0,'%');
Delay_xms(20);
}
void time_sacn()
{
int flag=0;
while(flag==0) //十分
{
if(K1==0)
{
while(K1==0);
f++;
if( f==('9')+1)
f='0';
}
if(K2==0)
{
while(K2==0);
f--;
if( f==('0')-1)
f='9';
}
if(K3==0)
{
while(K3==0);
flag=1;
}
time[0]=f;
time[1]=f1;
time[2]=':';
time[3]=g;
time[4]=g1;
LCD_write_str(5,1,time);
}
while(flag==1) //分
{
if(K1==0)
{
while(K1==0);
f1++;
if( f1==('9')+1)
f1='0';
}
if(K2==0)
{
while(K2==0);
f1--;
if( f1==('0')-1)
f1='9';
}
if(K3==0)
{
while(K3==0);
flag=2;
}
time[0]=f;
time[1]=f1;
time[2]=':';
time[3]=g;
time[4]=g1;
time[5]='\0';
flag_start=1;
LCD_write_str(5,1,time);
}
}
void moto()
{
if(K4==0) //加速
{
while(K4==0);
pwm_compare-=20;
if(pwm_compare<=20)
pwm_compare=20;
}
if(K5==0) //減速
{
while(K5==0);
pwm_compare+=20;
if(pwm_compare>=200)
pwm_compare=200;
}
}
void main()
{
PWM_OUT=0;
LCD_init(); //lcd初始化
LCD_clear(); //清屏
time_sacn(); //進行時間設置
timer_Init(); // 初始化
pt=ReadTemperature(0x3f); //上限溫度下限
//讀取溫度,溫度值存放在一個兩個字節的數組
while(1)
{
if(K3==0) //暫停
{
while(K3==0);
flag_start=~flag_start;
}
if((flag_start==1)||(flag_BJ==1))
EA=1;
if((flag_start!=1)||(flag_BJ!=1)) //停止計數
{ EA=0;PWM_OUT=0; }
moto(); //電機速度
pt=ReadTemperature(0x3f); //上限溫度下限
//讀取溫度,溫度值存放在一個兩個字節的數組
covert1();
LCD_write_str(2,0,TempBuffer);
ADC(); //ADC采集顯示
if((BJ_temp>=80)||(BJ_yw<=10)) //溫度高于80 或者 液位低于10% 報警 停止工作
{
time_over=1;
flag_BJ=0;
}
if((BJ_temp<80)&&(BJ_yw>10))
{
time_over=0;
flag_BJ=1;
}
if(time_over==1)
sing=0;
if(time_over==0)
sing=1;
}
}
void t0(void) interrupt 1 using 0 //定時器0 中斷服務
{
TH0 = (65536 - 100) / 256;
TL0= (65536 - 1000) % 256;
if(time1<pwm_compare)
{
PWM_OUT=0;
}
else
{
PWM_OUT=1;
}
if(time1==200)
{
time1=0;
PWM_OUT=0;
}
time1++;
}
void timer1_int() interrupt 3
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
timenum++;
if(timenum>=20) //1s
{
timenum=0;
g1--;
if(g1==('0')-1)
{ g--;g1='9';}
if(g==('0')-1)
{ f1--;g='5';}
if(f1==('0')-1)
{ f--;f1='9';}
if(f==('0')-1)
{ f='0';}
if((f=='0')&&(f1=='5')&&(g=='0')&&(g1=='0')) //倒計時5min
time_over=1;
if((f=='0')&&(f1=='4')&&(g=='5')&&(g1=='0')) // 報警10s
time_over=0;
if((f=='0')&&(f1=='0')&&(g=='0')&&(g1=='0')) //停止
flag_start=0;
time[0]=f;
time[1]=f1;
time[2]=':';
time[3]=g;
time[4]=g1;
time[5]='\0';
LCD_write_str(5,1,time);
}
}
|