#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
#include<intrins.h>
#include<stdio.h>
#include "18b20.h"
#include "delay.h"
#include "key.h"
sbit RS = P2^5; //定義LCD1602端口
sbit RW = P2^6;
sbit EN = P2^7;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0
#define TIME 10000 //與PWM頻率有關 12M晶振 10000周期為 10ms 頻率100Hz
sbit PWMOUT=P3^6;
int PWM_Z;//PWM脈沖占空比
long PWM_D;//定時器賦值相關
int count=0;//進入定時中斷計數
int TH=30; //溫度上限
int TL=10; //溫度下限
unsigned char KeyValue; //返回按鍵值
int temp,temp1;
float temperature;
char displaytemp[16];//定義顯示區域臨時存儲數組
/*------------------------------------------------
判忙函數
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
unsigned char LCD_Status;
RS = 0;
RW = 1;
EN = 1;
DelayMs(1);
LCD_Status = P0;
EN = 0;
return LCD_Status;
}
/*------------------------------------------------
寫入命令函數
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
while((LCD_Check_Busy()&0x80)==0x80);
RS = 0;
RW = 0;
EN = 0;
P0 = com;
EN = 1;
DelayMs(1);
EN = 0;
}
/*------------------------------------------------
寫入數據函數
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
while((LCD_Check_Busy()&0x80)==0x80);
RS = 1;
RW = 0;
EN = 0;
P0 = Data;
EN = 1;
DelayMs(1);
EN = 0;
}
/*------------------------------------------------
清屏函數
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
寫入字符串函數
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
寫入字符函數
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函數
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*顯示模式設置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
//LCD_Write_Com(0x08); /*顯示關閉*/
LCD_Write_Com(0x01); /*顯示清屏*/
DelayMs(5);
LCD_Write_Com(0x06); /*顯示光標移動設置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*顯示開及光標設置*/
DelayMs(5);
}
/*------------------------------------------------
定時器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=(65536-2000)/256; //重新賦值 2ms
TL0=(65536-2000)%256;
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關打開
}
/*------------------------------------------------
主函數
------------------------------------------------*/
void main(void)
{
LCD_Init();
Init_Timer0();
PWMOUT=0;
while (1)
{
KeyValue=KeyScan();
if(KeyValue!=0)//如果有鍵按下
{
Keyprocessing(KeyValue); //鍵值處理
}
temp1=ReadTemperature(); //讀取溫度值
if(temp1>0)
{ if(temp1<2000)temp=temp1;}
temperature=(float)temp*0.0625;
sprintf(displaytemp,"Temp=%3.1f",temperature);//
LCD_Write_String(0,1,displaytemp);// 顯示溫度值
PWM_Z=(temperature-TL)/(TH-TL)*100; //計算占空比
if(PWM_Z>100)PWM_Z=100;
if(PWM_Z<0)PWM_Z=0;
if(PWM_Z==100)
{
TR0=0;
ET0=0;
EA=0; //
PWMOUT=1;
}
if(PWM_Z==0)
{
TR0=0;
ET0=0;
EA=0; //
PWMOUT=0;
}
if((PWM_Z>0)&&(PWM_Z<100))
{
EA=1; //總中斷打開
ET0=1; //定時器中斷打開
TR0=1; //定時器開關打開
}
sprintf(displaytemp,"P=%3d",PWM_Z);//
LCD_Write_String(10,1,displaytemp);// 顯示占空比
sprintf(displaytemp,"TH=%2d",TH);//
LCD_Write_String(0,0,displaytemp);// 顯示溫度上限
sprintf(displaytemp,"TL=%2d",TL);//
LCD_Write_String(10,0,displaytemp);// 顯示溫度下限
DelayMs(300);
}
}
/*------------------------------------------------
定時器中斷子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
if(PWMOUT==0) //如果正輸出低電平 設置高電平延時時間
{
PWM_D=TIME/100*PWM_Z;
TH0=(65536-PWM_D)/256; //
TL0=(65536-PWM_D)%256;
PWMOUT=1;
}
else //如果正輸出高電平 設置低電平延時時間
{
PWM_D=TIME/100*PWM_Z;
//PWM_D=20000-PWM_D;
TH0=(65536-(TIME-PWM_D))/256; //
TL0=(65536-(TIME-PWM_D))%256;
PWMOUT=0;
}
}
|