基于单片机的全自动供暖温度控制设计毕业论文
2022-07-18 22:20:50
论文总字数:4794字
附 录
附录1.原理图:
附录2.C语言程序:
#includelt;reg52.hgt;
sbit BELL=P3^0; //蜂鸣器
sbit KEY_SET=P2^7; //报警温度设置选择按键
sbit KEY_UP=P2^6; //设定值加1
sbit KEY_DOWN=P2^5; //设定值减1
sbit Valve=P3^1; //驱动继电器信号输出端,进而控制热水阀
sbit EOC=P3^3; //ADC0809转换结束标志
sbit CLOCK=P3^4; //89C52定时中断为ADC0809提供始终频率
sbit START=P3^5; //START与ALE引脚相连,在同一脉冲信号上各取所需
sbit OE=P3^6; //ADC0809输出使能端,OE=1:ADC0809允许输出转换的数字信号
sbit LED3=P2^3; //LED显示温度十位数字
sbit LED2=P2^2; //LED显示温度个位数字
sbit LED1=P2^1; //LED显示温度小数位数字
int m=0; //用于temp_caiji [m]
float s; //“用于去极值平均滤波”
int a; //“用于去极值平均滤波”
float temp_caiji [6]; //连续6次采集温度数据,用于“去极值平均滤波”
float temp=0; //经过“去极值平均滤波”处理得到的温度,赋初值0;
int flag=0; //报警值设置选择标志:根据所按次数决定进入哪个温度值设定程序
int temp_up_limit=25,temp_down_limit=20;//所需温度上下限设定值,初始值分别为25,20
int temp_up_alarm=40,temp_down_alarm=5;//报警温度上下限设定值,给出初始值40,5
char code_1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0xff}; //不带小数点的共阳数码管段码
char code_2[]={0x40,0x79,0x24,0x30,0x19,0x12,
0x02,0x78,0x00,0x10,0xff}; //带小数点的共阳数码管段码
/*延时函数*/
void delay(int x) //延时1毫秒
{
int i,j;
for(i=0;ilt;x;i )
for(j=0;jlt;120;j );
}
/*冒泡排序*/
void BubbleSort(void)
{ int i,j;
float m; //交换数据的中间寄存变量
for(i=0;ilt;5; i)
{
for(j=0;jlt;5-i; j)
{
if (temp_caiji [j]gt;temp_caiji [j 1])
{
m=temp_caiji [j 1];
temp_caiji [j 1]=temp_caiji [j];
temp_caiji [j]=m;
}
}
}
}
/*温度数据处理--去极值平均滤波*/
void data_process(void) //由于需采集6次,还要通过ADC,所以温度显示存在一定延时
{
BubbleSort();
s=0;
for(a=1;alt;=4;a )
{
s=s temp_caiji [a];
}
temp=s/4;
}
/*显示函数*/
void Wendu_display(void)
{
int x=temp; //强制数据类型转换,去除小数部分得到整数部分
float y=temp-x; //temp的小数部分
float y_=y*100;
int z=y_;
int z_=z/10;
LED1=1; //显示小数位数字
P1=0xff; //初始化LED数码管:全灭
P1=code_1[z_];
delay(10);
LED1=0;
LED2=1; //显示个位数字
P1=0xff;
P1=code_2[x];
delay(10);
LED2=0;
LED3=1; //显示十位数字
P1=0xff;
P1=code_1[x/10];
delay(10);
LED3=0;
}
/*进入键盘中断设置显示画面*/
void keyset_disp(int x) //按键中断设置界面,由于温度设定值都为整数,所以int x;
{
LED1=1; //显示小数位
P1=0xff; //初始化LED数码管:全灭
P1=0xc0; //小数位为0
delay(10);
LED1=0;
LED2=1; //显示个位
P1=0xff;
P1=code_2[x];
delay(10);
LED2=0;
LED3=1; //显示十位
P1=0xff;
P1=code_1[x/10];
delay(10);
LED3=0;
}
/*按键设置上、下限温度*/
void Int0(void) interrupt 0 //中断按键扫描
{
KEY_SET==1; //设置P2.7为输入口
KEY_UP==1; //设置P2.6为输入口
KEY_DOWN==1; //设置P2.5为输入口
if(KEY_SET==0)
{
delay(20); //按键去抖动
if(KEY_SET==0)
{
while(KEY_SET==0); //防止按键一直被按下没有松手
flag ; //根据按键被按下的次数来判断是设置上限还是下限温度
if(flag==5) flag=0; //按5次SET键退出按键设置,切换到正常室温显示画面
}
}
if(flag==1) //设置温度上限值;flag最为标记
{
delay(20);
if(KEY_UP==0)
{
while(KEY_UP==0); //防止按键一直被按下没有松手
temp_up_limit ;
}
if(KEY_DOWN==0)
{
while(KEY_DOWN==0);
temp_up_limit--;
}
while(KEY_SET==1 amp;amp; KEY_UP==1 amp;amp; KEY_DOWN==1)
keyset_disp(temp_up_limit); //显示上限设定值
}
if(flag==2) //设置温度下限值
{
delay(20);
if(KEY_UP==0)
{
while(KEY_UP==0); //防止按键一直被按下没有松手
temp_down_limit ;
}
if(KEY_DOWN==0)
{
while(KEY_DOWN==0);
temp_down_limit--;
}
while(KEY_SET==1 amp;amp; KEY_UP==1 amp;amp; KEY_DOWN==1)
keyset_disp(temp_down_limit); //显示下限设定值
}
if(flag==3) //设置报警上限值
{
delay(20);
if(KEY_UP==0)
{
while(KEY_UP==0);
temp_up_alarm ;
}
if(KEY_DOWN==0)
{
while(KEY_DOWN==0);
temp_up_alarm--;
}
while(KEY_SET==1 amp;amp; KEY_UP==1 amp;amp; KEY_DOWN==1)
keyset_disp(temp_up_alarm);
}
if(flag==4) //设置报警下限值
{
delay(20);
if(KEY_UP==0)
{
while(KEY_UP==0);
temp_down_alarm ;
}
if(KEY_DOWN==0)
{
while(KEY_DOWN==0);
temp_down_alarm--;
}
while(KEY_SET==1 amp;amp; KEY_UP==1 amp;amp; KEY_DOWN==1)
keyset_disp(temp_down_alarm);
}
}
/*T0中断服务(给ADC0809提供时钟信号)*/
void time0(void) interrupt 1
{
CLOCK=~CLOCK; //ADC0809内部无时钟,用89C52的T0来产生时钟信号
}
/*主函数*/
void main()
{
IE=0x83; //允许INT0、T0中断
TMOD=0x02; //设置定时器T0中断工作方式
TH0=0x14; //TH0=256-236=20=0x14
TL0=0x14;
TR0=1; //启动Time0
START=0; //初始化ADC
OE=0; //初始化ADC
while(1)
{
START=0;
START=1; //上升沿复位ADC0809内部SAR(逐次逼近寄存器)
START=0; //下降沿启动AD转换
while(EOC==0) ; //AD转换结束后才允许输出转换的数字信号
请支付后下载全文,论文总字数:4794字