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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4533|回復: 4
打印 上一主題 下一主題
收起左側

基于18b20的PID溫控單片機程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:587827 發表于 2019-7-21 19:01 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
主控芯片采用STM32F103RCT6,用18b20作為溫度傳感器,可以通過串口發送命令和當前溫度等信息。PI調節,使用PWM控制固態繼電器繼而控制加熱器通斷。
/******************************************
/*********    無線遙控溫度控制            
/*********    MCU:STC89C52      
* *******    溫度傳感器:18b20     
* 控制方法:PID控制
* 串口命令格式'\0x04'+命令+'\0x05'
*****************************************/

#include <reg51.h>
#include <stdio.h>

#define uchar unsigned char
#define uint  unsigned int

#define FOSC 11059200L      //晶振頻率
#define BAUD 9600           //串口波特率

#define PWMPERIOD 100               //周期,*5ms
#define OPEN 1
#define CLOSE 0

sbit pwm_out=P1^2;              //pwm輸出口
sbit dq = P0^1;             //18b20數據接口
sbit die=P1^0;

uchar tx[10];               //溫度結果儲存,0、1為整數位,其余小數
uchar temp_now;
//float temp_now_dec;
float temp_set;
uchar cmd;
uchar time_length;
uchar duty_ratio;
//float duty;
float kp,ki,kd;             //pid參數
float e_k,e_k_1,e_k_2;      //偏差,此刻,上一刻,上上一刻

uchar cmd_flag;             //狀態標志量,與接收命令有關
uchar run;                      //運行狀態,為1則啟動溫控

//微秒級延時
void DelayUs(int num)
{
    while(num--) ;
}

//毫秒級延時
void DelayMs(uint di) //延時
{
    uint da,db;
    for(da=0;da<di;da++)
        for(db=0;db<100;db++);
}

//發送
void Print(uchar str)
{
    //TR0=0;
    SBUF=str;
    while(!TI);
    TI=0;
    //TR0=1;
}

//PID計算程序
void CalculatePID()
{
    char u_add;
   
    e_k_2=e_k_1;
    e_k_1=e_k;
    e_k=temp_set-temp_now;
    //u_add=(kp+ki+kd)*e_k-(kp+2*kd)*e_k_1+kd*e_k_2;
    u_add=kp*e_k-kp*e_k_1;
//  duty=duty-u_add;
//  if(duty>1)
//  {
//      duty=1;
//  }else if(duty<0)
//  {
//      duty=0;
//  }
//  duty_ratio=PWMPERIOD*duty;
    duty_ratio=u_add+duty_ratio;
    if(duty_ratio>=PWMPERIOD)
    {
        duty_ratio=PWMPERIOD;
    }
    Print('D');
    Print(duty_ratio/100+48);
    Print(duty_ratio%100/10+48);
    Print(duty_ratio%10+48);
    Print('\n');
}

//ds18b20初始化程序
//返回值:1初始化成功,0失敗
uchar Init_DS18B20(void)
{
    uchar x=0;
    dq = 1;    //dq復位
    DelayUs(8);  //稍做延時
    dq = 0;    //單片機將dq拉低
    DelayUs(80); //精確延時 大于 480us
    dq = 1;    //拉高總線
    DelayUs(14);
    x=dq;      //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
    if(x)
    {
        x=0;
    }else
    {
        x=1;
    }
   
    DelayUs(20);
    return x;
}

//串口初始化程序
void Init_Uart()
{
    SCON = 0x52;            //8bit無奇偶校驗
    TMOD = 0x20;            //Timer1設為8bit自動重裝模式
    TCON=0x00;
    PCON=0X00;
    TH1 = TL1 = -(FOSC/12/32/BAUD); //定時器初值
    TR1 = 1;                //Timer1使能
        RI=0;
    TI=0;
    ES = 1;                 //串口中斷使能
    EA = 1;                 //總中斷使能
}

//定時器初始化程序
void InitTimer()        //5毫秒
{
    //AUXR &= 0x7F;     //定時器時鐘12T模式
    TMOD &= 0x01;       //設置定時器模式
    TL0 = 0x00;     //設置定時初值
    TH0 = 0xEE;     //設置定時初值
    TF0 = 0;        //清除TF0標志
    TR0 = 1;        //定時器0開始計時
    ET0 = 1;
}

//從DS18B20讀取一節數據
//返回值:讀到的數據
uchar ReadOneChar(void)
{
    uchar i=0;
    uchar dat = 0;
    for (i=8;i>0;i--)
    {
        dq = 0; // 給脈沖信號
        dat>>=1;
        dq = 1; // 給脈沖信號
        if(dq)
        dat|=0x80;
        DelayUs(4);
    }
    return(dat);
}

//對18b20寫一個字節
//參數:數據
void WriteOneChar(unsigned char dat)
{
    uchar i=0;
    for (i=8; i>0; i--)
    {
        dq = 0;
        dq = dat&0x01;
        DelayUs(2);
        dq = 1;
        dat>>=1;
    }
}

//讀取溫度
void ReadTemperature(void)
{
    uchar a=0;
    uchar b=0;
    uchar Data_L=0;
    uchar num=0;

    Init_DS18B20();

    WriteOneChar(0xCC); // 跳過讀序號列號的操作
    WriteOneChar(0x44); // 啟動溫度轉換
    Init_DS18B20();
    WriteOneChar(0xCC); //跳過讀序號列號的操作
    WriteOneChar(0xBE); //讀取溫度寄存器

    a=ReadOneChar();  //讀低8位
    b=ReadOneChar(); //讀高8位

    tx[0] = (a/16+b*16)/10;      //整數部分
    tx[1] = (a/16+b*16)%10;

    Data_L=a&0X0F;
    for(num=3;num<7;num++)       //小數部分
   {
        Data_L=Data_L*10;      
        tx[num]=Data_L/16;           
        Data_L=Data_L%16;      
    }
    temp_now=(uchar)(tx[0*10+tx[1]);
    //temp_now_dec=tx[0]*10+tx[1]+tx[3]*0.1+tx[4]*0.01;
}

//處理命令
void DealCMD()
{
    if(cmd_flag==3)
        {
            switch (cmd)
            {
            case 'U':
            //up命令,溫度設定值上升
                if(temp_set<50)
                {
                    temp_set++;
                }else
                {
                    temp_set=50;
                }
                cmd_flag=0;
                break;
            case 'D':
            //down命令,溫度設定值下降
                if(temp_set>20)
                {
                    temp_set--;
                }else
                {
                    temp_set=20;
                }
                cmd_flag=0;
                break;
            case 'C':
            //close命令,關閉加熱
                run=0;
                //P1=0XF0;
                cmd_flag=0;
                break;
            case 'O':
            //open命令,開啟加熱
                run=1;
                //P1=0X10;
                cmd_flag=0;
                break;
            default:
                cmd_flag=0;
                break;
            }
        }
}

//串口中斷函數
void Get()interrupt 4
{
    uchar dat;
    //P1=0X0C;
    if(RI)//接收到數據
    {
        die=0;
        RI=0;
        dat=SBUF;

        switch (cmd_flag)   //根據當前狀態采取不同措施
        {
        case 0:
        //未接收到命令頭狀態
            if(dat=='$')
            //收到命令頭
            {
                cmd_flag=1;
            }
            break;
        case 1:
        //收到命令頭狀態
            cmd=dat;
            cmd_flag=2;
            break;
        case 2:
        //準備收結束位
            if(dat=='/')
            {
                cmd_flag=3;
            }else
            {
                cmd_flag=0;
            }
            break;
        default:
        //無效狀態
            cmd_flag=0;
            break;
        }
    }
}

//定時中斷函數
void Time()interrupt 1
{
  time_length++;
    if(time_length>=PWMPERIOD)
    {
        ReadTemperature();
        if(run)
        {
            pwm_out=OPEN;
            time_length=0;
            CalculatePID();
        }
    }else if (time_length>=duty_ratio)
    {
        pwm_out=CLOSE;
    }
   
}

//主函數
int main()
{
    IP=0x10;
    InitTimer();
    Init_Uart();
    Init_DS18B20();
    time_length=0;
    duty_ratio=0;
    e_k=0;
    e_k_1=0;
    e_k_2=0;
//  duty=0;
    temp_set=30;
    time_length=0;
    kp=1;
    ki=0;
    kd=0;
    run=1;
    while(1)
    {
        DealCMD();
        if(run)//判斷是否需要啟動了加熱
        {
            die=!die;           //指示燈閃爍
            TR0=1;
            Print('>');         //運行狀態
        }else
        {
            die=0;              //指示燈常亮
            //TR0=0;
            pwm_out=0;
            Print('|');         //暫停狀態
        }
        //輸出當前溫度
        Print('N');
//      Print('=');
//      Print(temp_now/10+48);
//      Print(temp_now%10+48);
//      Print('.');
//      Print((int)(temp_now_dec*10)+48);
//      Print((int)(temp_now_dec*100)%10+48);
        Print(tx[0+'0');
        Print(tx[1+'0');
        Print('.');
        Print(tx[3+'0');
        Print(tx[4+'0');
        Print(',');
        //Print('\n');
        //輸出設定溫度
        Print('S');
    //  Print('=');
        Print((int)temp_set/10+48);
        Print((int)temp_set%10+48);
        Print('\r');
        Print('\n');
        DelayMs(200);
    }
    return 0;
}

USER.7z

84.56 KB, 下載次數: 60, 下載積分: 黑幣 -5

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

使用道具 舉報

沙發
ID:202586 發表于 2019-7-25 19:45 來自觸屏版 | 只看該作者
不錯,謝謝樓主分享
回復

使用道具 舉報

板凳
ID:401343 發表于 2019-7-28 22:44 | 只看該作者
謝謝分享
回復

使用道具 舉報

地板
ID:879424 發表于 2021-4-6 17:41 | 只看該作者
能否詳細講一下PID的編程思路?
回復

使用道具 舉報

5#
ID:332674 發表于 2021-4-12 13:25 | 只看該作者
請問樓主模塊是用的什么?求分享
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91极品视频 | 精品久久久999 | 欧美精品一区二区三区在线 | 成人免费观看男女羞羞视频 | 日韩在线免费视频 | 亚洲成人一区二区在线 | 午夜在线视频 | 久久久精| 欧美日韩一区二区三区四区五区 | 久久久久香蕉视频 | 第一av| 精久久| 亚洲色欧美另类 | 岛国二区| 亚洲第一天堂无码专区 | 国产99免费视频 | 亚洲国产成人精品久久久国产成人一区 | 免费一区二区在线观看 | 毛片.com | 亚洲一区二区三区四区五区午夜 | 综合久 | 99精品一区二区三区 | 超碰免费在线观看 | 欧美视频日韩 | 国产在线视频在线观看 | 人和拘一级毛片c | 91久久国产精品 | 国产精品小视频在线观看 | 亚洲欧美视频 | 亚洲一区二区在线视频 | 91色在线视频 | 一本色道精品久久一区二区三区 | 久久久精品一区二区三区四季av | 成人二区 | 亚洲国产精品成人综合久久久 | 国产资源视频 | 九九国产在线观看 | 欧美网站一区二区 | 国产亚洲精品美女久久久久久久久久 | 欧美国产日韩一区二区三区 | 欧美激情五月 |