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++;
}
}