洪嵐峰 發表於 2023-4-27 06:40:56

PIC18F4520

製作PID控制系統需要以下零件:

PIC18F4520微控制器
LCD顯示屏
電位器
PWM模組
電容
電阻
輸入感測器
輸出設備(例如電機或LED燈)


以下PIC18F4520 PID控制系統的程式碼,您可以根據您的需求進行修改和優化:

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

#pragma config OSC = INTIO67
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOREN = SBORDIS
#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config PBADEN = OFF
#pragma config LVP = OFF

#define _XTAL_FREQ 8000000

int setpoint, input, output, error, last_error, integral, derivative;
int Kp = 1, Ki = 1, Kd = 1;

void interrupt isr(void) {
    if (PIR1bits.TMR2IF) {
        PIR1bits.TMR2IF = 0;
        TMR2 = 0;
        CCPR1L = output >> 2;
        CCP1CONbits.DC1B1 = (output & 0b10) >> 1;
        CCP1CONbits.DC1B0 = output & 0b01;
    }
}

void init_pwm() {
    TRISCbits.TRISC2 = 0;
    PR2 = 199;
    T2CON = 0b00000101;
    CCP1CON = 0b00001100;
}

void init_adc() {
    TRISA = 0b00001111;
    ADCON1 = 0b00001110;
    ADCON0 = 0b00000001;
}

int read_adc(int channel) {
    ADCON0bits.CHS = channel;
    __delay_us(20);
    GO_nDONE = 1;
    while (GO_nDONE);
    return ADRESH << 8 | ADRESL;
}

void init_pid() {
    last_error = 0;
    integral = 0;
}

void calculate_pid() {
    error = setpoint - input;
    integral += error;
    derivative = error - last_error;
    last_error = error;
    output = Kp * error + Ki * integral + Kd * derivative;
}

void main() {
    OSCCONbits.IRCF = 0b111;
    LCDInit();
    init_adc();
    init_pwm();
    init_pid();
    TMR2IE = 1;
    PEIE = 1;
    GIE = 1;
    while (1) {
        setpoint = 500; // set the desired setpoint
        input = read_adc(0); // read the input from the sensor
        calculate_pid(); // calculate the PID output
        __delay_ms(20);
    }
}
頁: [1]
查看完整版本: PIC18F4520