标题: Max的单片机PID温度控制第3.41版 源程序 [打印本页]
作者: ok4005-max 时间: 2019-12-4 15:22
标题: Max的单片机PID温度控制第3.41版 源程序
需要有个技术小结,为此做了一个PID温度控制器,要求入下:
1. 使用LCD1602显示:测量温度、设置温度、控制状态、输出量等。
2. 使用STC15W408AS单片机做为主控制系统。
3. 使用NTC电阻测量温度,经单片机取样后转换为温度显示。
4. 通过E,ADD,SUB三个输入按键修改设置温度、手动/自动、控制参数、输出量等。以1秒为周期,输出PWM波控制MOS管调节发热板的温度
电路图:
主要使用指令:
程序流程图:
单片机函数:
/*
硬件说明:
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。
作者: jovew 时间: 2019-12-4 20:37
能够发出来源码文件吗?
作者: ok4005-max 时间: 2019-12-9 08:36
编译过的HEX文件,自己下载吧。
作者: ok4005-max 时间: 2019-12-9 08:42
口试已经结束了,总共30分钟,基本没问跟单片机有关的问题。
由于测量温度精度的原因,使用微分控制时,很难调节微分的参数,容易超调。
现在这个版本没有使用指针,也没有使用微分控制,有时间还会编一个使用指针的程序。
毕竟使用指针才是C语言入门。
由于工作原因,更新时间不确定。
-
IMG_20191209_082247R.jpg
(848.6 KB, 下载次数: 144)
-
IMG_20191209_082736R.jpg
(762.13 KB, 下载次数: 125)
-
控制温度.jpg
(752.98 KB, 下载次数: 141)
-
室温.jpg
(1.03 MB, 下载次数: 136)
作者: ok4005-max 时间: 2019-12-9 09:02
好像从下面回复有问题,HEX文件重新发一遍。
-
-
PID温度控制 STC15W408AS.rar
3.28 KB, 下载次数: 45, 下载积分: 黑币 -5
作者: jovew 时间: 2019-12-22 20:16
能提供一下源程序打包吗?
作者: 1220875098 时间: 2020-1-8 14:14
你好 这个源程序有解析吗
作者: 1xiaosun 时间: 2020-1-14 08:12
居然是热底板的线路,不怕电死人吗?
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |