Ir ao conteúdo
  • Cadastre-se

Recommended Posts

Olá, gostaria de pedir o auxilio para conversão do programa abaixo para o pessoal que já trabalhou com esses compiladores, na primeira parte se encontra as alterações já realizadas, na se segunda está o programa a ser convertido, caso o programa seja muito grande gostaria de pedir auxilio principalmente nos INTCON, T0CON, RCON, CCP1CON e etc.

 

Convertendo XC8 para CCS:
Programa deixa o config.h como comentário por que o mesmo causava erro
__Delay_ms(); --> delay_ms();
TRISA();      --> set_tris_a();
#define en1 PORTAbits.RA2 --> en1 PIN_A2
ADC_read(); --> read_adc();


/* Titulo: PID digital 
 * Versão: 1.0
 * Autor: 
 * Data: 02/06/2018
 * Compilador: XC8 --> CCS
 * IDE: MplabX 4.10
 * Dispositivo: PIC18f4550
 * ======================================= Descrição ========================================== *
 * Este codigo realiza o controle PID de maneira discreta. Através dos dados de entrada         *
 * referência e feedback, ambos medidos pelo conversor A/D em AN0 e AN1, encontra-se o erro,    *
 * que então e usado como parametro para calcular um valor de pwm necessário para corrigi-lo    *
 * isso através da função: PID_set_PF(). O sentido de giro do motor e controlado através das    *
 * saidas digitais RA2, RA3.                                                                    *
 * ============================================================================================ *
 */
// PIC18F4550 Configuration Bit Settings
#include <xc.h>                 // compilador
#include <18f4550.h>            // dispositivo
#include <stdio.h>              // para utilizar a funcao sprintf
#include <stdarg.h>             // para utilizar a funcao sprintf
//#include "config.h"           // configuracoes do pic

//================== defines e mapeamento de hardware =============//
#use delay(clock = 48000000)    // constante usada pelo delay, clock
#define SHIFT 256               // usado para calculos com ponto fixo <<8
#define en1 PIN_A2              // en1 da ponte H, pino 4 do pic
#define en2 PIN_A3              // en2 da ponte H, pino 5 do pic
#define RS  PIN_D1
#define EN  PIN_D0
#define D4  PIN_D4
#define D5  PIN_D5
#define D6  PIN_D6
#define D7  PIN_D7
//==================== variaveis globais =========================//
long int ref = 0;               // guarda o valor do potenciomentro de referencia       
long int fb  = 0;               // guarda o valor do potenciomentro de feedback
long int pwm = 0;               // guarda valor de dutycicle do pwm
float kp;                       // coeficiente da acao proporcional
float ki;                       // coeficiente da acao integral
float kd;                       // coeficiente da acao derivativa
float T = 0.005;                // periodo de amostragem
long int k1;                    // coeficiente auxiliar, para uso de ponto fixo
long int k2;                    // coeficiente auxiliar, para uso de ponto fixo
long int k3;                    // coeficiente auxiliar, para uso de ponto fixo
long int erro0 = 0;             // erro da amostra atual e(n)
long int erro1 = 0;             // erro da amostra anterior e(n-1)
long int out0 = 0;              // saida da funcao do PID
long int integral = 0;          // parcela integral
long int derivativo = 0;        // derivativo

//========================= funcoes =============================//

void ADC_init() {
    ADCON1 = 0b00001101;             //Somente AN0 e AN1 como entrada analogica, referencia e realimentacao
    ADCON2 = 0b10001110;             //justificado a direita, 64 fosc , 2 Tda
}// fim ADC_init
unsigned ADC_read(unsigned char canal) {
    ADCON0 = canal;
    delay_us(10);                    // tempo para carregar capacitor interno
    ADCON0bits.GODONE = 1;           // inicia a conversao
    while (ADCON0bits.GODONE);       // espera o fim da conversao AD
    {
    }
    return ((ADRESH << 8) + ADRESL); // retorna um valor convertido de 0 - 1023
}// fim ADC_read
unsigned long int PID_set_PF() {
    erro0 = ref - fb;
    erro1 = erro0;                   // atualiza valores
    // calculo do PID 
    integral = integral + (erro0 * T);
    derivativo = ((erro0-erro1)/T);
    out0 = ((k1 * erro0)+ (k2 * integral) + (k3 * derivativo));
    out0 = out0 >> 8;                // deslocamento devido ao uso de ponto fixo

    if (out0 < -1) {                 // caso negativo 
            out0 = out0*(-1);        // multiplica por -1
        }
    if(out0>1023)                    // caso estoure
    {
        out0 = 1023;                 // saturar saida
    }
    return out0;
}// fim PID_set_PF
#ORG 0x1000, 0x3000
void interrupt high_priority interrupcoes(void) {
    if (INTCONbits.TMR0IF == 1) {
        INTCONbits.TMR0IF = 0;
        PORTBbits.RB7 = !PORTBbits.RB7;
        ref = read_adc(0b00000001);   // ler valor potenciomentro de referencia AN0 pino 2
        delay_us(10);                 // tempo para descarregar capacitor interno
        fb = read_adc(0b00000101);    // ler valor potenciomentro de realimentacao AN1 pino 3
        pwm = PID_set_PF();           // calcula valor do PID
        TMR0L = 22 + TMR0L;           // interrupcao a cada 0.005 segundos
    }
}

void setup() {
    CMCON = 0x07;                     // desabilita os comparadores internos
    // configura saidas e entradas
    set_tris_a = 0b00000011;          // somente RA0,RA1 como entrada analogica, demais pinos saida
    set_tris_b = 0x00;                // todo o PORTB como saida
    set_tris_c = 0x00;                // todo o PORTC como saida, onde pino 17 RC2/CCP1 sera a saida PWM 
    set_tris_d = 0x00;                // todo o PORTD como saida, onde se encotra conectado o LCD
    set_tris_e = 0x00;                // todo o PORTE como saida
    PORTB = 0xFF;                     // inicia o PORTB todo em alto
    ADC_init();                       // inicia configuracoes do ADC
    ADCON0bits.ADON = 1;              // liga o modulo adc  
    PORTDbits.RD2 = 0;                // pino onde se encontra o RW do LCD, para escrita deve estar em nivel logico baixo
    // configuração PWM
    T2CON = 0x07;                     // Liga timer2 e ativa prescaler 16
    PR2 = 0x7F;                       // Carrega PR2
    CCP1CON = 0x3C;
    CCPR1L = 0x00;
    CCP1CONbits.DC1B0 = 0;
    CCP1CONbits.DC1B1 = 0;
}// fim setup


//====================== funcao principal =======================//

void main() {          // inicio main
    setup();           // faz set up das configuracoes
    PORTDbits.RD2 = 0; // pino onde se encontra o RW do LCD, para escrita deve estar em nivel logico baixo

    en1 = 0;           // saida digital RA2 para ponte H
    en2 = 0;           // saida digital RA3 para ponte H
                       // calculo de coeficientes do PID
    kp = 1;
    ki = 0;
    kd = 0;
    // calculo dos coeficientes para ponto fixo
    k1 = (kp) * SHIFT;
    k2 = (ki) * SHIFT;
    k3 = (kd) * SHIFT;

    // configuracoes TIMER0
    T0CONbits.TMR0ON = 1;
    T0CONbits.T08BIT = 1;
    T0CONbits.T0CS = 0;
    T0CONbits.T0SE = 0;
    T0CONbits.PSA = 0;
    T0CONbits.T0PS = 0b111;
    TMR0L = 22;
    // configuracoes de interrupcao
    INTCONbits.TMR0IE = 1;
    INTCON2bits.TMR0IP = 1;
    RCONbits.IPEN = 0;
    INTCONbits.GIE_GIEH = 1;
    INTCONbits.PEIE_GIEL = 0;

    while (1) {                       // inicio loop
        if (ref > fb) {               // verifica sentido de giro necessario para o motor
            en1 = 0;                  // pino 4
            en2 = 1;                  // pino 5
        } else {
            en1 = 1;
            en2 = 0;
        }
                                      // seta o PWM -> 0-1023 CCPR1L:CCPxCON<5:4>
        CCPR1L = pwm >> 2;            // 8 bits mais significativos
        CCP1CONbits.DC1B1 = pwm >> 1; // segundo bit menos significativo
        CCP1CONbits.DC1B0 = pwm;      // bit menos significativo
        delay_ms(50);
    }// fim loop 
}// fim main

Modificação_CCS_2.txt

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×