PIC16LF1786 cambiar el pin PWM en CCP3 con APFCON1

1

PIC16 (L) F1786 tiene 3 módulos CCP. Necesito una señal PWM en el pin RB5 que pertenece al módulo CCP3, así como el pin RC6. PERO, cuando estoy configurando el PWM de acuerdo con la hoja de datos (página 277), estoy obtener señal PWM en RC6 en lugar de RB5, aunque en APFCON2 el bit CCP3SEL del registro se establece en 1. ¿Es incluso posible obtener PWM en RB5 en lugar de RC6? Y un "PERO" más: estoy usando Proteus para probar el firmware, y no sé si es un error en Proteus o me falta algo. Estoy 99% seguro de que estoy haciendo algo mal ya que este es mi segundo día de programación del microcontrolador PIC.

Gracias.

A continuación, estoy enumerando la configuración y mi código en MPLAB X IDE utilizando el compilador RC8:

#pragma config FOSC = INTOSC
#pragma config WDTE = OFF       
#pragma config PWRTE = OFF    
#pragma config MCLRE = ON   
#pragma config CP = OFF    
#pragma config CPD = OFF     
#pragma config BOREN = ON    
#pragma config CLKOUTEN = OFF   
#pragma config IESO = ON      
#pragma config FCMEN = ON       

#pragma config WRT = OFF        
#pragma config VCAPEN = OFF     
#pragma config PLLEN = OFF      
#pragma config STVREN = ON     
#pragma config BORV = LO      
#pragma config LPBOR = OFF      
#pragma config LVP = ON      

#include <xc.h>

void main(void) {
    TRISA = 0x00;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISE = 0x04;
    TRISBbits.TRISB5 = 0x01;
    TRISCbits.TRISC6 = 0x01;


    PR2 = 0x63; // PWMPeriod = (PR2(99)+1)*4*TMR2_Prescale_Value(1)/(f(8 000 000)) = 20kHz
    CCP3CONbits.CCP3M = 0x00;

    // CCP3M Mode Select bits 11xx = PWM mode
    CCP3CONbits.CCP3M3 = 0x01;
    CCP3CONbits.CCP3M2 = 0x01;

    CCPR3L = 0x32;
    CCP3CONbits.DC3B = 0x00; // CCP3L:DC3B = 0x32:0x00 = 00110010 00 = 200 DEC

    PIR1bits.TMR2IF = 0x00;

    APFCON2bits.CCP3SEL = 0x01; // CCP3SEL: CCP3 Input/Output Pin Selection bit, if 1 then CCP3 is on pin RB5

    //Timer configuration
    T2CONbits.T2CKPS = 0x00; // Timer prescale value 1:1
    T2CONbits.T2OUTPS = 0x00; // Timer postscale value 1:1
    T2CONbits.TMR2ON = 0x01; // Enable the Timer

    while(!PIR1bits.TMR2IF) // Wait until the Timer overflows and set the TMR2IF bit of the PIR1 register
    { 
        TRISBbits.TRISB5 = 0x00; // Enable the CCP3 pin output driver
    }

    while(1)
    {
    }

    return;
}
    
pregunta Arttu

1 respuesta

0

No uso Proteus, pero aquí hay un ejemplo que funciona en el simulador de MPLABX:

Este es el código completo:

/*
 * file: main.c
 * author: dan1138
 * target: PIC16F1786
 * compiler: XC8 v1.35
 * IDE: MPLABX v4.05
 * 
 * Description:
 *  Show PWM3 output on RB5 in MPLABX simulator.
 */
#pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = ON
#pragma config CP = OFF, CPD = OFF, BOREN = OFF, CLKOUTEN = OFF
#pragma config IESO = ON, FCMEN = OFF
#pragma config WRT = OFF, VCAPEN = OFF, PLLEN = OFF, STVREN = ON
#pragma config BORV = LO, LPBOR = OFF, LVP = OFF

#include <xc.h>

/*
 * Define what we expect the system oscillator frequency will be.
 */
#define FOSC (32000000ul)
#define FCYC (FOSC/4ul)
/*
 * Initialize this PIC hardware
 */
void PIC_Init( void ) {
    /* disable global interrupt sources */
    INTCON =  0;

    /* select 8MHz internal oscillator*/
    OSCCONbits.IRCF = 0b1110;
    /* Enable PLL for a 32MHZ system clock */
    OSCCONbits.SPLLEN = 1;

    /* disable all interrupt sources */
    PIE1 = 0;
    PIE2 = 0;
    PIE3 = 0;
    PIE4 = 0;

    /* Make all GPIOs inputs */
    TRISA = 0xFF;
    TRISB = 0xFF;
    TRISC = 0xFF;
    TRISE = 0xFF;

    /* set OPTION_REG to defaults */
    OPTION_REG = 0xFF;
}
/*
 * Initialize PWM3 on RB5
 */
void PWM3_Init( void ) {
    PIE3bits.CCP3IE = 0;            /* Disable CCP3 interrupts */
    PIE1bits.TMR2IE = 0;            /* Disable TIMER2 interrupts */
    TRISBbits.TRISB5 = 1;           /* Tri-state PWM3 output */
    CCP3CON = 0;                    /* Disable PWM3 */
    T2CON = 0;                      /* Stop TIMER2  */
    APFCON2bits.CCP3SEL = 1;        /* Select RB5 for CCP3 output */
    T2CONbits.T2CKPS = 1;           /* Select TIMER2 prescale as 1:4 */
    PR2 = (FCYC/(4ul*20000ul))-1;
    CCP3CONbits.CCP3M = 0b1100;     /* enable PWM3 */
    CCPR3L = (PR2+1u)>>1u;          /* Set for 50% duty cycle */
    PIR1bits.TMR2IF = 0;
    T2CONbits.TMR2ON = 1;           /* Start PWM clock source */
    while(!PIR1bits.TMR2IF);        /* wait for PWM to cycle once */
    PIR1bits.TMR2IF = 0;
    TRISBbits.TRISB5 = 0;           /* Turn on PWM3 output */
}
/*
 * Main application
 */
void main( void ) {
    unsigned char PWM_cycle_count = 9;

    PIC_Init();
    PWM3_Init();
    /* Process loop */
    for(;;) {
        if(PWM_cycle_count) {
            if(PIR1bits.TMR2IF) {
                PWM_cycle_count--;
                PIR1bits.TMR2IF = 0;
            }
            if(PWM_cycle_count == 5) {
                CCPR3L = 0; /* set duty cycle tp 0% */
            }
        } else {
             NOP(); /* put simulator breakpoint here */
        }
    }
}

El simulador MPLAB v8.92 no es totalmente compatible con PIC16F1786, por lo que la salida PWM solo está en RC6. Ninguna configuración en los registros APFCON1 o APFCON2 cambia esto.

    
respondido por el Dan1138

Lea otras preguntas en las etiquetas