Los LED no funcionan, Simple :)

5

Objetivo

Estoy intentando cambiar el estado de un pin en el PIC24FV16KA304 dependiendo de la presión de un botón. Inicialmente, los pines se configuran como entradas; al presionar un botón, los pines cambian a una salida con un estado bajo, al presionar otro botón se mantendrán los pines como salidas, pero el estado cambiará a alto. Finalmente, al presionar el 3er botón, las clavijas volverán a las entradas. Esto se repetirá para siempre. El circuito VDD es 3V y la tierra es 0V.

Hardware

ElbotónestáconectadoaINT0(Pin43)deestePICyVDD.Alpresionarelbotón,elPin43estásiendoelevado.Lospinesqueestánsiendomanipuladosporlapresióndelbotónsonlosnúmerosdepin42(RB6)y41(RB5).

Encadapinhay2LEDS,conuntotalde4LEDenambospines.Cadapinseutilizaenlasiguienteestructura:

VDD->Resistor->LEDROJO1->RB6(SENS1)->LEDVERDE2->Resistor->Suelo.

VDD->Resistor->LEDROJO3->RB5(DEBUG_LED)->LEDVERDE4->Resistor->Suelo.

LosvaloresdelaresistenciaylosumbralesdelosLEDsehanseleccionadodemodoquesielpinseestablececomoentrada(altaimpedancia),ningunodelosLEDestáencendido.Sielpinesunasalidaa3V,elLEDverdeseencenderáexclusivamente,sies0V,elLEDrojoseencenderáexclusivamente.

EldepuradorutilizadoeselMPLABICD3

Firmware

Heescritoelsiguientefirmwareparaesteobjetivo:

//main.c#include"main.h"

//configuration registers

_FDS( DSWDTEN_OFF & DSBOREN_ON )
_FICD( ICS_PGx1 )
_FPOR( BOREN_BOR0 & LVRCFG_ON & PWRTEN_ON & I2C1SEL_PRI & BORV_LPBOR & MCLRE_ON )
_FWDT( WDTPS_PS32768 & FWPSA_PR128 & FWDTEN_OFF &  WINDIS_OFF )
_FOSC( POSCMOD_NONE & OSCIOFNC_OFF & POSCFREQ_HS & SOSCSEL_SOSCLP & FCKSM_CSDCMD )
_FOSCSEL( FNOSC_FRC & SOSCSRC_ANA & LPRCSEL_HP & IESO_OFF)
_FGS(GWRP_OFF & GSS0_OFF )
_FBS(BWRP_OFF & BSS_OFF )

//variables
unsigned char index;
unsigned char continuity = 1; //will become more clear at problem.

//main
int main()
{
    INTCON2bits.INT0EP = 0; //Sets to trigger on rising edge
    IEC0 = IEC0 | 0x0001;   //turn on INT0 interrupt default priority 4
    IFS0bits.INT0IF = 0;    // Clearing interrupt flag


    while(1)                //inf loop
    {
        if((index == 0) && (continuity == 1))    
        {
            TRISBbits.TRISB6 = 1; //sets direction
            TRISBbits.TRISB5 = 1;
            continunity = 0;    
        }else if((index == 1) && (continuity == 1))
        {
            TRISBbits.TRISB6 = 0;
            TRISBbits.TRISB5 = 0;   
            PORTBbits.RB6 = 0;   //sets port value
            PORTBbits.RB5 = 0;
            continunity = 0;                
        }else if((index == 2) && (continuity == 1))
        {
            PORTBbits.RB6 = 1;
            PORTBbits.RB5 = 1;  
            continunity = 0;    
        }else if(index == 3)
        {
            index = 0;  
        }           
    }           
}

void __attribute__((interrupt, auto_psv)) _INT0Interrupt(void)
{
    //clear the interrupt flag  
    __delay_us(50);
    if(PORTBbits.RB7 == 1)
    {
        index++;
        continuity = 1;
    }   
    IFS0bits.INT0IF = 0;
} 

Problemas

Hay varios problemas que intentaré mantener la cohesión.

  1. Los estados cambian solos la mayor parte del tiempo. Esto tiene (a veces) correlación directa con los movimientos de mi cuerpo. Puedo amplificar este error si me aferro al metal de mi teléfono mientras se está cargando y coloco mi mano sobre el tablero. Actúa como un detector proxy PERFECTO. ¿Por qué esta tabla actúa como una antena? ¿Tiene alguna sugerencia de depuración para entender lo que está pasando? Si necesitas más información avísame. SOLVED

  2. Los estados del LED son incorrectos. Como puede verse en el código, nunca puede haber 1 LED rojo (RB6) y 1 LED verde (RB5) encendidos, sin embargo, cuando se ejecuta a toda velocidad, este problema ocurre aunque la expectativa es que ambos sean verdes por ejemplo (índice = 2). Una observación interesante con respecto a este problema es que ejecuté el código a toda velocidad sin la variable de continuidad, permití que ingresara constantemente en el mismo bloque IF, índice 2, la expectativa es que ambos LED sean verdes pero uno de ellos es rojo en realidad. Luego detengo el código y comienzo a progresar en pasos individuales, y de repente comienza a funcionar. SOLVED

  3. El botón no funciona. Cuando presiono el botón no tiene efecto. Sin embargo, si engancho un osciloscopio a una vía que lo conecta al PIC, de repente comienza a funcionar correctamente, y en el osciloscopio se está comportando como debería. Si quito el osciloscopio, deja de funcionar de nuevo. Pensé que tal vez la sonda está contribuyendo en alguna capacitancia, así que conecté el condensador más pequeño que tengo (10uF) en el punto de vía exacto, y no hay cambios. ¿De qué otra manera contribuyen las sondas del osciloscopio a la placa? SOLVED

  4. Si se quita la continuidad del código, el número de Pin 43 comienza a oscilar a 400 Hz en promedio. Cuando esto sucede, ambos LEDS parecen estar encendidos al mismo tiempo para mí. Esta oscilación no es periódica, es muy aleatoria. No entiendo cómo un solo pin puede verse afectado de esta manera cuando el código no tiene ese estado. Ha desaparecido

    Notas

Personalmente creo que el hardware se ha conectado a tierra bien, y personalmente no he visto ningún problema obvio de hardware.

Si ustedes necesitan información adicional, avísenme.

HELP!

Cualquier solución o método de depuración que pueda ofrecer será muy apreciado, estoy empezando a perder cabello gracias a este problema.

¿Todos los síntomas anteriores parecen haber sido causados por el mismo problema de hardware? Si ustedes han experimentado algo similar, estoy deseando escucharlo.

    
pregunta Volcano

2 respuestas

3

Parece que necesita un resistor desplegable en INT0, (no parece mencionar que tiene uno), mi clave para necesitar un resistor de arrastre es su problema número uno, donde su cuerpo afecta el cambio de estado. Este problema surge porque tiene una entrada de alta impedancia (INT0) y está flotando, no hay garantía de que su INT0 esté bajo porque se deja flotando hasta que presione el botón y lo mantenga presionado. Agregar la resistencia de bajada hará que su estado INT0 sea bajo, también recuerde que su sonda se ve como una tapa con una resistencia en paralelo, por lo que cada vez que pruebe su circuito, básicamente está colocando una resistencia de bajada. El otro problema que veo es que su botón no es rebotar, agregando un retraso de unos pocos milisegundos no rebotará una entrada.

    
respondido por el Kvegaoro
1

La causa de los estados de LED incorrectos fue porque no estaba permitiendo suficiente tiempo entre los comandos de cambio de puerto.

Al escribir:

    PORTBbits.RB6 = 1;
    PORTBbits.RB5 = 1;  

En realidad debería ser:

    PORTBbits.RB6 = 1;
    Nop(); //skip cycle
    PORTBbits.RB5 = 1;  

La única pista de esto en la hoja de datos es que se necesita un ciclo para transferir los datos desde el cierre del puerto al puerto real.

El puerto también se puede actualizar con:

    PORTB = 0x60;

Para el mismo efecto.

    
respondido por el Volcano

Lea otras preguntas en las etiquetas