Objetivo
Realizar la coordinación del encendido del LED RGB utilizando una
estructura de interrupciones ISR, con Eventos de MQX.
Descripción del Programa
El contenido de la práctica, se describe a continuación:
El programa principal (main.c) enlista, mediante una estructura, las
tareas que desarrollará el mismo. En este caso, se tiene una sola tarea.
Además, se realiza la estructura perteneciente a la interrupcíón, declarando
una variable y un apuntador de dicha estructura. También se declaran las
funciones de las interrupciones de los puertos A y C; en el puerto A se realiza
el incremento tanto del contador global como de un contador de
interrupciones, mientras que el puerto C incremente el contador de interrupciones,
y decrementa el contador global. Además, ambas funciones llaman al evento con
el valor actual del contador del evento.
La tarea del programa realiza la creación del evento, además de
habilitar el uso de los pines (LEDs), habilitar las interrupciones y comprobar
si se realizó dicha acción correctamente. En el lazo infinito, se espera por la
bandera del evento, para imprimir el valor del contador global, el contador del
puerto A y del puerto C, asi como encender el LED del color correspondiente.
El archivo LED_RGB.h contiene la enumeración de los colores que se
utilizarán para el encendido del LED. Además contiene el protocolo de las
funciones para el encendido del LED y la impresión del color correspondiente.
El archivo LED_RGB.c realiza, de acuerdo al valor del color deseado,
encender la combinación de LEDs correspondiente para generar el color deseado.
Así mismo, permite la impresión del color correspondiente.
Códigos del Programa
-
main.c
#include <stdio.h>
#include <assert.h>
#include <mqx.h>
#include <bsp.h>
#include <fsl_interrupt_manager.h>
#include "LED_RGB.h"
#include"lwevent.h"
#define EVENT_COUNTER
1
#define MAIN_TASK
10
void main_task(uint32_t initial_data);
_mqx_uint G_Counter;
LWEVENT_STRUCT lwevent;
const TASK_TEMPLATE_STRUCT MQX_template_list[]
=
{
/* Indice de la Tarea,
Funcion, Stack, Prioridad, Nombre, Atributos, Parametro,
Fraccion de tiempo */
{ MAIN_TASK, main_task, 1000, 8,
"Main", MQX_AUTO_START_TASK,
0, 0 },
{ 0 }
};
typedef struct my_isr_struct
{
void *OLD_ISR_DATA;
INT_ISR_FPTR OLD_ISR;
_mqx_uint Counter;
} MY_ISR_STRUCT, * MY_ISR_STRUCT_PTR;
MY_ISR_STRUCT isr_data_PORTA,isr_data_PORTC;
void new_isr_PORTA(void *user_isr_ptr)
{
MY_ISR_STRUCT_PTR isr_ptr;
PORT_HAL_ClearPortIntFlag(PORTA_BASE_PTR);
isr_ptr = (MY_ISR_STRUCT_PTR)user_isr_ptr;
isr_ptr->Counter++;
G_Counter++;
_lwevent_set(&lwevent,EVENT_COUNTER);
}
void new_isr_PORTC(void *user_isr_ptr)
{
MY_ISR_STRUCT_PTR isr_ptr;
PORT_HAL_ClearPortIntFlag(PORTC_BASE_PTR);
isr_ptr = (MY_ISR_STRUCT_PTR)user_isr_ptr;
isr_ptr->Counter++;
G_Counter--;
_lwevent_set(&lwevent,EVENT_COUNTER);
}
/*TASK*----------------------------------------------------------
*
* Nombre de la
tarea : main_task
* Comentarios :
* Esta
tarea demuestra la instalación de la interrupción en MQX.
*END*-----------------------------------------------------------*/
void main_task(uint32_t initial_data)
{
INT_ISR_FPTR old_isr_PORTA,old_isr_PORTC;
_lwevent_create(&lwevent,LWEVENT_AUTO_CLEAR);
GPIO_DRV_Init(switchPins,ledPins);
/* Habilita la interrupción para
PORTA_IRQn*/
INT_SYS_EnableIRQ(PORTA_IRQn);
/* Habilita la interrupción
para PORTC_IRQn*/
INT_SYS_EnableIRQ(PORTC_IRQn);
/** Demostracion de la intalación de
la interrupción de mqx. Trabaja con la tabla de vectores ubicada en RW como en
RO memory **/
G_Counter=0;
isr_data_PORTA.Counter = 0;
isr_data_PORTA.OLD_ISR_DATA = _int_get_isr_data(PORTA_IRQn);
isr_data_PORTA.OLD_ISR = _int_get_isr(PORTA_IRQn);
isr_data_PORTC.Counter = 0;
isr_data_PORTC.OLD_ISR_DATA = _int_get_isr_data(PORTC_IRQn);
isr_data_PORTC.OLD_ISR = _int_get_isr(PORTC_IRQn);
/* Instala la rutina de interrupción
de MQX. No cambia la tabla del vector.*/
old_isr_PORTA = _int_install_isr(PORTA_IRQn, new_isr_PORTA, &isr_data_PORTA);
old_isr_PORTC =
_int_install_isr(PORTC_IRQn,
new_isr_PORTC, &isr_data_PORTC);
/* Verifica si _int_install_isr
devuelve lo mismo que _int_get_isr*/
assert(old_isr_PORTA == isr_data_PORTA.OLD_ISR);
assert(old_isr_PORTC ==
isr_data_PORTC.OLD_ISR);
/* Llama a la interrupción por
software 10 veces cada 10ms */
while(TRUE)
{
_lwevent_wait_for(&lwevent,EVENT_COUNTER,FALSE,NULL);
printf("Counter
= %d C_PtoA = %d C_PtoC = %d ", G_Counter,
isr_data_PORTA.Counter, isr_data_PORTC.Counter);
printf_color(G_Counter&0x7);
led(G_Counter&0x7);
}
_task_block();
}
/* EOF */
-
LED_RGB.h
#ifndef LED_RGB_H_
#define LED_RGB_H_
#define SIZE_ARR
8
typedef char string[SIZE_ARR];
typedef enum {BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE} color;
enum bits{B0=1,B1=2,B2=4,B3=8,B4=0X10,B5=0X20,B6=0X40,B7=0X80};
void led(color);
void printf_color(color dato);
#endif /* LED_RGB_H_ */
-
LED_RGB.c
#include "LED_RGB.h"
#include <bsp.h>
#include <stdio.h>
void led(color dato)
{
GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_RED,!(dato&B0));
GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_GREEN,!(dato&B1));
GPIO_DRV_WritePinOutput(BOARD_GPIO_LED_BLUE,!(dato&B2));
}
void printf_color(color dato)
{
string color_names[]={"Black","Red","Green","Yellow","Blue","Magenta","Cyan","White"};
printf("%s\n",color_names[dato]);
}
Refencias
Manual de
microcontroladores de la serie K64:
Para conocer el curso completo de Essentials Course
of MQX, visita la página: