找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3425|回复: 7
收起左侧

Max的单片机PID温度控制第3.41版 源程序

[复制链接]
ID:423556 发表于 2019-12-4 15:22 | 显示全部楼层 |阅读模式
需要有个技术小结,为此做了一个PID温度控制器,要求入下:

1. 使用LCD1602显示:测量温度、设置温度、控制状态、输出量等。
2. 使用STC15W408AS单片机做为主控制系统。
3. 使用NTC电阻测量温度,经单片机取样后转换为温度显示。
4. 通过E,ADD,SUB三个输入按键修改设置温度、手动/自动、控制参数、输出量等。1秒为周期,输出PWM波控制MOS管调节发热板的温度


电路图:

电路图

电路图


主要使用指令:
指令1.jpg
指令2.jpg

程序流程图:
主函数.jpg 初始化函数.jpg 定时函数.jpg 温度函数.jpg
按键输入函数.jpg LCD输出函数.jpg PID控制函数.jpg

单片机函数:

/*
硬件说明:
1.使用STC15W408AS单片机,使用内部IRS时钟30MHz。
2.使用LCD1602显示,P2口输出8位并口数据,P3.2设置指令/数据,P3.3下降沿执行。
3.P1.1模拟量输入端,P1.3按键E,P1.4按键SUB,P1.5按键ADD。
4.P1.0PWM输出。

程序运行说明:
1.每1毫秒执行1次程序。
2.温度测量范围0--110度,精度1度。1000个温度平均1次,1秒更新1次温度值。
3.通过按键E激活或选择菜单,按键SUB和ADD修改参数,并具有保存设置参数到EEPROM功能。
   按键连续加减时每50毫秒加减1次,激活显示消影取消影项最后一个数值以10个输出为1周期,一半显示一半消影。
4.PWM以1000毫秒(1秒)为周期,最小1毫秒。
5.LCD每1毫秒执行1个指令或数据。

*/

#include<stc15w408as.h>//头文件

//主函数+初始化+计时--------------------------------------------------------------
void INIT();//初始化函数
void T_00();//计时函数
unsigned int T_1S;//1秒计时器

//NTC_01温度--------------------------------------------------------------
void NTC_01();//温度
unsigned int ADC_IN,NTC_PV;//模拟量,温度和缓存
unsigned long int PV_BUF;//温度累积值

//ADC数值40-790对应0-111度, NTC 10K 3950电阻10K取样电阻转换值
unsigned char code NTC_DATA[]={
0X6F,0X6F,0X6F,0X6F,0X6F,0X6F,0X6F,0X6F,0X6E,0X6E,0X6D,0X6C,0X6B,0X6B,0X6A,0X6A,0X69,0X68,0X68,0X67
,0X67,0X66,0X65,0X65,0X64,0X64,0X63,0X63,0X62,0X62,0X61,0X61,0X60,0X60,0X5F,0X5F,0X5E,0X5E,0X5D,0X5D
,0X5C,0X5C,0X5B,0X5C,0X5A,0X5A,0X5A,0X59,0X59,0X58,0X58,0X58,0X57,0X57,0X56,0X56,0X56,0X55,0X55,0X55
,0X54,0X54,0X54,0X53,0X53,0X53,0X52,0X52,0X52,0X51,0X51,0X51,0X50,0X50,0X50,0X4F,0X4F,0X4F,0X4F,0X4E
,0X4E,0X4E,0X4D,0X4D,0X4D,0X4D,0X4C,0X4C,0X4C,0X4C,0X4B,0X4B,0X4B,0X4B,0X4A,0X4A,0X4A,0X4A,0X49,0X49
,0X49,0X49,0X48,0X48,0X48,0X48,0X47,0X47,0X47,0X47,0X46,0X46,0X46,0X46,0X45,0X45,0X45,0X45,0X45,0X44
,0X44,0X44,0X44,0X43,0X43,0X43,0X43,0X43,0X43,0X42,0X42,0X42,0X42,0X42,0X41,0X41,0X41,0X41,0X40,0X40
,0X40,0X40,0X40,0X40,0X3F,0X3F,0X3F,0X3F,0X3F,0X3E,0X3E,0X3E,0X3E,0X3E,0X3E,0X3D,0X3D,0X3D,0X3D,0X3D
,0X3D,0X3C,0X3C,0X3C,0X3C,0X3C,0X3C,0X3B,0X3B,0X3B,0X3B,0X3B,0X3B,0X3B,0X3A,0X3A,0X3A,0X3A,0X3A,0X39
,0X39,0X39,0X39,0X39,0X39,0X39,0X38,0X38,0X38,0X38,0X38,0X38,0X37,0X37,0X37,0X37,0X37,0X37,0X37,0X36
,0X36,0X36,0X36,0X36,0X36,0X36,0X35,0X35,0X35,0X35,0X35,0X35,0X35,0X34,0X34,0X34,0X34,0X34,0X34,0X34
,0X33,0X33,0X33,0X33,0X33,0X33,0X33,0X32,0X32,0X32,0X32,0X32,0X32,0X32,0X32,0X31,0X31,0X31,0X31,0X31
,0X31,0X31,0X31,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X2F,0X2F,0X2F,0X2F,0X2F,0X2F,0X2F,0X2F,0X2E
,0X2E,0X2E,0X2E,0X2E,0X2E,0X2E,0X2E,0X2E,0X2D,0X2D,0X2D,0X2D,0X2D,0X2D,0X2D,0X2D,0X2C,0X2C,0X2C,0X2C
,0X2C,0X2C,0X2C,0X2C,0X2C,0X2B,0X2B,0X2B,0X2B,0X2B,0X2B,0X2B,0X2B,0X2A,0X2A,0X2A,0X2A,0X2A,0X2A,0X2A
,0X2A,0X2A,0X29,0X29,0X29,0X29,0X29,0X29,0X29,0X29,0X29,0X29,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28
,0X28,0X27,0X27,0X27,0X27,0X27,0X27,0X27,0X27,0X27,0X26,0X26,0X26,0X26,0X26,0X26,0X26,0X26,0X26,0X26
,0X25,0X25,0X25,0X25,0X25,0X25,0X25,0X25,0X25,0X25,0X24,0X24,0X24,0X24,0X24,0X24,0X24,0X24,0X24,0X24
,0X23,0X23,0X23,0X23,0X23,0X23,0X23,0X23,0X23,0X23,0X22,0X22,0X22,0X22,0X22,0X22,0X22,0X22,0X22,0X22
,0X21,0X21,0X21,0X21,0X21,0X21,0X21,0X21,0X21,0X21,0X21,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20,0X20
,0X20,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1F,0X1E,0X1E,0X1E,0X1E,0X1E,0X1E,0X1E,0X1E
,0X1E,0X1E,0X1E,0X1D,0X1D,0X1D,0X1D,0X1D,0X1D,0X1D,0X1D,0X1D,0X1D,0X1C,0X1C,0X1C,0X1C,0X1C,0X1C,0X1C
,0X1C,0X1C,0X1C,0X1C,0X1C,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1B,0X1A,0X1A,0X1A
,0X1A,0X1A,0X1A,0X1A,0X1A,0X1A,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19,0X19
,0X18,0X18,0X18,0X18,0X18,0X18,0X18,0X18,0X18,0X17,0X17,0X17,0X17,0X17,0X17,0X17,0X17,0X17,0X17,0X17
,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X16,0X15,0X15,0X15,0X15,0X15,0X15,0X15
,0X15,0X15,0X15,0X15,0X15,0X14,0X14,0X14,0X14,0X14,0X14,0X14,0X14,0X14,0X14,0X13,0X13,0X13,0X13,0X13
,0X13,0X13,0X13,0X13,0X13,0X13,0X13,0X12,0X12,0X12,0X12,0X12,0X12,0X12,0X12,0X12,0X12,0X11,0X11,0X11
,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10
,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0F,0X0E,0X0E,0X0E,0X0E,0X0E,0X0E,0X0E,0X0E
,0X0E,0X0E,0X0E,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0D,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C
,0X0C,0X0C,0X0C,0X0C,0X0C,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0B,0X0A,0X0A,0X0A,0X0A
,0X0A,0X0A,0X0A,0X0A,0X0A,0X0A,0X0A,0X09,0X09,0X09,0X09,0X09,0X09,0X09,0X09,0X09,0X09,0X09,0X08,0X08
,0X08,0X08,0X08,0X08,0X08,0X08,0X08,0X08,0X08,0X08,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07
,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X05,0X05,0X05,0X05,0X05,0X05,0X05,0X05,0X05,0X05
,0X04,0X04,0X04,0X04,0X04,0X04,0X04,0X04,0X04,0X04,0X03,0X03,0X03,0X03,0X03,0X03,0X03,0X03,0X03,0X03
,0X03,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X02,0X01,0X01,0X01,0X01,0X01,0X01,0X01,0X01,0X01,0X01
,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00};


//SW_02按键--------------------------------------------------------------
void SW_02();//按键
sbit SW_E=P1^3;//按键E
sbit SW_SUB=P1^4;//按键SUB
sbit SW_ADD=P1^5;//按键ADD
unsigned char SW_E_T,SW_SUB_T,SW_ADD_T;//按键计时器
unsigned char SW_M;//菜单激活激活计数器
unsigned int SW_M_T;//菜单激活计时器

//PID_03控制--------------------------------------------------------------
void PID_03();//控制
sbit PWM_OUT=P1^0;//PWM输出端口
unsigned char PID_PV,PID_SV,PID_MA,PID_P,PID_I;//设置计数器
unsigned char PID_V,PID_I_T;//温度差,积分计时器
int PID_OUT,PID_I_BUF;//输出计数器

//LCD_04显示--------------------------------------------------------------
void LCD_04();//显示
#define LCD_DATA P2 //8位并口
sbit LCD_RS=P3^2;//指令/数据设置
sbit LCD_E=P3^3;//下降沿执行
unsigned char LCD_C,LCD_ON;//计数器,消影计数器
unsigned char code LCD_INIT[]={0X38,0X06,0X0C,0X01};//8位,显示开,增量,清屏
unsigned char LCD_BUF[]="#PV:123 OUT:123.4#SV:123 M* P:12.3";//缓冲区
unsigned char LCD_CHAR[]="0123456789 MA*PI:.";//字符显示

//声明结束。。。。。。。。。。。。。。。。。。。。。。。。。。。。。



//主函数+初始化+计时--------------------------------------------------------------
void main()//主函数
{
        INIT();//初始化
        while(1)//循环指令
        {
                while(!TF0);//1毫秒溢出等待,复位溢出标记
                TF0=0;

                T_00();//T_00计时
                NTC_01();//NTC_01温度
                SW_02();//SW_02按键
                PID_03();//PID_03控制
                LCD_04();//LCD_04显示
        }
}
void INIT()//初始化函数
{
        //T0,12T/30M=0.4us;0.4*2500=1ms.
        AUXR&=0X80;//B7=1,T0=12T
        TMOD&=0XF0;//B3210=0;//内计数,计时器,16位自动重装
        TL0=(65536-2500)%256;//重装值低8位
        TH0=(65536-2500)/256;//重装值高8位
        TF0=0;//T0溢出标记复位
        TR0=1;//T0开始计时

        //ADC端口
        P1ASF=0X02;//P1.1设置位模拟量输入
        //读EEPROM
        IAP_CONTR=0X80;//允许IAP
        IAP_CMD=1;//读模式
        IAP_ADDRH=0X00;//EEPROM地址高8位
        IAP_ADDRL=0X00;//EEPROM地址低8位
        IAP_TRIG=0X5A;
        IAP_TRIG=0XA5;//执行指令
        while(0);//不循环,等待1个时钟
        PID_SV=IAP_DATA;//读SV

        IAP_ADDRL=0X01;//EEPROM地址低8位
        IAP_TRIG=0X5A;
        IAP_TRIG=0XA5;//执行指令
        while(0);//不循环,等待1个时钟
        PID_MA=IAP_DATA;//读MA

        IAP_ADDRL=0X02;//EEPROM地址低8位
        IAP_TRIG=0X5A;
        IAP_TRIG=0XA5;//执行指令
        while(0);//不循环,等待1个时钟
        PID_P=IAP_DATA;//读P

        IAP_ADDRL=0X03;//EEPROM地址低8位
        IAP_TRIG=0X5A;
        IAP_TRIG=0XA5;//执行指令
        while(0);//不循环,等待1个时钟
        PID_I=IAP_DATA;//读I

        IAP_CONTR=0;//关闭IAP
        IAP_CMD=0;//待机模式
        IAP_ADDRH=0XFF;//设置到非EEPROM地址
        IAP_ADDRL=0XFF;//设置到非EEPROM地址
        IAP_TRIG=0;//清除触发寄存器

        //LCD
        LCD_RS=0;//指令模式
        for(LCD_C=0;LCD_C<4;LCD_C++)//发送4个设置参数
        {
                LCD_DATA=LCD_INIT[LCD_C];//发送参数
                LCD_E=1;//执行准备
                LCD_E=0;//执行参数
                while(!TF0);//等待1毫秒溢出
                TF0=0;//溢出复位
        }
        LCD_C=0;//复位计数器
        LCD_BUF[0]=0X80;//缓冲区0是LCD第一行起始地址
        LCD_BUF[17]=0XC0;//缓冲区17是LCD第二行起始地址
}
void T_00()//计时函数
{
        //1秒循环计时
        T_1S++;//1毫秒加1
        if(T_1S>=1000)//计时满1000毫秒复位
                T_1S=0;        
}

//NTC_01温度--------------------------------------------------------------
void NTC_01()//温度
{
        //设置ADC端口读
        ADC_CONTR=0XE9;//启动ADC
        //读ADC数值
        ADC_IN=ADC_RES;//高8位
        ADC_IN=ADC_IN<<2;//左移2位
        ADC_IN+=ADC_RESL;//低2位
                //限制
        if(ADC_IN<40)
                ADC_IN=40;
        if(ADC_IN>790)
                ADC_IN=790;
        //ADC转温度
        NTC_PV=NTC_DATA[ADC_IN-40];
        //温度累积
        PV_BUF=PV_BUF+NTC_PV;
        //满1000个温度数据平均并复位
        if(T_1S==0)
        {
                PV_BUF=PV_BUF/1000;
                PID_PV=PV_BUF;
        }
}

//SW_02按键--------------------------------------------------------------
void SW_02()//按键
{
        //按键输入计时
        if(SW_E==0&SW_E_T<200)//按键有输入且计时器小于200毫秒计时器加1
                SW_E_T++;
        if(SW_E==1)//按键无输入
                SW_E_T=0;//计时器复位
        if(SW_SUB==0&SW_SUB_T<200)//按键有输入且计时器小于200毫秒计时器加1
                SW_SUB_T++;
        if(SW_SUB==1)//按键无输入
                SW_SUB_T=0;//计时器复位
        if(SW_ADD==0&SW_ADD_T<200)//按键有输入且计时器小于200毫秒计时器加1
                SW_ADD_T++;
        if(SW_ADD==1)//按键无输入
                SW_ADD_T=0;//计时器复位
        //按键E处理
        if(SW_M==0&SW_E_T==200)//菜单未激活且按键E有连续200毫秒输入
        {
                //计时器未满
                if(SW_M_T<3000)//计时加1
                        SW_M_T++;
                else//计时器已满
                {
                        SW_M=1;//激活菜单
                        SW_M_T=10000;//计数器置数
                }
        }
        if(SW_M>0)//菜单已激活操作
        {
                //菜单循环选择
                if(SW_E_T==10)//10毫秒防抖操作1次
                {
                        SW_M++;//菜单选择下1个
                        if(SW_M>5)//选择到I后回到OUT
                                SW_M=1;
                }
                //计数器到数
                SW_M_T--;//倒计时
                if(SW_E_T>10|SW_SUB_T>10|SW_ADD_T>10)//按键有输入
                        SW_M_T=10000;//计数器置数
                //计时器结束
                if(SW_M_T==0)
                {
                        SW_M=0;//关闭菜单

                        //保存设置到EEPROM
                                //差除扇区
                        IAP_CONTR=0X80;//允许IAP
                        IAP_CMD=3;//删除模式
                        IAP_ADDRH=0X00;//EEPROM地址高8位
                        IAP_ADDRL=0X00;//EEPROM地址低8位
                        IAP_TRIG=0X5A;
                        IAP_TRIG=0XA5;//执行指令
                        while(0);//不循环,等待1个时钟
                                //写入设置到EEPROM
                        IAP_CMD=2;//写模式
                        IAP_ADDRL=0X00;//EEPROM地址低8位
                        IAP_DATA=PID_SV;//写入SV
                        IAP_TRIG=0X5A;
                        IAP_TRIG=0XA5;//执行指令
                        while(0);//不循环,等待1个时钟

                        IAP_ADDRL=0X01;//EEPROM地址低8位
                        IAP_DATA=PID_MA;//写入MA
                        IAP_TRIG=0X5A;
                        IAP_TRIG=0XA5;//执行指令
                        while(0);//不循环,等待1个时钟

                        IAP_ADDRL=0X02;//EEPROM地址低8位
                        IAP_DATA=PID_P;//写入P
                        IAP_TRIG=0X5A;
                        IAP_TRIG=0XA5;//执行指令
                        while(0);//不循环,等待1个时钟

                        IAP_ADDRL=0X03;//EEPROM地址低8位
                        IAP_DATA=PID_I;//写入I
                        IAP_TRIG=0X5A;
                        IAP_TRIG=0XA5;//执行指令
                        while(0);//不循环,等待1个时钟

                        IAP_CONTR=0;//关闭IAP
                        IAP_CMD=0;//待机模式
                        IAP_ADDRH=0XFF;//设置到非EEPROM地址
                        IAP_ADDRL=0XFF;//设置到非EEPROM地址
                        IAP_TRIG=0;//清除触发寄存器
                }
        }

        //菜单激活1,OUT
        if(SW_M==1)
        {
                if(SW_SUB_T==10&PID_OUT>0)//防抖10毫秒后操作1次
                        PID_OUT--;//自减1
                if(SW_SUB_T==200&PID_OUT>0)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_OUT--;//自减1        
                        SW_SUB_T=150;//计数器置数
                }
                if(SW_ADD_T==10)//防抖10毫秒后操作1次
                        PID_OUT++;//自加1
                if(SW_ADD_T==200)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_OUT++;//自加1        
                        SW_ADD_T=150;//计数器置数
                }
                        //限制
                if(PID_OUT>1000)
                        PID_OUT=1000;
        }
        //菜单激活2,SV
        if(SW_M==2)
        {
                if(SW_SUB_T==10&PID_SV>0)//防抖10毫秒后操作1次
                        PID_SV--;//自减1
                if(SW_SUB_T==200&PID_SV>0)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_SV--;//自减1        
                        SW_SUB_T=150;//计数器置数
                }
                if(SW_ADD_T==10)//防抖10毫秒后操作1次
                        PID_SV++;//自加1
                if(SW_ADD_T==200)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_SV++;//自加1        
                        SW_ADD_T=150;//计数器置数
                }
                        //限制
                if(PID_SV>110)
                        PID_SV=110;
        }
        //菜单激活3,MA
        if(SW_M==3)
        {
                if(SW_SUB_T==10)//防抖10毫秒后操作1次
                        PID_MA=0;//手动
                if(SW_ADD_T==10)//防抖10毫秒后操作1次
                        PID_MA=1;//自动
                if(PID_MA>1)
                        PID_MA=1;
        }
        //菜单激活4,P
        if(SW_M==4)
        {
                if(SW_SUB_T==10&PID_P>0)//防抖10毫秒后操作1次
                        PID_P--;//自减1
                if(SW_SUB_T==200&PID_P>0)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_P--;//自减1        
                        SW_SUB_T=150;//计数器置数
                }
                if(SW_ADD_T==10)//防抖10毫秒后操作1次
                        PID_P++;//自加1
                if(SW_ADD_T==200)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_P++;//自加1        
                        SW_ADD_T=150;//计数器置数
                }
                        //限制
                if(PID_P>200)
                        PID_P=200;
        }
        //菜单激活5,I
        if(SW_M==5)
        {
                if(SW_SUB_T==10&PID_I>0)//防抖10毫秒后操作1次
                        PID_I--;//自减1
                if(SW_SUB_T==200&PID_I>0)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_I--;//自减1        
                        SW_SUB_T=150;//计数器置数
                }
                if(SW_ADD_T==10)//防抖10毫秒后操作1次
                        PID_I++;//自加1
                if(SW_ADD_T==200)//连续输入200毫秒后每50毫秒操作1次
                {
                        PID_I++;//自加1        
                        SW_ADD_T=150;//计数器置数
                }
                        //限制
                if(PID_I>200)
                        PID_I=200;
        }
}

//PID_03控制--------------------------------------------------------------
void PID_03()//按键
{
        //PID计算
        //自动模式且T_1S=0
        if(PID_MA>0&T_1S==0)//自动时且1秒计时开始时
        {
                if(PID_PV<PID_SV)//温度低
                {
                        PID_V=PID_SV-PID_PV;//计算温差
                        if(PID_V>3)//温度低超过3度
                                PID_OUT=PID_P*(PID_SV-PID_PV*9/10);//比例输出
                        else//温度低不超过3度
                        {
                                if(PID_I_T==0)//每5秒计算1次积分
                                        PID_OUT+=PID_I;//输出减少
                        }
                        //温度差越小调节时间越长
                        PID_I_T++;
                        PID_V=10-PID_V;
                        if(PID_I_T>=PID_V)//循环计时
                                PID_I_T=0;
                }

                if(PID_PV>PID_SV)//温度高
                {
                        PID_V=PID_PV-PID_SV;//计算温差
                        if(PID_V>5)//温度低超过5度
                                PID_OUT-=PID_I;//输出减少
                        else//温度低不超过3度
                        {
                                if(PID_I_T==0)
                                        PID_OUT-=PID_I;//输出减少
                        }
                        //温度差越小调节时间越长
                        PID_I_T++;
                        PID_V=10-PID_V;
                        if(PID_I_T>=PID_V)//循环计时
                                PID_I_T=0;
                }
                //积分计时器复位
                if(PID_PV==PID_SV)//温度相等
                        PID_I_T=0;//积分计时器复位
        }
        //PWM输出
                //输出限制
        if(PID_OUT>1000)//输出最大1000(显示100.0)
                PID_OUT=1000;
        if(PID_OUT<0)//输出最小0(显示000.0)
                PID_OUT=0;
        if(PID_PV>105|PID_PV==0)//温度超过105度或温度测量0度(0度一般是NTC电阻开路)时输出为0
                PID_OUT=0;
                //PWM输出处理
        if(T_1S>=PID_OUT)//转1秒周期的PWM输出
                PWM_OUT=1;//截止
        else
                PWM_OUT=0;//导通
}

//LCD_04显示--------------------------------------------------------------
void LCD_04()//显示
{
        //设置指令/数据
        if(LCD_C==0|LCD_C==17)//发送缓冲区0和17时是指令,其他是数据
                LCD_RS=0;//指令
        else
                LCD_RS=1;//数据
        //计数器=0时
        if(LCD_C==0)
        {
                //更新缓冲区
                        //更新PV
                LCD_BUF[4]=LCD_CHAR[PID_PV/100%10];//百位字符
                LCD_BUF[5]=LCD_CHAR[PID_PV/10%10];//十位字符
                LCD_BUF[6]=LCD_CHAR[PID_PV%10];//个位字符
                if(PID_PV<100)//小于100时百位不显示字符
                        LCD_BUF[4]=LCD_CHAR[10];//消影
                if(PID_PV<10)//小于10时十位不显示字符
                        LCD_BUF[5]=LCD_CHAR[10];//消影
                        //更新OUT
                LCD_BUF[12]=LCD_CHAR[PID_OUT/1000%10];//百位字符
                LCD_BUF[13]=LCD_CHAR[PID_OUT/100%10];//十位字符
                LCD_BUF[14]=LCD_CHAR[PID_OUT/10%10];//个位字符
                LCD_BUF[16]=LCD_CHAR[PID_OUT%10];//小数点后1位字符
                if(PID_OUT<1000)//小于100.0时百位不显示字符
                        LCD_BUF[12]=LCD_CHAR[10];//消影
                if(PID_OUT<100)//小于10.0时十位不显示字符
                        LCD_BUF[13]=LCD_CHAR[10];//消影
                        //更新SV
                LCD_BUF[21]=LCD_CHAR[PID_SV/100%10];//百位字符
                LCD_BUF[22]=LCD_CHAR[PID_SV/10%10];//十位字符
                LCD_BUF[23]=LCD_CHAR[PID_SV%10];//个位字符
                if(PID_SV<100)//小于100时百位不显示字符
                        LCD_BUF[21]=LCD_CHAR[10];//消影
                if(PID_SV<10)//小于10时十位不显示字符
                        LCD_BUF[22]=LCD_CHAR[10];//消影
                        //更新MA
                if(PID_MA>0)//设置为自动时
                        LCD_BUF[25]=LCD_CHAR[12];//显示A自动
                else
                        LCD_BUF[25]=LCD_CHAR[11];//显示M手动
                        //更新P,I,D
                if(SW_M<4)//未选择P,I,D
                {
                        LCD_BUF[28]=LCD_CHAR[10];//消影
                        LCD_BUF[29]=LCD_CHAR[10];//消影
                        LCD_BUF[30]=LCD_CHAR[10];//消影
                        LCD_BUF[31]=LCD_CHAR[10];//消影
                        LCD_BUF[32]=LCD_CHAR[10];//消影
                        LCD_BUF[33]=LCD_CHAR[10];//消影
                }
                if(SW_M==4)//选择P
                {
                        LCD_BUF[28]=LCD_CHAR[14];//显示P
                        LCD_BUF[29]=LCD_CHAR[16];//显示:
                        LCD_BUF[32]=LCD_CHAR[17];//显示.
                        LCD_BUF[30]=LCD_CHAR[PID_P/100%10];//十位字符
                        LCD_BUF[31]=LCD_CHAR[PID_P/10%10];//个位字符
                        LCD_BUF[33]=LCD_CHAR[PID_P%10];//小数点后1位字符
                        if(PID_P<100)//小于10.0时十位不显示字符
                                LCD_BUF[30]=LCD_CHAR[10];//消影
                }
                if(SW_M==5)//选择I
                {
                        LCD_BUF[28]=LCD_CHAR[15];//显示I
                        LCD_BUF[29]=LCD_CHAR[16];//显示:
                        LCD_BUF[32]=LCD_CHAR[17];//显示.
                        LCD_BUF[30]=LCD_CHAR[PID_I/100%10];//十位字符
                        LCD_BUF[31]=LCD_CHAR[PID_I/10%10];//个位字符
                        LCD_BUF[33]=LCD_CHAR[PID_I%10];//小数点后1位字符
                        if(PID_I<100)//小于10.0时十位不显示字符
                                LCD_BUF[30]=LCD_CHAR[10];//消影
                }

                //标记消影
                if(T_1S>=500)//1秒为周期,0.5秒消影,0.5秒显示
                        LCD_BUF[26]=LCD_CHAR[10];//消影
                else
                        LCD_BUF[26]=LCD_CHAR[13];//显示*
                //菜单激活消影
                if(SW_SUB_T<10&SW_ADD_T<10)//按键无输入
                {
                        LCD_ON++;//消影计数
                        if(LCD_ON>=10)//10个输出为循环周期
                                LCD_ON=0;//复位
                        if(LCD_ON<5)//消影时间
                        {
                                if(SW_M==1)//选择OUT
                                        LCD_BUF[16]=LCD_CHAR[10];//消影
                                if(SW_M==2)//选择SV
                                        LCD_BUF[23]=LCD_CHAR[10];//消影
                                if(SW_M==3)//选择MA
                                        LCD_BUF[25]=LCD_CHAR[10];//消影
                                if(SW_M>3)//选择P,I,D
                                        LCD_BUF[33]=LCD_CHAR[10];//消影
                        }
                }
                else//按键有输入
                        LCD_ON=0;//复位
        }        
        //输出缓冲区
        LCD_DATA=LCD_BUF[LCD_C];//根据计数器输出对应的缓冲区指令或数据
        LCD_E=1;//使能准备
        LCD_E=0;//执行指令或数据
        //计数器循环
        LCD_C++;//每发送1个缓冲区计数器加1
        if(LCD_C>=34)//发送完毕缓冲区复位计数器,循环发送
                LCD_C=0;//复位计数器
}

//END。END。END。END。END。END。END。END。END。END。END。END。









评分

参与人数 2黑币 +65 收起 理由
lyxxzrb + 15
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:97678 发表于 2019-12-4 20:37 | 显示全部楼层
能够发出来源码文件吗?
回复

使用道具 举报

ID:423556 发表于 2019-12-9 08:36 | 显示全部楼层
编译过的HEX文件,自己下载吧。
回复

使用道具 举报

ID:423556 发表于 2019-12-9 08:42 | 显示全部楼层
口试已经结束了,总共30分钟,基本没问跟单片机有关的问题。

由于测量温度精度的原因,使用微分控制时,很难调节微分的参数,容易超调。

现在这个版本没有使用指针,也没有使用微分控制,有时间还会编一个使用指针的程序。
毕竟使用指针才是C语言入门。

由于工作原因,更新时间不确定。
IMG_20191209_082247R.jpg
IMG_20191209_082736R.jpg
控制温度.jpg
室温.jpg
回复

使用道具 举报

ID:423556 发表于 2019-12-9 09:02 | 显示全部楼层
好像从下面回复有问题,HEX文件重新发一遍。


PID温度控制 STC15W408AS.rar

3.28 KB, 下载次数: 40, 下载积分: 黑币 -5

回复

使用道具 举报

ID:97678 发表于 2019-12-22 20:16 | 显示全部楼层
能提供一下源程序打包吗?
回复

使用道具 举报

ID:682979 发表于 2020-1-8 14:14 | 显示全部楼层
ok4005-max 发表于 2019-12-9 09:02
好像从下面回复有问题,HEX文件重新发一遍。

你好 这个源程序有解析吗  
回复

使用道具 举报

ID:275671 发表于 2020-1-14 08:12 | 显示全部楼层
居然是热底板的线路,不怕电死人吗?

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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