martes, 8 de septiembre de 2015

ISR con MQX KDS 3.0 SDK 1.2 con Eventos

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,WHITEcolor;
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:


No hay comentarios:

Publicar un comentario