Cómo simplificar los controladores de interrupción UART en Tiva TM4C con SIMcom 900

1

UARTIntHandler0 se conecta al USB UART para la depuración.

UARTIntHandler1 se conecta al módulo GSM SIM900.

El propósito de UARTIntHandler0 es muy simple: tome un carácter entrante y empújelo a UART1 (el módulo GSM).

UARTIntHandler1 es más complicado. En el "modo de conversación", debería permitirle al usuario hablar directamente con el módulo GSM, es decir, cualquier carácter que venga en el UART simplemente se envía al otro UART para que el usuario pueda verlo a través de la conexión del terminal.

En el modo normal, la interrupción es activada por cualquier entrada del GSM y realiza algún procesamiento si esta entrada es una notificación de mensaje. Cualquier otra entrada es ignorada por el controlador de interrupciones (pero aún así llena el búfer, donde otras partes del código pueden acceder a él).

Sé que el UARTIntHandler1 (y posiblemente el otro también) es demasiado grande para una rutina de interrupción: cuando el programa haya terminado, habrá al menos siete fuentes de interrupción (GSM UART, consola UART, ADC, tres temporizadores, y la interrupción de hardware desde el teclado), así que quiero mantenerlos cortos.

Mi pregunta es , ¿cuánto debo esperar que haga en esta situación y cuánto debo transferir a una función diferente al establecer marcas para el programa principal? Tenga en cuenta que este código funciona la mayor parte del tiempo, pero es cuando no funciona (señal de la celda, mensajes largos, etc.) lo que realmente duele. Sospecho que mi manejo de interrupciones es el problema.

En mi programa principal, tengo un superloop en ejecución que verifica periódicamente si el recuento de mensajes se ha incrementado.

Algunas cosas globales:

// Used by UART interrupt handlers
unsigned char var;                  // Incoming UART character
unsigned char ptr[10000];           // Array for storing incoming UART characters
unsigned long i;                    // UART character pointer.
unsigned long ulStatus0,ulStatus1;  // To hold the interrupt status  

La consola UART:

void
UARTIntHandler0(void)
{
    // Get the interrupt status.
    ulStatus0 = ROM_UARTIntStatus(UART0_BASE, true);

    // Clear the asserted interrupts
    ROM_UARTIntClear(UART0_BASE, ulStatus0);

    // Loop while there are characters in the receive FIFO.
    while(ROM_UARTCharsAvail(UART0_BASE))
    {
        // Grab a character
        var = (unsigned char)ROM_UARTCharGetNonBlocking(UART0_BASE);

        // Hold it
        ptr[i] = var;

        // Mirror it to GSM
        ROM_UARTCharPutNonBlocking(UART1_BASE, ptr[i]);

        // Proceed to next character
        i++;
    }
}

El GSM UART:

void
UARTIntHandler1(void)
{
    char *msgCountStr;                  // Number of new messages
    static char g_cInput[128];          // String input to a UART

    // Get the interrupt status.
    ulStatus1 = ROM_UARTIntStatus(UART1_BASE, true);

    // Clear the asserted interrupts.
    ROM_UARTIntClear(UART1_BASE, ulStatus1);

    // Interrupt trigger means GSM is on
    if ( GSMoff ) { GSMoff = false; }

    // Loop while there are characters in the receive FIFO.
    while(ROM_UARTCharsAvail(UART1_BASE))
    {
        // Grab a character
        var = (unsigned char)ROM_UARTCharGetNonBlocking(UART1_BASE);

        // Hold it
        ptr[i] = var;

        // In talk mode mirror to console...
        if (talkMode) { ROM_UARTCharPutNonBlocking(UART0_BASE, ptr[i]); }

        // ...or else see if it's a message notification (like +CMTI: "SM",12):
        else 
        {
            if(ptr[i-3] == 'C' && ptr[i-2] == 'M' && ptr[i-1] == 'T'&& ptr[i] == 'I')
            {
                // Grab everything
                UART1gets(g_cInput,sizeof(g_cInput));

                // Stop after newline character
                msgCountStr = strtok(g_cInput,"\n");

                // Parse out the message count (terminate with null to store)
                strncpy(msgCountStr,msgCountStr+7,3);
                msgCountStr[3]='
// Used by UART interrupt handlers
unsigned char var;                  // Incoming UART character
unsigned char ptr[10000];           // Array for storing incoming UART characters
unsigned long i;                    // UART character pointer.
unsigned long ulStatus0,ulStatus1;  // To hold the interrupt status  
'; // Convert to integer sscanf(msgCountStr, "%d", &msgCount); // Tell the user UART0printf("\n\r>>> %u NEW MESSAGE(S)",msgCount); } } // Proceed to next character i++; } }
    
pregunta LShaver

3 respuestas

1

Por lo general, la idea es que tomes el personaje, lo pongas en un búfer circular y manejes los datos en una función Llamado desde el superloop. Al hacerlos parece, todo lo que necesita es manejar adecuadamente la circularidad. De hecho, en su controlador UART1 no veo ningún tipo de condición para verificar el desbordamiento del búfer en los datos entrantes. Debería ajustarme al tamaño de lo que sea a lo que apunta.

En una aplicación similar, tengo 3 buffers, uno para manejar los datos que vienen de la PC (tengo que analizarlos un poco), uno para manejar los datos que llegan de la radio y uno temporal para el análisis.

    
respondido por el Jan Dorniak
0
  

cuánto debería esperar que haga en esta situación y cuánto debo entregar a una función diferente

Hacer las instrucciones en su rutina de servicio de interrupción al pasar el manejo a una función diferente no hace ninguna diferencia. Lo que sucede cuando llega la interrupción es que el "subproceso" actual de la CPU se detiene y se le da prioridad al servicio de interrupción. El manejo de la interrupción a otra función dentro de esa rutina de interrupción no tiene sentido

    
respondido por el Funkyguy
0

Una cosa que puedes hacer es establecer diferentes prioridades para cada interrupción. Por ejemplo, puede establecer la prioridad más alta para sus temporizadores, y luego las prioridades más bajas para los uarts. El microcontrolador TivaC tiene 8 niveles diferentes. 0 es el más alto y 7 es el más bajo. Este es un ejemplo de la página 354 de la Guía del usuario de la biblioteca de controladores periféricos de TivaWare ™ .pdf

// // Establezca la prioridad de interrupción de UART 0 en la prioridad más baja. // IntPrioritySet(INT_UART0, 0xE0);

También tengo el mismo problema, pero es con xbee en el orden de módulo gsm.

    
respondido por el Thiago Onofre

Lea otras preguntas en las etiquetas