单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 332|回复: 1
收起左侧

pid控温求助,LCD只亮不显示

[复制链接]
heartofYan 发表于 2018-5-30 19:53 | 显示全部楼层 |阅读模式
#include <at89x51.h>
#include <absacc.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <DS18B20.h>
#include "LCD1602.h"                        ////液晶显示头文件
#define uchar unsigned char
#define uint unsigned int
sbit Key1=P1^0;
sbit Key2=P1^1;
sbit Up  =P1^2;
sbit Down=P1^3;
uchar t[2],*pt;                                //这是用来存放温度值的,测温程序通过这个数组与主函数通信
uchar  TempBuffer1[9]={0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0x43,'\0'};
                                                                //显示实时的温度,上电时显示+125.00C
uchar  TempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20,
                                                                0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,0x43,'\0'};
                                                                //显示温度上下限,上电时显示TH:+125 TL:+124C                                                       
uchar code dotcode[4]={0,25,50,75};
uchar set;//温度初始值
uchar count,high_time=0; //调节占空比的参数
uint rout;// PID输出
/查表法*******
将表值分离出的十位和个位送到十分位和百分位********************/

struct PID
{
        uint SetPoint;      // 设定目标 Desired Value
        uint Proportion;    // 比例常数 Proportional Const
        uint Integral;      // 积分常数 Integral Const
        uint Derivative;    // 微分常数 Derivative Const
        signed int LastError;     // 错误Error[-1]
        signed int PrevError;     // 错误Error[-2]
        signed int SumError;      // Sums of Errors
};
struct PID spid;                // PID控制结构体

void init_pid()
//PID初始化
{
        high_time=50;
        spid.Proportion = 23;       // Set PID Coefficients
        spid.Integral = 2;
        spid.Derivative =6;
        spid.SetPoint = set;      // Set PID Setpoint
}

unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
//PID算法
{
        signed int dError,Error;
        Error = pp->SetPoint - NextPoint;           // 偏差
        pp->SumError += Error;                      // 积分
        dError = pp->LastError - pp->PrevError;     // 当前微分
        pp->PrevError = pp->LastError;       
        pp->LastError = Error;
        return (pp->Proportion * Error+ pp->Integral * pp->SumError        + pp->Derivative * dError);
}

void duty_cycle(uint t)                              
// 占空比
{
        uchar s;
        t=t/10;
        s=set;
        if(s>t)
        {
                if(s-t>2)
                        high_time=100;
                else
                {
                        rout = PIDCalc ( &spid,t );   // Perform PID Interation
                        if(high_time<=100)
                                high_time=(uchar)(rout/600);
                        else
                                high_time=100;       
                }
        }
        else
                high_time=0;
}

void covert0( unsigned char TH, unsigned char TL)        //将温度上下限转换为LCD显示的数据
{
        if(TH>0x7F)                    //判断正负,如果为负温,将其转化为其绝对值
        {
                TempBuffer0[3]=0x2d;             //0x2d为"-"的ASCII码
                TH=~TH;
                TH++;
        }
        else TempBuffer0[3]=0x2b;        //0x2B为"+"的ASCII码
       
        if(TL>0x7f)
        {
                TempBuffer0[11]=0x2d;             //0x2d为"-"的ASCII码
                TL=~TL+1;
        }
        else
                TempBuffer0[11]=0x2b;        //0x2B为"+"的ASCII码
       
        TempBuffer0[4]=TH/100+0x30;                             //分离出TH的百十个位
        if( TempBuffer0[4]==0x30)
                TempBuffer0[4]=0xfe; //百位数消隐
        TempBuffer0[5]=(TH%100)/10+0x30;                                //分离出十位
        TempBuffer0[6]=(TH%100)%10+0x30;                                 //分离出个位
        TempBuffer0[12]=TL/100+0x30;                             //分离出TL的百十个位
        if( TempBuffer0[12]==0x30)
                TempBuffer0[12]=0xfe; //百位数消隐
        TempBuffer0[13]=(TL%100)/10+0x30;                                //分离出十位
        TempBuffer0[14]=(TL%100)%10+0x30;                                 //分离出个位
}


void covert1(void)        //将温度转换为LCD显示的数据
{
        unsigned char x=0x00,y=0x00;
           t[0]=*pt;
           pt++;
           t[1]=*pt;
           if(t[1]>0x07)                    //判断正负温度
           {
            TempBuffer1[0]=0x2d;             //0x2d为"-"的ASCII码
                t[1]=~t[1];                         /*下面几句把负数的补码*/
                t[0]=~t[0];                  /* 换算成绝对值*********/
                x=t[0]+1;                                 /***********************/
                t[0]=x;                                         /***********************/
                if(x>255)                /**********************/
                        t[1]++;                                 /*********************/
           }
           else
                TempBuffer1[0]=0x2b;        //0xfe为变"+"的ASCII码
          t[1]<<=4;                //将高字节左移4位
          t[1]=t[1]&0x70;                //取出高字节的3个有效数字位
          x=t[0];                                        //将t[0]暂存到X,因为取小数部分还要用到它
          x>>=4;                                        //右移4位
          x=x&0x0f;                                        //和前面两句就是取出t[0]的高四位       
          t[1]=t[1]|x;                        //将高低字节的有效值的整数部分拼成一个字节
          TempBuffer1[1]=t[1]/100+0x30;                             //+0x30 为变 0~9 ASCII码
           if( TempBuffer1[1]==0x30)
                TempBuffer1[1]=0xfe; //百位数消隐
          TempBuffer1[2]=(t[1]%100)/10+0x30;                                //分离出十位
          TempBuffer1[3]=(t[1]%100)%10+0x30;                                 //分离出个位
          t[0]=t[0]&0x0c;                                                        //取有效的两位小数
          t[0]>>=2;                                                                        //左移两位,以便查表
          x=t[0];                                                                               
          y=dotcode[x];                                                                        //查表换算成实际的小数
          TempBuffer1[5]=y/10+0x30;                                                        //分离出十分位
          TempBuffer1[6]=y%10+0x30;                                                        //分离出百分位
}                       

void delay(unsigned int i)
{
        while(i--);
}

void t0_int(void) interrupt 1                //PWM波输出
{
        if(++count<=(high_time))
        Relay=0;
        else if(count<=100)
        Relay=1;
        else
        count=0;
        TH0=0X20;
        TL0=0X00;
}

main()
{
        unsigned char TH=50,TL=10,temp=0;                                            //下一步扩展时可能通过这两个变量,调节上下限
                                                                       //测温函数返回这个数组的头地址
        TMOD=0X01;
        TH0=0X20;
        TL0=0X00;
        EA=1;
        ET0=1;
        TR0=1;
        set=60;//目标温度
        Beep=0;Relay=0;
        init_pid();
        while(1)
        {       
            if(Up==0)
                {
                   while(!Up);
                   TH++;
                }
                if(Down==0)
                {
                        while(!Down);
                        TL--;
                }
                pt=ReadTemperature(TH,TL,0x3f);                 //上限温度-22,下限-24,分辨率10位,也就是0.25C
                                                                                         //读取温度,温度值存放在一个两个字节的数组
          
            if((t[1]>TH)|(t[1]<TL))
                {
                    Beep=1;
        //                Relay=1;
               
                }
                else
                {
                    Beep=0;
        //                Relay=0;
                }
                delay(10000);
                covert1();
                covert0(TH,TL);
                LCD_Initial();                                                        //第一个参数列号,第二个为行号,为0表示第一行
                                                                                                //为1表示第二行,第三个参数为显示数据的首地址
                LCD_Print(0,0,TempBuffer0);       
                LCD_Print(0,1,TempBuffer1);                                
        }
}

仿真图

仿真图

测试1.rar

98.41 KB, 下载次数: 1

回复

使用道具 举报

booty 发表于 2019-1-12 20:45 | 显示全部楼层
这是不是和最近的那篇一样啊
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机.

Powered by 单片机教程网

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