找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5500|回复: 4
收起左侧

51单片机电加热炉温度控制系统程序设计

[复制链接]
ID:541094 发表于 2019-5-18 10:08 | 显示全部楼层 |阅读模式
基于89cC51温度控制系统
含显示屏
以下为源程序和仿真
#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#include<DS18B20.h>
#define uchar unsigned char
#define uint unsigned int
#define BUSY 0x80            //1cd忙检測标志
#define DATAPORT P0          //定义P0口为LCD通讯端口
#define PLAYE_ADDR XBYTE[0XBFFF]     //语音报警地址
sbit RED_ALARM=P1^0;          //红色指示灯
sbit WRITE_ALARM=P1^1;        // 白色指示灯
sbit GREEN_ALARM=P1^2;        //绿色指示灯
sbit BLUE_ALARM = P1^3;
sbit P1_4 = P1^4;        //时钟调整
sbit P1_5 = P1^5;        //时钟加
sbit P1_6=P1^6;          //时钟减
sbit DQ=P1^7;            //定义ds18b20通信端口
sbit LCM_RS=P2^0;        //数据/命令端
sbit LCM_RW=P2^1;        //读/写选择端
sbit LCM_EN=P2^2;
sbit sda=P2^3;          //I0口定义
sbit scl=P2^4;          //LCD使能信号
sbit ad_busy=P3^2;      //adc中断方式接口
sbit RECLED_EOC=P3^5;   //ISD1420放音结東查询标志
sbit OUT=P3^7;

uchar ad_data;        //ad采样值存储
uchar seconde;        //定义并初始化时钟变量
uchar minite;
uchar hour;
uchar mstcnt=0;
uchar temp1,temp2,temp;   //温度显示变量
uchar t,set;
uchar K;
bit ON_OFF=0;
bit outflag;
bit write=0;
uchar code str0[]={"---  :  :  ---  "};
uchar code str1[]={"SET:  C SA:  . C"};
void delay_LCM(uint);   //LCD延时子程序
void initLCM( void);     //LCD初始化子程序
void lcd_wait(void);    //LCD检测忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC);//写指令到1CM子函数
void WriteDataLCM(uchar WDLCM);  //写数据到1CM子函数
void DisplayOneChar(uchar X,uchar Y,uchar DData);//显示指定坐标的一个字符子函数
void DisplayListChar(uchar X,uchar Y,uchar code *DData);//显示指定坐标的串字符子函数
void init_timer0(void);        //定时器初始化
void displayfun1(void);
void displayfun2(void);
void displayfun3(void);
void displayfun4(void);
void keyscan(void );           //键盘扫描子程序
void set_adj(void);
void inc_key(void);
void dec_key(void);
void delay_18B20(unsigned int i);
void Init_DS18B20(void);
uchar ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void ReadTemperature(void);
void ad0809(void);
void playalarm(void);

//**********延时K*1ms,12.000mhz*******/
void delay_LCM(uint k)
{
        uint i,j;
        for(i=0; i<k; i++)
        {
        for(j=0;j<60;j++)
        {;}
        }
}
//*****写指令到LCM子函数********//
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
        if(BusyC)lcd_wait();
        DATAPORT=WCLCM;
        LCM_RS=0;         //选中指令寄存器
        LCM_RW=0;        //写模式
        LCM_EN=1;
        _nop_();
        _nop_();
        _nop_();
        LCM_EN=0;
}
//*****写数据到LCM子函数********//
void WriteDataLcm(uchar WDLCM)
{
        lcd_wait( );          //检测忙信号
        DATAPORT=WDLCM;
        LCM_RS=1;           //选中数据寄存器
        LCM_RW=0;           //写模式
        LCM_EN = 1;
        _nop_();
        _nop_();
        _nop_();
        LCM_EN=0;
}
//*******1cm内部等待函数********/
void lcd_wait(void)
{
        DATAPORT=0xff;
        LCM_EN=1;
        LCM_RS=0;
        LCM_RW=1;
        _nop_();
        while(DATAPORT&BUSY)
        {
                LCM_EN=0;
                _nop_();
                _nop_();
                LCM_EN=1;
                _nop_();
                _nop_();
        }
        LCM_EN=0;
}
//*******LCM初始化子函数*******/
void initLCM( )
{
        DATAPORT=0;
        delay_LCM(15);
        WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
        delay_LCM(5);
        WriteCommandLCM(0x38,0);
        delay_LCM(5);
        WriteCommandLCM(0x38,0);
        delay_LCM(5);
        WriteCommandLCM(0x38,1);//8bit数据传送,2行显示,5*7字型,检测忙信号
        WriteCommandLCM(0x08,1);//关闭显示,检测忙信号
        WriteCommandLCM(0x01,1);//清屏,检測忙信号
        WriteCommandLCM(0x06,1);//显示光标右移设置,检测忙信号
        WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号
}
//****常显示指定坐标的一个字符子函数******//
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
        Y &= 1;
        X &= 15;
        if(Y)X|=0x40;   //若y为1(显示第二行),地址码+0X40
        X|=0x80;       //指令码为地址码+0X80
        WriteCommandLCM(X,0);
        WriteDataLCM(DData);
}
//****显示指定坐标的一串字符子函数*****//
void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
        uchar ListLength = 0;
        Y &= 0x01;
        X &= 0x0f;
        while(X < 16)
        {
                DisplayOneChar(X,Y,DData[ListLength]);
                ListLength++;
                X++;
        }
}
//*****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&0x0l;
                delay_18B20(5);
                DQ = 1;
                dat >>= 1;
        }
}
//****读取ds18b20当前温度*****/
void ReadTemperature(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();     //读取温度值高位
        temp1 = b<<4;
        temp1 += (a&0xf0)>>4;
        temp2 = a&0x0f;
        temp =((b*256+a)>>4);//当前采集温度值除16得实际温度值
}
//****液品显示子函数1正常显示*****//
void displayfun1(void)
{
        WriteCommandLCM(0x0c,1);         //显示屏打开,光标不显示,不闪烁,检测忙信号
        
        DisplayListChar(0,0,str0);
        DisplayListChar(0,1,str1);

        DisplayOneChar(3,0,hour/10+0x30);//液晶上显示小时
        DisplayOneChar(4,0,hour%10+0x30);

        DisplayOneChar(6,0,minite/10+0x30),//液晶上显示分
        DisplayOneChar(7,0,minite%10+0x30);

        DisplayOneChar(9,0,seconde/10+0x30);//液晶上显示秒
        DisplayOneChar(10,0,seconde%10+0x30);

        DisplayOneChar(4,1,K/10+0x30);     //液品上显示设定的温度
        DisplayOneChar(5,1,K%10+0x30);

        DisplayOneChar(11,1,temp1/10+0x30);//液晶上显示测得的温度
        DisplayOneChar(12,1,temp1%10+0x30);
        DisplayOneChar(14,1,temp2/10+0x30);
        if(ON_OFF == 0)         //若温控标志为0
        {
                DisplayOneChar(14,0,0x4f);  //液晶上显示不控温的标志
                DisplayOneChar(15,0,0x46);
        }
        else
        {
                        DisplayOneChar(14,0,0x4f);   //液晶上显示控温的标志
                        DisplayOneChar(15,0,0x4e);
                        if(outflag == 1)
                                DisplayOneChar(0,0,0x7c);
                        else
                                DisplayOneChar(0,0,0xef);
        }
}
//*****液晶最示子函数2*****//
void displayfun2(void)
{
        WriteCommandLCM(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检測忙信号

        DisplayListChar(0,0,str0);
        DisplayListChar(0,1,str1);
        
        DisplayOneChar(6,0,minite/10+0x30);
        DisplayOneChar(7,0,minite%10+0x30);
        
        DisplayOneChar(9,0,seconde/10+0x30);
        DisplayOneChar(10,0,seconde%10+0x30);
        
        DisplayOneChar(4,1,K/10+0x30);
        DisplayOneChar(5,1,K%10+0x30);
        
        DisplayOneChar(11,1,temp1/10+0x30);
        DisplayOneChar(12,1,temp1%10+0x30);
        DisplayOneChar(14,1,temp2/10+0x30);

        WriteCommandLCM(0x0f,1);    //显示打开,光标显示,闪烁,检测忙信号
        DisplayOneChar(3,0,hour/10+0x30);
        DisplayOneChar(4,0,hour%10+0x30);
}
//*****液晶显示子函数3****//
void displayfun3(void)
{
        WriteCommandLCM(0x0c,1);   //显示屏打开,光标不显示,不闪烁,检测忙信号
        DisplayListChar(0,0,str0);
        DisplayListChar(0,1,str1);
        
        DisplayOneChar(3,0,hour/10+0x30);
        DisplayOneChar(4,0,hour%10+0x30);
        
        DisplayOneChar(9,0,seconde/10+0x30);
        DisplayOneChar (10,0,seconde%10+0x30);

        DisplayOneChar(4,1,K/10+0x30);
        DisplayOneChar(5,1,K%10+0x30);

        DisplayOneChar(11,1,temp1/10+0x30);
        DisplayOneChar(12,1,temp1%10+0x30);
        DisplayOneChar(14,1,temp2/10+0x30);

        WriteCommandLCM(0x0f,1);//显示屏打开,光标显示,闪烁,检测忙信号
        DisplayOneChar(6,0,minite/10+0x30);
        DisplayOneChar(7,0,minite%10+0x30);
}
//*****液晶显示子函数4******//
void displayfun4(void)
{
        WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号
        
        DisplayListChar(0,0,str0);
        DisplayListChar(0,1,str1);
        
        DisplayOneChar(3,0,hour/10+0x30);
        DisplayOneChar(4,0,hour%10+0x30);
        
        DisplayOneChar(6,0,minite/10+0x30);
        DisplayOneChar(7,0,minite%10+0x30);
        
        DisplayOneChar(9,0,seconde/10+0x30);
        DisplayOneChar(10,0,seconde%10+0x30);
        
        DisplayOneChar(11,1,temp1/10+0x30);
        DisplayOneChar(12,1,temp1%10+0x30);
        DisplayOneChar(14,1,temp2/10+0x30);
        
        WriteCommandLCM(0x0f,1);//显示屏打开,光标显示,闪烁,检测忙信号
        DisplayOneChar(4,1,K/10+0x30);
        DisplayOneChar(5,1,K%10+0x30);
}
//*****键盘扫描子函数*****//
void keyscan(void)
{
        uchar xx;        //局部变量
        P1 = 0xff;
        if( P1 != 0xff)
        {
                delay_LCM(50);
                if(P1 != 0xff)
                {
                        xx = P1;
                        switch (xx)   //根据按键状态,调用不同的子函数
                        {
                                case 0xfe:set_adj();
                                break;
                                case 0xfd:inc_key();
                                break;
                                case 0xfb:dec_key();
                                break;
                                case 0xf7:{delay_LCM(150);ON_OFF=!ON_OFF;while(!BLUE_ALARM);}
                                 break;
                                default: break;
                        }
                }
        }
}

//*****设定工作模式子函数*****//
void set_adj(void)
{
        delay_LCM(100);
        set++;
        if(set >= 4)set = 0;
        while(!RED_ALARM);
}
//*****按键加法子函数******//
void inc_key(void)
{
        delay_LCM(150);
        switch(set)
        {
                case 0: if(P1 == 0xf7)
                          {delay_LCM(150);ON_OFF = !ON_OFF;}
                break;
                case 1: hour++; if(hour >= 23)hour = 23;
                break;
                case 2: minite++; if(minite >= 59)minite = 59;
                break;
                case 3:K++;if(K >= 99)K = 99;
                break;
                default: break;
        }
        while(!WRITE_ALARM);
}
//*****按键减法子函数******//
void dec_key(void)
{
        delay_LCM(150);
        switch(set)
        {
                case 0:if(P1 == 0xf7)
                         {delay_LCM(150);ON_OFF=!ON_OFF;}
                break;
                case 1:hour--;
                if(hour <= 0)hour = 0;
                break;
                case 2: minite--;
                if(minite <= 0)minite = 0;
                break;
                case 3: K--; if(K <= 1)K = 1;
                break;
                default: break;
        }
        while(!GREEN_ALARM);
}
//******24C02读写驱动程序*****//
void delay1(uchar x)
{
        uint i;
        for(i = 0;i < x;i++);
}
void flash()
        {  ;  ; }
void x24c02_init()//24c02初始化子程序
{
        scl = 1;
        flash();
        sda = 1;
        flash();
}
void start()     //启动I2C总线
{
        sda = 1;
        flash();
        scl = 1;
        flash();
        sda = 0;
        flash();
        scl = 0;
        flash();
}
void stop()     //停止I2C总线
{
        sda = 0;
        flash();
        scl = 1;
        flash();
        sda = 1;
        flash();
}
void writex(uchar j)//写一个字节
{
        uchar i,temp;
        temp = j;
        for (i = 0; i < 8; i++)
        {
                temp = temp<<1;
                scl = 0;
                flash();
                sda = CY;
                flash();
                scl = 1;
                flash();
        }
        scl = 0;
        flash();
        sda = 1;
        flash();
}
uchar readx()//读一个字节
{
        uchar i,j,k = 0;
        scl = 0;
        flash();
        sda = 1;         
        for(i = 0;i < 8;i++)
        {
                flash();
                scl = 1;
                flash();
                if(sda == 1)j = 1;
                else j = 0;
                k = (k<<1)|j;
                scl = 0;
        }
        flash();
        return(k);
}
void clock()     //I2C总线时钟
{
        uchar i = 0;
        scl = 1,
        flash();
        while((sda == 1)&&(i<255))i++;
        scl = 0;
        flash();
}
//////从24c02的地址 address中读取一个字节数据////
uchar x24c02_read(uchar address)
{
        uchar i;
        start();
        writex(0xa0);
        clock();
        writex(address);
        clock();
        start();
        writex(0xa1);
        clock();
        i = readx();
        stop();
        delay1(10);
        return (i);
}
////向24c02的address地址中写入一字节数据info////
void x24c02_write(uchar address,uchar info)
{
        EA = 0;
        start();
        writex(0xa0);
        clock();
        writex(address);
        clock();
        writex(info);
        clock();
        stop();
        EA = 1;
        delay1(50);
}
//*****定时器t0初始化*****//
void init_timer0(void)
{
        TMOD = 0x01;   //time0为定时器,方式1
        TH0 = 0x3c;           //于预置计数初值
        TL0 = 0xb0;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
}
//*****定时器t0中断子函数*****//
void timer0(void) interrupt 1 using 0          //定时器0方式1,50ms中断一次
{
        TH0 = 0x3c;
        TL0 = 0xb0;
        mstcnt++;
        if(mstcnt >= 20 )
           {seconde++;write = 1; mstcnt = 0;}
        if(seconde >= 60)
           {minite++; seconde = 0;}
        if(minite >= 60 )
           {hour++; minite = 0;}
        if(hour >= 24 )
           {hour = 0;}
        keyscan( );           //按键扫描
}
//******the main funtion******/

电加热炉温度控制系统设计.zip

187.21 KB, 下载次数: 140, 下载积分: 黑币 -5

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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