电子开发网

电子开发网电子设计 | 电子开发网Rss 2.0 会员中心 会员注册
搜索: 您现在的位置: 电子开发网 >> 电子开发 >> 单片机 >> 正文

基于51单片机的恒温控制器系统 protues+keil c

作者:佚名    文章来源:网友    点击数:    更新时间:2023/5/21

恒温控制器系统概述

该恒温控制器系统包含以下几个功能:

  • 可按键设定温度
  • 可显示当前温度和用户设定温度
  • 有升温、降温模块
  • 可最终达到恒温

仿真软件

  • Keil 5
  • Proteus 8.6

系统设计

电路设计

 
恒温控制系统一共有6个模块,分别是主控芯片模块、按键输入模块、设定温度显示模块、当前温度显示模块、温度采集模块和升温、降温模块。

  1. 按键输入模块:该模块由4*3的矩阵键盘和1个确认按钮构成。系统刚开始启动后,用户通过矩阵键盘输入想要设定的温度(0°~99°),输入完毕后按下确认键,然后将该温度数据传送给主控芯片AT89C51;
  2. 设定温度显示模块:该模块由一个2位8段LED数码管构成,主控芯片AT89C51使用P3口控制该数码管的段选,使用P2.4和P2.5两个端口来控制该数码管的位选。主控芯片AT89C51将从矩阵键盘得到的设定温度信息,通过2位8段LED数码管显示出来;
  3. 温度采集模块;该模块由一个DS18B20温度传感器构成。使用DS18B20温度传感器采集当前的温度,并将该温度信息传送给主控芯片AT89C51;
  4. 当前温度显示模块:该模块由两个74HC573锁存器和一个4位8段LED数码管构成,主控芯片AT89C51使用P2.6和P2.7控制两个74HC573锁存器的片选,两个锁存器的输入口均与主控芯片的P0口相连,并使用一个100欧的排阻作为P0口的上拉电阻,两个锁存器的输出口分别与4位8段LED数码管的段选口与位选口相连;
  5. 升温、降温模块:该模块由一个绿色LED和一个红色LED构成,绿色LED负责降温,每闪烁一次温度下降0.5°,红色LED负责升温,每闪烁一次温度上升0.5°。主控芯片AT89C51根据当前温度和用户设定温度之间的差值,来控制升温还是降温,以达到恒温的目的。

软件代码编写

 

51单片机恒温控制系统程序流程图  

程序的具体流程如下:

  1. 硬件初始化,关闭所有的数码管;
  2. 进行两次按键扫描循环,分别获取用户设定温度的十位和个位,获取完毕后,判断确认键是否被按下,如果用户按下确认键则进入到主程序循环中;
 while(ok) //用户设定温度
 {
  while(key1 == 15)
  {
   key1 = keyscan();
   delay(50);
  }
  while(key2 == 15)
  {
   key2 = keyscan();
   delay(50);
  }
  delay(100);//等待确认键
 }
//键盘扫描
uchar keyscan()
{
 uchar temp,key;
 key = 15; // 默认值,如果没有按键按下key就为该默认值
 P1 = 0xfe; //扫描第一行
 temp = P1;
 temp = temp & 0xf0;
 if(temp!=0xf0)
 {
  delay(10); // 延时消抖
  temp = P1;
  temp = temp & 0xf0;
  if(temp!=0xf0) 
  {
   temp = P1;
   switch(temp) //扫描列
   {
    case 0xee:
     key = 1;
     break;
    case 0xde:
     key = 2;
     break;
    case 0xbe:
     key = 3;
     break;
   }
   while(temp!=0xf0) //等待按键释放
   {
    temp = P1;
    temp = temp & 0xf0;
   }
  }
 }
 P1 = 0xfd; //扫描第二行
 temp = P1;
 temp = temp & 0xf0;
 if(temp!=0xf0)
 {
  delay(10); // 延时消抖
  temp = P1;
  temp = temp & 0xf0;
  if(temp!=0xf0)
  {
   temp = P1;
   switch(temp) //扫描列
   {
    case 0xed:
     key = 4;
     break;
    case 0xdd:
     key = 5;
     break;
    case 0xbd:
     key = 6;
     break;
   }
   while(temp!=0xf0) //等待按键释放
   {
    temp = P1;
    temp = temp & 0xf0;
   }
  }
 }
 P1 = 0xfb; //扫描第三行
 temp = P1;
 temp = temp & 0xf0;
 if(temp!=0xf0)
 {
  delay(10); // 延时消抖
  temp = P1;
  temp = temp & 0xf0;
  if(temp!=0xf0)
  {
   temp = P1;
   switch(temp) //扫描列
   {
    case 0xeb:
     key = 7;
     break;
    case 0xdb:
     key = 8;
     break;
    case 0xbb:
     key = 9;
     break;
   }
   while(temp!=0xf0) //等待按键释放
   {
    temp = P1;
    temp = temp & 0xf0;
   }
  }
 }
 P1 = 0xf7; //扫描第四行
 temp = P1;
 temp = temp & 0xf0;
 if(temp!=0xf0)
 {
  delay(10); // 延时消抖
  temp = P1;
  temp = temp & 0xf0;
  if(temp!=0xf0)
  {
   temp = P1;
   switch(temp) //扫描列
   {
    case 0xe7:
     key = 0;
     break;
    case 0xd7:
     key = 0;
     break;
    case 0xb7:
     key = 0;
     break;
   }
   while(temp!=0xf0) //等待按键释放
   {
    temp = P1;
    temp = temp & 0xf0;
   }
  }
 }
 return key;
}
  1. 在主程序循环中,首先调用dis_set()函数显示用户设定温度;
for(i=20;i>0;i--) 
 dis_set(key1, key2); //显示用户设定的温度
//显示设定温度函数
void dis_set(uchar k1, uchar k2)
{
  display2(1, k1);
  display2(2, k2);
  display2(0, k1);
}
//设定温度数据显示函数
void display2(uchar num, uchar tem_data)
{
 if(num==0)
 {
  S1 = 1;
  S2 = 1;
  delay(5);
 }
 if(num==1)
 {
  S1 = 0;
  S2 = 1;
  P3 = table[tem_data]; //table为 0-9的16进制编码表
  delay(5);
 }
 else if(num==2)
 {
  S1 = 1;
  S2 = 0;
  P3 = table[tem_data];
  delay(5);
 }
}

然后再从温度传感器获取当前温度,获取当前温度的流程如下图所示,先调用DSreset()函数进行温度传感器的初始化,再调用temwrite()函数,对传感器写入温度转换的指令,进行温度获取和转换,然后调用get_tem()函数对传感器写入读取寄存器指令,从寄存器中读取存储的温度数据,并对该数据进行精度转换处理,最后获得一个保留了1位小数的当前温度数据;

 

temchange();    //获取当前温度
//温度获取和转换函数
void temchange(void)
{
 DSreset();
 delay(1);
 temwrite(0xcc); //写跳过ROM指令
 temwrite(0x44); //写温度转换指令
} 
//读取寄存器中存储的温度数据
uint get_tem(void)
{
 uchar l8,h8;
 DSreset();
 delay(1);
 temwrite(0xcc); //写跳过ROM指令
 temwrite(0xbe); //写读寄存器指令
 l8 = temread(); //读低8位数据
 h8 = temread(); //读高8位数据
 tem = h8;
 tem = tem<<8;
 tem = tem|l8; //合成一个16位数据
 f_tem = tem*0.0625;
 tem = f_tem*10+0.5; //*10用于保留1位小数点,+0.5用于四舍五入
 return (tem);
}

DS18B20温度传感器的基本操作代码如下,各项操作要严格遵守DS18B20温度传感器的时序图,延时时间要足够,可以根据使用的主控芯片适当地修改循环的次数来调整延时。

初始化

//温度传感器初始化
uint DSreset(void)
{
 uint i;
 DS = 0;
 i = 73;
 while(i>0)
  i--;
 DS = 1;
 i = 0;
 while(DS) 
 {//等待DS18B20拉低总线
  delay(1);
  i++;
  if(i>10)
  {
   return 0;//初始化失败
  }
 }
 DS = 1;
 return 1;//初始化成功
}

读1位数据

//读1位数据
bit temreadbit(void)
{
 uint i;
 bit tem_bitdata;
 DS = 0;
 i++; //延时
 DS = 1;
 i++;
 i++;
 tem_bitdata = DS;
 i = 10;
 while(i>0)
  i--;
 return(tem_bitdata);
}

读1字节数据

//读1字节数据
uchar temread(void)
{
 uint i;
 uchar j,tem_data;
 for(i=1;i<=8;i++)
 {
  j = temreadbit();
  tem_data = (j<<7)|(tem_data>>1); //移位,让最低位在最后面
 }
 return (tem_data);
}

写1字节数据

//写1字节数据
void temwrite(uchar tem_data)
{
 uint i;
 uchar j;
 bit send_bitdata;
 for(j=1;j<=8;j++)
 {
  send_bitdata = tem_data&0x01; //取要发送数据的最低位
  tem_data = tem_data>>1; //右移一位
  if(send_bitdata) //写1
  {
   DS = 0;
   i++;
   i++;
   DS = 1;
   i = 10;
   while(i>0)
    i--;
  }
  else     //写0
  {
   DS = 0;
   i = 10;
   while(i>0)
    i--;
   DS = 1;
   i++;
   i++;
  }
 }
}
  1. 获取完当前温度,调用dis_tem()函数显示当前温度;
for(i=20;i>0;i--)  //显示当前温度
 dis_tem(get_tem());
//显示当前温度函数
void dis_tem(uint t)
{
 uchar i;
 i = t/100; //取温度的十位
 display1(1,i);
 i = t%100/10; //取温度的个位
 display1(2,i+10);
 i = t%10; //取温度的小数点后一位
 display1(3,i);
}
//当前温度数据显示函数
void display1(uchar num, uchar tem_data)
{
 WE = 1; //选位,低电平有效
 P0 = ~((0x01)<<(num));
 WE = 0;
 DU = 1; //选段,高电平有效
 P0 = table[tem_data];
 DU = 0;
 delay(10);
}
  1. 将当前温度和用户设定温度传入deal()函数,进行恒温控制,在恒温控制函数deal()中,根据判断当前温度和用户设定温度之间的差值进行不同的处理,如果当前温度小于用户设定温度,就进行升温处理,即红灯闪烁一次,每闪烁一次温度上升0.5°,如果当前温度大于用户设定温度,就进行降温处理,即绿灯闪烁一次,每闪烁一次温度下降0.5°,如果当前温度与用户设定温度想等,则不做处理,只显示温度;
void deal(uint t, uint t_set)
{
 uchar i;
 if(tt_set)
 {
  work(15, 0x40); //降温
 }
 else
 {
  i = 15;
  while(i--)
   {
    dis_tem(tem_set);
    dis_set(key1, key2);
   }
 }
}
//升温、降温模块
void work(uint s, uchar led)
{
 uchar i;
 if(led==0x20)
 {
  i = s;
  led0 = ~(led0); //灯亮
  tem = tem+5;
  while(i--)
  {
   dis_tem(tem);
   dis_set(key1, key2);
  }
  led0 = ~(led0); //灯灭
  i = s;
  while(i--)
  {
   dis_tem(tem);
   dis_set(key1, key2);
  }
 }
 else
 {
  i = s;
  led1 = ~(led1); //灯亮
  tem = tem-5;
  while(i--)
  {
   dis_tem(tem);
   dis_set(key1, key2);
  }
  led1 = ~(led1); //灯灭
  i = s;
  while(i--)
  {
   dis_tem(tem);
   dis_set(key1, key2);
  }
 }
}
  1. 进行一次恒温控制后,系统又回到主程序循环的起始点,不断重复上述3-5步骤,使温度保持在用户设定的温度,达到恒温的效果。

代码下载 51单片机恒温控制系统C语言程序代码

Tags:51单片机,恒温控制,C语言,proteus  
责任编辑:admin
  • 上一篇文章:
  • 下一篇文章: 没有了
  • 相关文章列表
    51单片机数码管显示程序, 共阴数码管显示程序 数码管原理(显示
    单片机C语言编程入门教程  流水灯程序示例
    51单片机学习笔记直流电机驱动(PWM)C语言程序
    MCU-51单片机直流电机驱动(PWM)51单片机驱动直流电机
    先学51还是先学STM32?STM32和51单片机的区别
    51单片机和STM32单片机的结构有什么不同
    51单片机、AVR单片机和PIC单片机的IO口操作
    关于51单片机IO引脚的驱动能力与上拉电阻
    51单片机“呼吸灯”程序
    51单片机入门之静态数码管电路设计
    稳定可靠的恒温控制装置,TWH8751 Temperature controller
    AT89C51,51单片机1602液晶显示时钟程序
    单片机电子时钟程序设计
    4位单片机数字钟 电子钟制作
    51单片机4位数码管电子钟源程序
    AT89C2051电脑机箱风扇智能温控仪,AT89C2051 Temperature contro
    51单片机温控风扇(含程序+原理图+仿真+PCB)
    89C52来做定时记数器程序,51定时程序
    单片机C语言程序设计:用 ADC0808 控制PWM 输出
    51单片机蜂鸣器播放音乐代码
    利用单片机AT89S51与ADC0809设计数字电压表,Voltmeter
    单片机制作的纯正弦波逆变器,12V Pure Sine Wave Inverter
    51单片机00-59秒计时器 0-59s Timer
    51单片机按键程序中 while(!key)的作用
    51系列单片机寻址方式
    认识单片机引脚【详解】
    数码管显示矩阵键盘扫描值
    用51单片机设计的无线防盗报警器技术
    51单片机产生“嘀、嘀、……”报警声
    51单片机汇编模拟串口通信程序
    请文明参与讨论,禁止漫骂攻击,不要恶意评论、违禁词语。 昵称:
    1分 2分 3分 4分 5分

    还可以输入 200 个字
    [ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 在线帮助 - 文章列表
    返回顶部
    刷新页面
    下到页底
    晶体管查询