Las señales PWM no se generan en el proyecto PIC

0

He abordado el siguiente proyecto proteus proffessional:

Laideaesqueelinterruptorgiratoriocontrolelavelocidaddelos2ventiladoresdeCC,laopciónaltadacomoresultadounciclodetrabajodel100%,Med75%yBajaesdel50%.EltutorialqueseguíparaconfigurarelmóduloPWMdelPIC16F877AproporcionaestaimagentomadadelmanualdelICsobrecómofuncionabásicamenteelmodoPWMdelaMCU:

  

GeneracióndeseñalPWM:unavezqueseconfiguraelPWMysehabilitaelTimer2,TMR2comienzaaincrementarsesegúnelvalorprescalar.UnavezqueelvalordeTMR2seaigualadutyCycle(CCPR1L+CCP1CON<5:4>),elpinPWMsetiraráhaciaBAJO.EltemporizadorcontinúaaumentandohastaquecoincideconelperíodoPR2.DespuésdelocualelpinPWMsejalaráALTOyTMR2serestableceráparaelpróximociclo.   Fuente

Y así escribí un código en mikroC donde configuro ambos módulos CCP ya que necesito una señal PWM para controlar la velocidad de dos ventiladores. Aquí está el fragmento de código que se supone debe configurar el modo PWM de estos registros CCP:

TRISC.RC1 = 0;
TRISC.RC2 = 0;
CCP1CON = 0x0F;  // Select the PWM mode.
CCP2CON = 0x0F;
TMR2ON = 1;
PR2 = 100;      // Set the Cycle time to 100 for varying the duty cycle from 0-100
CCPR1L = 0;     // By default set the dutyCycle to 0
CCPR2L = 0;

Cuando ejecuto la simulación funciona en proteus. Cuando intento cargarlo en la MCU con mi kit de selección 3, no obtengo una señal PWM en PORTC1-2. He comprobado que el interruptor está funcionando con un multímetro y he probado el cristal y descubrí que está oscilando. El mecanismo de conmutación no parece tener un efecto notable en las señales en el PORTC1-2, aparte de una posible falla cuando cambia la posición del interruptor.

Aquí hay una captura de pantalla de cómo se ve la señal donde se supone que debo obtener una onda PWM (PORTC1).

PORTC2 tiene el mismo aspecto. Como dije, he monitoreado el mecanismo de conmutación, he sondeado el cristal y los puertos PWM. No puedo pensar por qué esto no funcionará cuando lo hace en simulación. Tal vez alguien podría ayudarme a depurar esto. El resto del código C se muestra aquí:

    int solenoid_state = 0;

    void main() 
      {

        //TRISB = 0x0F;    // Configure PORTB
        TRISB.RB0 = 1;
        TRISB.RB1 = 1;
        TRISB.RB2 = 1;
        TRISB.RB3 = 1;
        TRISD.RD0 = 0;
        TRISD.RD1 = 0;
        TRISC.RC1 = 0;
        TRISC.RC2 = 0;
        CCP1CON = 0x0F;  // Select the PWM mode.
        CCP2CON = 0x0F;
        TMR2ON = 1;
        PR2 = 100;      // Set the Cycle time to 100 for varying the duty 
                            cycle from 0-100
        CCPR1L = 0;     // By default set the dutyCycle to 0
        CCPR2L = 0;
        //solenoid_state = 0;

        while(1){
                  if(RB0_bit == 0)                // Off state
                   {
                     delay_ms(300);
                     if(RB0_bit == 0)
                       {
                         CCPR1L = 0;
                         CCPR2L = 0;
                         RD0_bit = 0;
                         RD1_bit = 0;
                       }
       while(RB0_bit == 0)            //Do nothing until switch status changes
           {

           }
           }

          else
           {
             solenoid_state = 1;
             //RD0_bit = 1;
             //RD1_bit = 1;
           }

          while(solenoid_state == 1)
           {

             if(RB1_bit == 0)                 // Low state
               {
                 delay_ms(300);
                 if(RB1_bit == 0)
                 {
                   CCPR1L = 50;
                   CCPR2L = 50;
                 }
                 while(RB1_bit == 0)            //Do nothing until switch status changes
                  {

                  }
           }
         else if(RB2_bit == 0)            // Med state
           {
             delay_ms(300);
             if(RB2_bit == 0)
              {
                CCPR1L = 75;
                CCPR2L = 75;
              }
         while(RB2_bit == 0)           //Do nothing until switch status changes
              {

              }
           }
         else if(RB3_bit == 0)           // High state
           {
             delay_ms(300);
             if(RB3_bit == 0)
              {
                CCPR1L = 100;
                CCPR2L = 100;
              }
          while(RB2_bit == 0)         //Do nothing until switch status changes
           {

           }
           }
          else
           {
             //RD0_bit = 0;
             //RD1_bit = 0;
             solenoid_state = 0;
           }

           }
        }
    }

Cualquier consejo / sugerencia apreciada,

Simon.

    
pregunta burton01

1 respuesta

0

Otros sospechan que tus problemas con el hardware real se encuentran en la parte de tu código que MikroC dificulta para que puedas mostrar a otros.

Existen las configuraciones para las palabras de configuración de PIC y la inicialización de inicio de los bloques de funciones del convertidor analógico a digital y del comparador.

Para proyectos simples como el descrito, es útil deshabilitar las funciones ADC y Comparator y luego configurar o borrar todos los bits en las palabras de configuración a valores razonables.

Aquí se cambia el código para compilarlo con el compilador XC8 gratuito de Microchip:

/*
 * file: main.c
 * target: PIC16F877A
 * compiler: XC8 v1.45
 *
 * description:
 *  Configure for PWM output ib CCP1 and CCP2.
 *  Selector inputs from RB0, RB1, RB2, RB3.
 *
 */
#include <xc.h>

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 20000000

int solenoid_state = 0;

void main() 
{
    INTCON = 0;         // disable interrupts
    ADCON1 = 0x06;      // disable ADC
    CMCON  = 0x07;      // disable Comparators

    //TRISB = 0x0F;     // Configure PORTB
    TRISBbits.TRISB0 = 1;
    TRISBbits.TRISB1 = 1;
    TRISBbits.TRISB2 = 1;
    TRISBbits.TRISB3 = 1;
    TRISDbits.TRISD0 = 0;
    TRISDbits.TRISD1 = 0;
    TRISCbits.TRISC1 = 0;
    TRISCbits.TRISC2 = 0;
    CCP1CON = 0x0F;     // Select the PWM mode.
    CCP2CON = 0x0F;
    T2CON   = 0x01;     // Set TIMER2 prescale as 1:4
    TMR2ON = 1;
    PR2 = 99;           // Set the Cycle time to 100 for varying the duty cycle from 0-100
    CCPR1L = 0;         // By default set the dutyCycle to 0
    CCPR2L = 0;
    solenoid_state = 0;

    while(1)
    {
        if(PORTBbits.RB0 == 0)              // Off state
        {
            __delay_ms(300);
            if(PORTBbits.RB0 == 0)
            {
                CCPR1L = 0;
                CCPR2L = 0;
                PORTDbits.RD0 = 0;
                PORTDbits.RD1 = 0;
            }
            while(PORTBbits.RB0 == 0)       //Do nothing until switch status changes
            {

            }
        }

        else
        {
            solenoid_state = 1;
            //PORTDbits.RD0 = 1;
            //PORTDbits.RD1 = 1;
        }

        while(solenoid_state == 1)
        {

            if(PORTBbits.RB1 == 0)          // Low state
            {
                __delay_ms(300);
                if(PORTBbits.RB1 == 0)
                {
                    CCPR1L = 50;
                    CCPR2L = 50;
                }
                while(PORTBbits.RB1 == 0)   //Do nothing until switch status changes
                {

                }
            }
            else if(PORTBbits.RB2 == 0)     // Med state
            {
                __delay_ms(300);
                if(PORTBbits.RB2 == 0)
                {
                    CCPR1L = 75;
                    CCPR2L = 75;
                }
                while(PORTBbits.RB2 == 0)   //Do nothing until switch status changes
                {

                }
            }
            else if(PORTBbits.RB3 == 0)     // High state
            {
                __delay_ms(300);
                if(PORTBbits.RB3 == 0)
                {
                    CCPR1L = 100;
                    CCPR2L = 100;
                }
                while(PORTBbits.RB2 == 0)   //Do nothing until switch status changes
                {

                }
            }
            else
            {
                //PORTDbits.RD0 = 0;
                //PORTDbits.RD1 = 0;
                solenoid_state = 0;
            }
        }
    }
}

Quizás todas las necesidades de tu código sean estas líneas:

    INTCON = 0;         // disable interrupts
    ADCON1 = 0x06;      // disable ADC
    CMCON  = 0x07;      // disable Comparators
    
respondido por el Dan1138

Lea otras preguntas en las etiquetas