硬汉嵌入式论坛

 找回密码
 立即注册
查看: 231|回复: 0
收起左侧

[客户分享] 基于单片机鱼缸定时喂食彩灯控制系统

[复制链接]

27

主题

25

回帖

106

积分

初级会员

积分
106
发表于 2023-7-19 16:57:12 | 显示全部楼层 |阅读模式

一、系统方案
本设计采用AT89C52单片机主控器,液晶显示1602显示,按键设置定时时间,温度DS18B20传感器采集温度值,按键设置温度上下限,测量温度值低于下限,启动加热设备,温度值大于上限,启动降温设备,24路彩灯控制。
图片1.png
二、硬件设计
原理图如下:
图片2.png
三、单片机软件设计
1首先是定时器初始化:
/*************定时器0初始化程序***************/
void init_time0()          
{
        EA   = 1;                   //开总中断
        TMOD = 0X11;          //定时器0、工作方式1
        TH0 = (65536-10000)/256;  //重新加载初值
  TL0 = (65536-10000)%256;;
       
        ET0  = 1;                  //开定时器0中断
        TR0  = 1;                  //允许定时器0定时
}
2、中断服务程序
/**************定时器0中断程序*****************/
void time0() interrupt 1
{                         
        static uchar value;
       
  unsigned char tmp;  //临时变量
  static unsigned char index = 0;  //节拍输出索引
  unsigned char code BeatCode[8] = {  //步进电机节拍对应的IO控制代码
        0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
    };
       
  if (beats1 != 0)  //节拍数不为0则产生一个驱动节拍
    {
        tmp = P2;                    //tmpP2口当前值暂存
        tmp = tmp & 0xF0;            //&操作清零低4
        tmp = tmp | BeatCode[index]; //|操作把节拍代码写到低4
        P2  = tmp;                   //把低4位的节拍代码和高4位的原值送回P2
                if(mode1==0)
        index++;                     //节拍输出索引递增
                if(mode1==1)
        index--;                     //节拍输出索引递增
        index = index & 0x07;        //&操作实现到8归零
        beats1--;                     //总节拍数-1
    }
    else  //节拍数为0则关闭电机所有的相
    {
        P2 = P2 | 0x0F;               
    }
       
       
       
        TH0 = (65536-10000)/256;  //重新加载初值
  TL0 = (65536-10000)%256;;
       
        value ++;          
        if((value % 10) == 0)         //100ms  
                flag_100ms = 1;         
        if(value >=20)                         //200ms
        {
                value = 0;
                flag_200ms = 1;
        }
}
3、按键检测程序
void key()         //独立按键程序
{
        static uchar key_new;
        key_can = 20;                   //按键值还原
        P3 |= 0x78;                     //对应的按键IO口输出为1
        if((P3 & 0x78) != 0x78)                //按键按下
        {
                delay_1ms(10);                     //按键消抖动
                if(((P3 & 0x78) != 0x78) && (key_new == 1))
                {                                                //确认是按键按下
                        key_new = 0;
                        switch(P3 & 0x78)
                        {
                                case 0x70:  key_can = 4; //
                                if(menu_1==0)
                                {
          mode++;
                                        if(mode>2) mode=0;
                                        num=0;
                                }
                                break;         //得到按键值
                                case 0x68:  key_can = 3;  
                                if(menu_1==0)
                                {
                                                if(number==1)       
                                        led=!led;
                                }
                               
                               
                                break;         //得到按键值
                                case 0x58:  key_can = 2;
                                if(menu_1==0)
                                {
                                                if(number==1)       
                                        led1=!led1;
                                }
                                if(led1==0)
                                {
                    mode1=0;
                       
                 StartMotor1(360);
                                }
                                else
                               
                                {
                    mode1=1;
                       
                 StartMotor1(360);
                                }       
                               
                                break;         //得到按键值
                                case 0x38:  key_can = 1;  break;         //得到按键值
                        }
                }                       
        }
        else
                key_new = 1;       
}
4、温度检测程序
/*************读取温度的值 读出来的是小数***************/
uint read_temp()
{
        int value;
        uchar low;                           //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
        init_18b20();                   //初始化18b20
        write_18b20(0xcc);           //跳过64ROM
        write_18b20(0x44);           //启动一次温度转换命令
        delay_uint(50);                   //500us
        init_18b20();                   //初始化18b20
       
        write_18b20(0xcc);           //跳过64ROM
        write_18b20(0xbe);           //发出读取暂存器命令
       
        EA = 0;
        low = read_18b20();           //读温度低字节
        value = read_18b20();  //读温度高字节
        EA = 1;
        value <<= 8;                   //把温度的高位左移8
        value |= low;                   //把读出的温度低位放到value的低八位中
        if(value< 0)                                //当温度值为负数
  {
               
                fuhao=1;
                value=0;
        }
        else
        value *= 0.625;               //转换到温度值 小数
        return value;                   //返回读出的温度 带小数
}
四、proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
图片3.png

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 13:38 , Processed in 0.268197 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表