dsPIC: ¿pierdo la funcionalidad del puerto en un pin CN?

1

Estoy probando algunos códigos con un dsPIC33FJ32MC102 en el MPLAB X con XC16. Tengo algunos interruptores dip conectados a RB0-RB2 que quiero usar para cambiar los LED conectados a RB7-RB9. Puedo hacer que los LED se enciendan manualmente con una instrucción LATB = 0x380, sin embargo, cuando enciendo los interruptores no pasa nada. He probado los interruptores y el cableado y he comprobado que todo está correcto, y por lo que puedo decir, mi código es correcto. Basándome en todas las hojas de datos que he leído, todavía debería obtener la E / S del puerto en una entrada de CN, ¿por qué no funciona esto?

Aquí está mi código (en un estado primordial, por lo que todas las configuraciones aún son detalladas):

// DSPIC33FJ32MC102 Configuration Bit Settings

// 'C' source line config statements

#define FOSC    (3686400ULL)
#define FCY     (FOSC/2)

#include <xc.h>
#include <libpic30.h>

// CONFIG2
#pragma config POSCMOD = NONE           // Primary Oscillator Select (Primary oscillator disabled)
#pragma config ALTI2C = OFF             // Alternate I2C pins (I2C mapped to SDA1/SCL1)
#pragma config LPOL = ON                // Motor Control PWM Low Side Polarity bit (PWM module low side output pins have active-high output polarity)
#pragma config IOL1WAY = ON             // IOLOCK Protection (Allow Only One Re-configuration)
#pragma config OSCIOFNC = ON            // Primary Oscillator Output Function (OSC2 pin has digital I/O function)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = FRCDIVN          // Oscillator Mode (Internal Fast RC (FRC) with divide by N)
#pragma config WDTWIN = WDTWIN25        // Watchdog Window Select (Watchdog Window is 25% of WDT period)
#pragma config PWMPIN = ON              // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)
#pragma config PWMLOCK = ON             // PWM Lock Enable (Certain PWM registers may only be written after key sequence)
#pragma config IESO = ON                // Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)

// CONFIG1
#pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128           // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config PLLKEN = ON              // PLL Lock Enable (Clock switch to PLL source will wait until the PLL lock signal is valid.)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog timer enabled/disabled by user software)
#pragma config ICS = PGD3               // Comm Channel Select (Communicate on PGEC3/PGED3)
#pragma config HPOL = ON                // Motor Control PWM High Side Polarity bit (PWM module high side output pins have active-high output polarity)
#pragma config GWRP = ON                // General Code Segment Write Protect (Writes to program memory are disabled)
#pragma config GCP = OFF                // General Segment Code Protection (General Segment Code protect is disabled)

char t1ctr = 0;
unsigned short PAin     = 0;
unsigned short PAout    = 0;
unsigned short PBin     = 0;
unsigned short PBout    = 0;

void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void){
    t1ctr++;
    if(t1ctr==40){              //after 1 second
        t1ctr = 0;
        LATAbits.LATA1 ^= 1;    //toggle the LED
    }

    IFS0bits.T1IF = 0;
}

void __attribute__((__interrupt__, __auto_psv__)) _CNInterrupt(void){
    PBin = PORTB;       //Read the port
    PBin &= 0x0007;     //get only the inputs
    PBout = PBin << 7;  //move them out to the outputs
    LATB = PBout;       
    IFS1bits.CNIF = 0;
}

void main(void){

//OSCILLATOR CONFIGS
    CLKDIVbits.ROI      = 0;
    CLKDIVbits.FRCDIV   = 0b001; //3.68MHz
    CLKDIVbits.DOZEN    = 0;
    OSCTUNbits.TUN      = 0b00000;
    OSCCONbits.CLKLOCK  = 1;

//PERIPHERAL CONFIGS
    //enable only Timer 1, PWM, and ADC
    PMD1bits.T5MD       = 1;
    PMD1bits.T4MD       = 1;
    PMD1bits.T3MD       = 1;
    PMD1bits.T2MD       = 1;
    PMD1bits.T1MD       = 0;
    PMD1bits.PWM1MD     = 0;
    PMD1bits.I2C1MD     = 1;
    PMD1bits.U1MD       = 1;
    PMD1bits.SPI1MD     = 1;
    PMD1bits.AD1MD      = 0;

    //disable Input Capture/Output Compare
    PMD2bits.IC3MD      = 1;
    PMD2bits.IC2MD      = 1;
    PMD2bits.IC1MD      = 1;
    PMD2bits.OC2MD      = 1;
    PMD2bits.OC1MD      = 1;

    //disable comparator and RTCC
    PMD3bits.CMPMD      = 1;
    PMD3bits.RTCCMD     = 1;

    //disable CTMU
    PMD4bits.CTMUMD     = 1;

//PORT CONFIGS
    //disable open drains on Port A, B
    ODCA                = 0x0000;
    ODCB                = 0x0000;

    //Enable AN0 only; digital I/O on all other pins
    AD1PCFGL            = 0x0001;
    TRISA               = 0x0001;   //AN0 must be input for ADC to work right

    //Port B
    TRISB               = 0x0007;   //In on 0,1,2
    LATB                = 0x0000;
    //IFS3bits.FLTA1IF    = 0;        //must be pulled up externally  
    //IFS4bits.FLTB1IF    = 0;

    //Clear outputs
    LATA                = 0x0000;
    //LATB already clear

    //Enable CN4,5,6 (PortB) and corresponding interrupts
    CNEN1bits.CN4IE     = 1;
    CNEN1bits.CN5IE     = 1;
    CNEN1bits.CN6IE     = 1; //pullups are disabled on reset
    IEC1bits.CNIE       = 1; 

    IPC4bits.CNIP       = 0b010; // Change on bus is priority 6 of 7

    //Set UART input to RP8 (17), output ot RP9 (18)
    /*
    RPINR18bits.U1RXR   = 0b01000;
    RPOR4bits.RP9R      = 0b00011;
    */


//TIMER CONFIGS
    //setup Timer1
    T1CONbits.TCS       = 0;        //Use internal clock
    T1CONbits.TCKPS     = 00;       //Prescale 1; ticks at 1.843200MHz
    T1CONbits.TSIDL     = 1;        //Disable during idle
    PR1                 = 46080;    //46080 ticks = 25ms to ovf
    T1CONbits.TGATE     = 0;        //dunno if this should be 0 or 1.
    IPC0bits.T1IP       = 0b001;    //Lowest priority interrupt
    IEC0bits.T1IE       = 1;        //Enable interrupts
    T1CONbits.TON       = 1;        //Turn on

    LATB = 0x0380;
    while(1){
    }
}
    
pregunta BB ON

2 respuestas

0

Se solucionó el problema. El ADC en este dsPIC está activo bajo, no activo alto, por lo que al establecer la configuración en 0x0001 se activaron todos los ADC excepto el que necesitaba, bloqueando la entrada crítica. Invertí el ajuste de configuración y ahora funciona perfectamente.

    
respondido por el BB ON
1

Muestra cómo están conectados exactamente los conmutadores a los pines del puerto. Si hizo lo normal al conectar cada conmutador entre un pin de E / S y una conexión a tierra, entonces probablemente olvidó activar los controles internos para esos pines.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas