久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4303|回復: 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.使用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 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
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 (848.6 KB, 下載次數: 144)

IMG_20191209_082247R.jpg

IMG_20191209_082736R.jpg (762.13 KB, 下載次數: 125)

IMG_20191209_082736R.jpg

控制溫度.jpg (752.98 KB, 下載次數: 141)

控制溫度.jpg

室溫.jpg (1.03 MB, 下載次數: 136)

室溫.jpg
回復

使用道具 舉報

5#
ID:423556 發表于 2019-12-9 09:02 | 只看該作者
好像從下面回復有問題,HEX文件重新發一遍。


PID溫度控制 STC15W408AS.rar

3.28 KB, 下載次數: 45, 下載積分: 黑幣 -5

回復

使用道具 舉報

6#
ID:97678 發表于 2019-12-22 20:16 | 只看該作者
能提供一下源程序打包嗎?
回復

使用道具 舉報

7#
ID:682979 發表于 2020-1-8 14:14 | 只看該作者
ok4005-max 發表于 2019-12-9 09:02
好像從下面回復有問題,HEX文件重新發一遍。

你好 這個源程序有解析嗎  
回復

使用道具 舉報

8#
ID:275671 發表于 2020-1-14 08:12 | 只看該作者
居然是熱底板的線路,不怕電死人嗎?

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九精品久久久 | 爱操av| 综合精品久久久 | 九九精品在线 | 亚洲国产日韩欧美 | 亚洲一二三区在线观看 | 国产欧美日韩精品一区 | 国产成人一区二区三区 | 丝袜久久| 国产精品日产欧美久久久久 | 免费看日韩视频 | 91久色| h视频免费观看 | 99re超碰 | 成人精品一区二区 | 国产精品一区二 | 国产成人jvid在线播放 | 日日夜精品视频 | 久久综合久色欧美综合狠狠 | 中国毛片免费 | 亚洲性综合网 | 国产免费拔擦拔擦8x高清 | 精品久久av | 龙珠z在线观看 | www性色| 日本午夜视频 | 久久蜜桃资源一区二区老牛 | 超碰精品在线 | 亚洲视频在线观看免费 | 久久久久久久综合 | 久久久久国产一区二区三区四区 | 黑人巨大精品欧美一区二区免费 | 九九九久久国产免费 | 久久99精品视频 | 国产欧美精品区一区二区三区 | 美女久久视频 | 日本精品视频 | 人人看人人搞 | 不卡一二区 | 97超在线视频 | 国产欧美日韩精品一区二区三区 |