Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  

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






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

×