problema de flujo del programa PIC C XC8

-1

Problema: Mi código C no se está ejecutando hasta el final.

Para probar mi lectura y escritura de EEPROM, decidí escribir una matriz simple y leerla de nuevo en una matriz diferente usando un PIC. Sin embargo, el problema no es la EEPROM, ya que parece que mi código c no se ejecuta hasta el final. Decidí ir a través de bit-banging antes de intentar usar el EUSART.

Hay tres instrucciones para hacer:

  • EWEN (habilitar escritura)
  • escribir
  • Lee

Para eso tengo seis funciones básicas, dos para cada parte: EWENdata, EWENArray, sendData ..... etc.

Se supone que

Main debe llamar a EWENdata, que debería hacer que el código envíe la instrucción EWEN, luego esperar un poco y llamar a sendData, luego esperar un poco y llamar a receiveData. Sin embargo, el código parece detenerse después de completar la función sendArray (). Confirmé a través de puntos de interrupción que va a la última línea de sendArray (). Después de eso, la ejecución del programa parece desaparecer en el aire. He puesto el código a continuación. (PROBLEMA PRINCIPAL)

Lo siento si no he explicado mi código más. Lo puse a continuación, así que no estoy seguro de cuánta más explicación necesito escribir o si soy redundante, pero si necesita que le explique más, solo pregunte.

Gracias por tomarse el tiempo de revisar la pregunta.

El PIC que estoy usando es el PIC16F1764 y el EEPROM es el 93LC66BX.

#include <stdio.h>
#include <stdlib.h>

#include <xc.h>
#include "eeprom64lcconfig.h"

/*
 * 
 */

#define _XTAL_FREQ 16000000

char arrayEWEN[] = {1,0,0,1,1};
char arraytosend[] = {1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0};
char arrayreceived[27] = {1,1,0,0,0,0,0,0,0,0,1};
char arraycount = 0;
bit messagesent = 0b0;
bit sendNow = 0b0;
bit receiveNow = 0b0;
bit EWENnow = 0b0;


void EWENArray()
{
    if(arraycount < 5)
    {
        LATC2 = arrayEWEN[arraycount];
        arraycount++;
    }
    else if(arraycount > 4 && arraycount < 11)
    {
        arraycount++;
        //Do nothing for 7 cycles 
    }
    else //if(arraycount > 10)
    {        
        PIE3bits.PWM5IE = 0b0;
        arraycount = 0;
        EWENnow = 0b0;
        LATC4 = 0b0;
        messagesent = 0b1;
    }
}

void EWENdata()
{
    EWENnow = 0b1;
    PIE3bits.PWM5IE = 0b1;
}

void sendArray()
{
    if(arraycount < 27)
    {
        LATC2 = arraytosend[arraycount];
        arraycount++;
    }
    else if(arraycount == 27)
    {
        PIE3bits.PWM5IE = 0b0;
        arraycount = 0;
        sendNow = 0b0;
        LATC4 = 0b0;
        messagesent = 0b1;
    }

}

void sendData()
{
    sendNow = 0b1;        
    PIE3bits.PWM5IE = 0b1;
}

void receiveArray()
{
    if(arraycount < 11)
    {
        LATC2 = arrayreceived[arraycount];
        arraycount++;
    }
    else if(arraycount > 10 && arraycount < 27)
    {
        arrayreceived[arraycount] == PORTCbits.RC1;
        arraycount++;
    }
    else //if(arraycount > 26)
    {
        PIE3bits.PWM5IE = 0b0;
        receiveNow = 0b0;
        arraycount = 0;
        LATC4 = 0b0;
        messagesent = 0b1;
    }

}

void receiveData()
{
    receiveNow = 0b1;
    PIE3bits.PWM5IE = 0b1;
}

int interrupt interruptSorter()
{
    if(PWM5INTFbits.PRIF == 0b1)
    {
        if(EWENnow == 0b1)
        {
            LATC4 = 0b1;
            EWENArray();
        }

        else if(sendNow == 0b1)
        {
            LATC4 = 0b1;
            sendArray();            
        }
        else if(receiveNow == 0b1)
        {
            LATC4 = 0b1;
            receiveArray();
        }        
    }
    INTCONbits.GIE = 0b1;        
}

int main()
{
    OSCCONbits.SPLLEN = 0b0;
    OSCCONbits.IRCF = 0b1111;
    OSCCONbits.SCS = 0b00;
    /*
     * SPLLEN OFF because you aren't using the 4xPLL
     * IRCF is set to select a 16MHz internal oscillator frequency
     * SCS is set to tell the micro to use the clock source defined in
     * the config words. That is internal oscillator at this time
     */

    __delay_ms(100); //For Debug, because debug takes away Power-up Timer.

    ANSC2 = 0b0;
    TRISC2 = 0b0;
    TRISC4 = 0b0;
    ANSC1 = 0b0;
    TRISC1 = 0b1;
    /* 93LC66BX PIN CONNECTIONS
     * C1-DO, C2-DI, C3-CLK, C4-CS
     */
    //C3 setup in PWM function 


    setupInterrupts();
    startPWM();

    ///////////////////////////////EWEN
    EWENdata();
    while(messagesent == 0b0)
    {

    }
    messagesent = 0b0;
    __delay_ms(20);

    ///////////////////////////////SEND
    sendData();
    messagesent = 0b1;
    while(messagesent == 0b0)
    {

    }
    messagesent = 0b0;
    __delay_ms(20);

    /////////////////////////////RECEIVE
    receiveData();
    while(messagesent == 0b0)
    {

    }
    messagesent = 0b0;
    __delay_ms(20);

    NOP(); //Just for use as a breakpoint spot.

    return 0;
}

En otro archivo, las funciones startPWM () y setupInterrupts.

void startPWM()
{
    //PPS setup
    TRISC3 = 0b0;
    RC3PPS = 0b10000;
    /*
     * TRISC3 - Set C3 as output
     * RC3PPS - Set RC3 to link to the output of PWM5
     */

    //PWM Clock Control
    PWM5CLKCONbits.PS = 0b000;
    PWM5CLKCONbits.CS = 0b00;
    /*
    * PS - The PWM clock is used without a prescaler
    * CS - The PWM clock source is the system FOSC
    */

    PWM5CONbits.POL = 0b0;
    PWM5CONbits.MODE = 0b00;
    /*
     * POL set to make active HIGH
     * MODE set to select Standard PWM mode
     * OE - Enables the PWM output
     */


    //FOR 10% 100KHz 
    PWM5PH = 1440;
    PWM5DC = 1600;
    PWM5PR = 1610;

    /*
     * PWM1PH starts first, is number of PWM clock cycles spent low
     * PWM1DC has been counting during PH, takes signal high when PH is over
     * PWM1PR resets the counter
     */


    PWM5CONbits.EN = 0b1;
    //EN - Enables the PWM module. The last step
}

void setupInterrupts()
{
    INTCONbits.GIE = 0b1;
    INTCONbits.PEIE = 0b1;
    /*
     * GIE set to enable interrupts 1
     * PEIE set to enable peripheral(PWM, ADC etc.) interrupts 1
     */

    //PIE3bits.PWM5IE = 0b1;
    //PWM5IE set to allow PWM5 to generate interrupts 1.

    PWM5INTEbits.PRIE = 0b1;
    //PWM5 set to generate interrupts on period match
}

Cualquier ayuda sería apreciada.

    
pregunta Alaba Baju

1 respuesta

0

Gracias por todos los comentarios, solucioné el problema unos días después. Un error muy simple. Olvidé borrar el indicador de interrupción para la coincidencia de período una vez que ingresé a la función de interrupción. Anteriormente mencioné que ejecuté este código para alternar un puerto y probar que funcionaba mi función de interrupción. Sin embargo, cuando reemplacé el código dentro de la función de interrupción, borré por error la línea de código que borraba el indicador de coincidencia de período.

Esto

int interrupt interruptSorter()
{
    if(PWM5INTFbits.PRIF == 0b1)
    {            
        if(EWENnow == 0b1)
        {
            LATC4 = 0b1;
            EWENArray();            
        }
        .
        .
        .

debería ser esto

int interrupt interruptSorter()
{
    if(PWM5INTFbits.PRIF == 0b1)
    {
        //I forgot this line below
        PWM5INTFbits.PRIF = 0b0;

        if(EWENnow == 0b1)
        {
            LATC4 = 0b1;
            EWENArray();            
        }
        .
        .
        .

Aprecio el tiempo que las personas que comentaron pasaron mi desafío. Gracias.

    
respondido por el Alaba Baju

Lea otras preguntas en las etiquetas