#include <REG52.H>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit wireless_1 = P3^0;
sbit wireless_2 = P3^1;
sbit wireless_3 = P3^2;
sbit wireless_4 = P3^3;
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
void show_time(); //液晶显示程序
#define tim0 65536-1000
#define tim1 65536-20000
uchar tm=1,tx=0; //记数两个定时中断的
enum{Y,U,R,Ts,Kd,Kp};//Y采集量 U控制量 R 设定量 Ts 采样时间 Kd 微分 Kp比例
int para[6],ptr,out; //out 是从PID()得到的控制量
int wd,wd1,r,kp,kd,ts,e2,e1,e0,u; //wd 是从DS18B20采到的数据
bit dealCS=0;
sbit EN1=P2^2;
sbit IN1=P2^1;
sbit PWM=P2^0;
sbit DQ = P2^4; //温度传送数据IO口
char done,count,temp,flag,up_flag,down_flag;
uchar temp_value; //温度值
uchar TempBuffer[15], week_value[2];
uchar TempBuffer1[7];
uchar Ctrltab[20]={8,15,20,40,50,60,70,80,100,120,140,160,180,200};
char T=23;
char disp;
void show_time1(void);
void debouncer(void); //去键盘抖动延时函数
void shezhiwendu(void); //设定温度函数
void scanner(void);
void PID(); //键盘扫描函数
#define rowkey()(~P1)&0x0f //读取端口宏定义
/**************去抖动延时函数***************/
void debouncer(void)
{ int i;
for(i=0;i<2400;i++);
}
/*******************************************/
/**************设置温度函数***************/
void shezhiwendu(void)
{
while(1)
{
scanner();
show_time1();
if(disp==2) { T++; disp=0; }
if(disp==3) { T--; disp=0; }
if(disp==4) break;
}
}
/*******************************************/
/***********键盘扫描函数********************/
void scanner(void)
{ char col,row;
char scan,keyin;
scan=0xef;
for(col=0;col<4;col++)
{ P1=scan;
keyin=rowkey();
if(keyin!=0)
{ for(row=0;row<4;row++)
{ if(keyin==(0x01<<row))
{ disp=row+4*col;
break;
}
if(row==4)
disp=0;
}
while(rowkey());
debouncer();
}
scan=(scan<<1)|0x01;
}
}
/*****************************************************/
void initTimer0_Timer1() //初始化定时器0,定时器1
{
TMOD=0x01;
TH0=tim0>>8; TL0=tim0;
TR0=1;
ET0=1;
EA=1;
}
void initPID() //初始化PID函参数
{
para[Kp]=100;
para[Kd]=3;
para[Ts]=10;
}
void PID() //PID服务程序
{
TR0=0;
ET0=0;
EA=0; //检测的温度
//wd设定的温度
e0=e1;e1=e2;e2=wd-T;
kp=para[Kp]; kd=para[Kd]; ts=para[Ts];
u=wd+kp*(e2+kd*(e2-e1));
if(u<0) u=0;
if(u>500) u=500;
out=u/10; //控制量
TR0=1;
ET0=1;
EA=1;
}
void PWM_timer0() interrupt 1 //定时器0中断服务子程序
{
TH0=tim0>>8; TL0=tim0;
if(tm++>=out)
PWM=0; //通过变量out控制PWM脉冲宽度
else PWM=1;
if(tm>=50)
{
PID();
tm=1; //通过变量tm控制PWM的周期
}
}
/*
void timer1() interrupt 3 //定时器1中断服务子程序
{
TH1=tim1>>8; TL1=tim1;
if(dealCS==0) ///模糊控制
{
wdCtrl=para[R];
if((wdCtrl-wd/10)>10)out=0;
else if((wd/10-wdCtrl)>2)out=225;
else out=Ctrltab[wdCtrl+2-wd/10];
}
else if(tx++>=ts) //dealCS为1,选择的是PID();
{
tx=0;
}
} */
/***********1602液晶显示部分子程序****************/
sbit LcdRs = P2^5;
sbit LcdRw = P2^6;
sbit LcdEn = P2^7;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
LcdEn=0;
return DBPort;
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();//注意顺序
LcdEn=1; _nop_();//注意顺序
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化LCD************************************************************
void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}
//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
//将字符输出到液晶显示
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void)
{
unsigned char 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读一个字节**************/
unsigned char ReadOneChar(void)
{
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)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************读取ds18b20当前温度************/
void ReadTemp(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=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(); //读取温度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
}
void temp_to_str() //温度数据转换成液晶字符显示
{
TempBuffer[0]='t'; //十位
TempBuffer[1]='i'; //个位
TempBuffer[2]='m'; //温度符号
TempBuffer[3]='e';
TempBuffer[4]='0';
TempBuffer[5]=':';
TempBuffer[6]=temp_value/10+'0'; //十位
TempBuffer[7]=temp_value%10+'0'; //个位
TempBuffer[8]=0xdf; //温度符号
TempBuffer[9]='C';
TempBuffer[10]='\0';
}
void temp_to_str1() //温度数据转换成液晶字符显示
{
TempBuffer1[0]='t'; //十位
TempBuffer1[1]='1'; //十位
TempBuffer1[2]=':'; //十位
TempBuffer1[3]=T/10+'0';
TempBuffer1[4]=T%10+'0';
TempBuffer1[5]=0xdf
- 1
- 2
- 3
- 4
- 5
前往页