冰楓論壇

 找回密碼
 立即註冊
搜索
查看: 726|回覆: 0
打印 上一主題 下一主題

[討論] PIC16F877

[複製鏈接]

2609

主題

0

好友

1003

積分

金牌會員

Rank: 6Rank: 6

UID
373967
帖子
9008
主題
2609
精華
0
積分
1003
楓幣
0
威望
980
存款
35891
贊助金額
0
推廣
0
GP
1205
閱讀權限
70
在線時間
460 小時
註冊時間
2023-1-12
最後登入
2024-12-22

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-27 06:37:58 |只看該作者 |倒序瀏覽
製作PID控制器所需的零件如下:

PIC16F877微控制器
16x2液晶顯示器
電位計
電容
電阻
電晶體
繼電器
電源供應器

PIC16F877微控制器的引腳連結如下:

VDD連接至電源正極
VSS連接至電源負極
RA0連接至電位計輸出
RA1連接至繼電器控制腳
RA2連接至液晶顯示器RS腳
RA3連接至液晶顯示器EN腳
RC0連接至液晶顯示器D4腳
RC1連接至液晶顯示器D5腳
RC2連接至液晶顯示器D6腳
RC3連接至液晶顯示器D7腳

以下是PIC16F877製作PID控制器的程式碼,使用的開發環境是MPLAB IDE和XC8編譯器:


#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 20000000

// PID參數
float Kp = 1.0;
float Ki = 0.0;
float Kd = 0.0;
float last_error = 0.0;
float integral = 0.0;

// 目標值
float target = 50.0;

void main(void) {
    // 設定I/O
    TRISA = 0b00000001; // RA0為輸入
    TRISC = 0b00000000; // RC為輸出
   
    // 設定液晶顯示器
    Lcd_Init();
    Lcd_Clear();
    Lcd_Set_Cursor(1,1);
    Lcd_Write_String("Temperature: ");
   
    // 設定ADC
    ADC_Init();
   
    // 設定計時器
    TMR1_Init();
   
    while(1) {
        // 讀取溫度值
        float temp = ADC_Read(0);
        temp = temp * 0.4887; // 轉換為攝氏溫度
        
        // 計算誤差
        float error = target - temp;
        
        // 計算PID輸出
        float Pout = Kp * error;
        integral += error;
        float Iout = Ki * integral;
        float derivative = error - last_error;
        float Dout = Kd * derivative;
        float output = Pout + Iout + Dout;
        last_error = error;
        
        // 限制輸出範圍
        if(output > 255) {
            output = 255;
        } else if(output < 0) {
            output = 0;
}

    // 控制繼電器
    if(output > temp) {
        PORTAbits.RA1 = 1;
    } else {
        PORTAbits.RA1 = 0;
    }
   
    // 顯示溫度和PID輸出
    Lcd_Set_Cursor(1, 14);
    Lcd_Write_Char(temp/10 + '0');
    Lcd_Write_Char(temp%10 + '0');
    Lcd_Write_String("C ");
    Lcd_Set_Cursor(2, 1);
    Lcd_Write_String("PID Output: ");
    Lcd_Set_Cursor(2, 13);
    Lcd_Write_Char(output/100 + '0');
    Lcd_Write_Char((output/10)%10 + '0');
    Lcd_Write_Char(output%10 + '0');
   
    __delay_ms(500);
}
}

// 設定ADC
void ADC_Init() {
ADCON0 = 0b00000001; // 設定RA0為輸入和啟用ADC
ADCON1 = 0b00000000; // 設定VDD和VSS為參考電壓
__delay_us(20);
}

// 讀取ADC
float ADC_Read(unsigned char ch) {
if(ch > 7) {
return 0;
}
ADCON0 = (ch<<2) | 0b00000001;
__delay_us(20);
GO_DONE = 1;
while(GO_DONE);
return ADRESH * 256 + ADRESL;
}

// 設定計時器
void TMR1_Init() {
T1CON = 0b00000111; // 設定為16位元計時器、Fosc/256、啟用計時器
}

// 設定液晶顯示器
void Lcd_Init() {
Lcd_Port = 0x00;
__delay_ms(20);
Lcd_Command(0x03);
__delay_ms(5);
Lcd_Command(0x03);
__delay_ms(11);
Lcd_Command(0x03);
Lcd_Command(0x02);
Lcd_Command(0x28);
Lcd_Command(0x0c);
Lcd_Command(0x06);
Lcd_Command(0x01);
}

// 寫入液晶顯示器指令
void Lcd_Command(unsigned char cmd) {
Lcd_Port = cmd;
RS = 0;
EN = 1;
__delay_ms(4);
EN = 0;
}

// 寫入液晶顯示器字符
void Lcd_Write_Char(unsigned char data) {
Lcd_Port = data;
RS = 1;
EN = 1;
__delay_us(40);
EN = 0;
}

// 寫入液晶顯示器字串
void Lcd_Write_String(char *str) {
int i;
for(i=0;str[i]!='\0';i++) {
Lcd_Write_Char(str[i]);
}
}

// 設定液晶顯示器游標位置
void Lcd_Set_Cursor(unsigned char row, unsigned char col) {
if(row == 1) {
Lcd_Command(0x80 + col - 1} else if(row == 2) {
Lcd_Command(0xc0 + col - 1);
}
}

// 計算PID輸出
int PID_Controller(float set_point, float process_variable) {
static float integral = 0;
static float derivative = 0;
static float last_error = 0;
float error = set_point - process_variable;
integral += error * TIME_INTERVAL;
derivative = (error - last_error) / TIME_INTERVAL;
last_error = error;

return (int)(KP * error + KI * integral + KD * derivative);
}



關於連結腳位,請參考PIC16F877的資料手冊,其中包括了PIC16F877的腳位圖和對應的功能,以及每個腳位的電氣特性和建議的連接方法。
收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1鑰匙
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-12-22 16:58

回頂部