找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2691|回復(fù): 2
收起左側(cè)

pid控溫求助,LCD只亮不顯示

[復(fù)制鏈接]
ID:341661 發(fā)表于 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;                                //這是用來存放溫度值的,測溫程序通過這個數(shù)組與主函數(shù)通信
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; //調(diào)節(jié)占空比的參數(shù)
uint rout;// PID輸出
/查表法*******
將表值分離出的十位和個位送到十分位和百分位********************/

struct PID
{
        uint SetPoint;      // 設(shè)定目標 Desired Value
        uint Proportion;    // 比例常數(shù) Proportional Const
        uint Integral;      // 積分常數(shù) Integral Const
        uint Derivative;    // 微分常數(shù) Derivative Const
        signed int LastError;     // 錯誤Error[-1]
        signed int PrevError;     // 錯誤Error[-2]
        signed int SumError;      // Sums of Errors
};
struct PID spid;                // PID控制結(jié)構(gòu)體

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)        //將溫度上下限轉(zhuǎn)換為LCD顯示的數(shù)據(jù)
{
        if(TH>0x7F)                    //判斷正負,如果為負溫,將其轉(zhuǎn)化為其絕對值
        {
                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; //百位數(shù)消隱
        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; //百位數(shù)消隱
        TempBuffer0[13]=(TL%100)/10+0x30;                                //分離出十位
        TempBuffer0[14]=(TL%100)%10+0x30;                                 //分離出個位
}


void covert1(void)        //將溫度轉(zhuǎn)換為LCD顯示的數(shù)據(jù)
{
        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];                         /*下面幾句把負數(shù)的補碼*/
                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;                //將高字節(jié)左移4位
          t[1]=t[1]&0x70;                //取出高字節(jié)的3個有效數(shù)字位
          x=t[0];                                        //將t[0]暫存到X,因為取小數(shù)部分還要用到它
          x>>=4;                                        //右移4位
          x=x&0x0f;                                        //和前面兩句就是取出t[0]的高四位       
          t[1]=t[1]|x;                        //將高低字節(jié)的有效值的整數(shù)部分拼成一個字節(jié)
          TempBuffer1[1]=t[1]/100+0x30;                             //+0x30 為變 0~9 ASCII碼
           if( TempBuffer1[1]==0x30)
                TempBuffer1[1]=0xfe; //百位數(shù)消隱
          TempBuffer1[2]=(t[1]%100)/10+0x30;                                //分離出十位
          TempBuffer1[3]=(t[1]%100)%10+0x30;                                 //分離出個位
          t[0]=t[0]&0x0c;                                                        //取有效的兩位小數(shù)
          t[0]>>=2;                                                                        //左移兩位,以便查表
          x=t[0];                                                                               
          y=dotcode[x];                                                                        //查表換算成實際的小數(shù)
          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;                                            //下一步擴展時可能通過這兩個變量,調(diào)節(jié)上下限
                                                                       //測溫函數(shù)返回這個數(shù)組的頭地址
        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
                                                                                         //讀取溫度,溫度值存放在一個兩個字節(jié)的數(shù)組
          
            if((t[1]>TH)|(t[1]<TL))
                {
                    Beep=1;
        //                Relay=1;
               
                }
                else
                {
                    Beep=0;
        //                Relay=0;
                }
                delay(10000);
                covert1();
                covert0(TH,TL);
                LCD_Initial();                                                        //第一個參數(shù)列號,第二個為行號,為0表示第一行
                                                                                                //為1表示第二行,第三個參數(shù)為顯示數(shù)據(jù)的首地址
                LCD_Print(0,0,TempBuffer0);       
                LCD_Print(0,1,TempBuffer1);                                
        }
}

仿真圖

仿真圖

測試1.rar

98.41 KB, 下載次數(shù): 25

回復(fù)

使用道具 舉報

ID:466975 發(fā)表于 2019-1-12 20:45 | 顯示全部樓層
這是不是和最近的那篇一樣啊
回復(fù)

使用道具 舉報

ID:681421 發(fā)表于 2020-1-5 10:21 | 顯示全部樓層
運行的時候總是提示沒有發(fā)現(xiàn)DS18b20.h是什么意思?
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表