Semáforos y más semáforos

Semáforo MSP430

Que levante la mano quién no haya hecho el típico circuito de semáforo para probar una plataforma o un microcontrolador nuevo. El semáforo se podría considerar como el HolaMundo de la electrónica. Cualquier alumno de tecnología o de ingeniería podrá corroborar lo que digo. Tanto es así que el hashtag #nomassemaforos es cada día más popular en Twitter. Sobre este particular, José Antonio Vacas dio una interesante charla en Malakabot 2017 que os dejo aquí debajo.

Está claro que como ejemplo inicial, el semáforo puede ser un diseño útil, pero después hay que ir más allá. Si andáis faltos de imaginación, José Antonio os deja en su GitHub algunas ideas que os pueden servir de inspiración

Pero si pensabais que tras todo este movimiento se habían acabado los semáforos, estáis muy equivocados. Tras el hashtag #RetoSemaforos se encuentra un interesante reto propuesto por Cesar García del podcast La Hora Maker y David Cuartielles. Se trata de un proyecto colectivo para realizar semáforos en la mayor cantidad de modos posible. Dejo que ellos mismos os presenten el proyecto.

Si queréis participar sólo tenéis que acudir al GitHub de David y seguir las instrucciones. Yo por mi parte me he animado a enviar dos diseños: Uno con el TI MSP430 y otro con FreeRTOS.

El diseño del semáforo es muy simple y se muestra en el siguiente esquema, donde se indica a qué pines han de conectarse los LED. En este caso he usado una placa de desarrollo LaunchPad basada en el microcontrolador MSP430. También os dejo el código C del semáforo.

#include <msp430.h>

enum estados { ROJO, AMARILLO, VERDE };
int color;

int main(void)
{
	WDTCTL = WDTPW + WDTHOLD; 	// Detiene el watchdog
	P3DIR |= BIT0;            	// P3.0 (LED rojo) como salida digital
	P3DIR |= BIT1;            	// P3.1 (LED amarillo) como salida digital
	P2DIR |= BIT6;            	// P2.6 (LED verde) como salida digital
	P1REN |= BIT1;		  	// Resistencia en P1.1 (pulsador derecho)
	P3OUT |= BIT1;		  	// Modo pull-up
	P2OUT |= BIT1;
	P1IE  |= BIT1;			// habilita la interrupción de P1.1
	P1IES |= BIT1;			// Interrupción por flanco de bajada
	P1IFG &= ~(BIT1);		// baja flag de interrupción de P1.1 (por si acaso)

	color = ROJO;
	P3OUT |= BIT0; 			// Empezamos encendiendo el rojo
	P3OUT &= ~BIT1;			// apagamos el amarillo
	P2OUT &= ~BIT6;			// apagamos el verde

	// Activar interrupciones
	__bis_SR_register(GIE); 	// también puede usarse: __enable_interrupt()

	// Modo bajo consumo pero atendemos interrupciones
	__low_power_mode_0();		// Entrada LPM0, habilita interrupciones
	__no_operation();         	// Para depuración

}

// Rutina de gestión de interrupciones de P1
#pragma vector=PORT1_VECTOR
__interrupt
void P1_ISR(void) {
	extern int color;
	if (P1IFG & BIT1) {		// ¿fuente de la interrupción es P1.1 (pulsador)?
		switch (color) {
			case ROJO:
				color = AMARILLO;
				P3OUT &= ~BIT0;	// apagamos el rojo
				P3OUT |= BIT1;	// encendemos el amarillo
				break;
			case AMARILLO:
				color = VERDE;
				P3OUT &= ~BIT1;	// apagamos el amarillo
				P2OUT |= BIT6;	// encendemos el verde
				break;
			case VERDE:
				color = ROJO;
				P2OUT &= ~BIT6;	// apagamos el verde
				P3OUT |= BIT0;	// encendemos el rojo
				break;
		}
		P1IFG &= ~BIT1;		// puesta a cero del flag de interrupción P1.1
	}
}

Para el ejemplo de semáforo con FreeRTOS he usado la placa de desarrollo LaunchPad CC3200 que utiliza una MCU ARM Cortex A4. El esquema de conexionado con la placa y el código son los siguientes.

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "hw_types.h"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "interrupt.h"
#include "rom_map.h"
#include "prcm.h"
#include "gpio.h"
#include "pinmux.h"
#include "FreeRTOS.h"
#include "task.h"

// prototipos de función
void BoardInit(void);


// variables globales
extern void (* const g_pfnVectors[])(void);


//*****************************************************************************
// FreeRTOS User Hook Functions enabled in FreeRTOSConfig.h
//*****************************************************************************
void
vAssertCalled( const char *pcFile, unsigned long ulLine )
{
    //Handle Assert here
    while(1)
    {
    }
}

void vApplicationMallocFailedHook()
{
    //Handle Memory Allocation Errors
    while(1)
    {
    }
}

void vApplicationStackOverflowHook( void *pxTask,
                                   signed char *pcTaskName)
{
    //Handle FreeRTOS Stack Overflow
    while(1)
    {
    }
}


// Board Initialization & Configuration
void BoardInit(void)
{

    // Set vector table base
    IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);

    // Enable Processor
    MAP_IntMasterEnable();
    MAP_IntEnable(FAULT_SYSTICK);

    PRCMCC3200MCUInit();
}
  

/*-----------------------------------------------------------*/
//Esta tarea enceinde las luces del semáforo
static void SemaforoBlink( void *pvParameters )
{

	//La tarea debe tener un bucle infinito...
	for( ;; )
	{
		// Encender LED rojo
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_3,GPIO_PIN_3);
		vTaskDelay(0.5*configTICK_RATE_HZ);
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_3,0);

		// Encender LED amarillo
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_2,GPIO_PIN_2);
		vTaskDelay(0.5*configTICK_RATE_HZ);
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_2,0);

		// Encender LED verde
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_1,GPIO_PIN_1);
		vTaskDelay(0.5*configTICK_RATE_HZ);
		GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_1,0);
	}
}
/*-----------------------------------------------------------*/


// Función main
void main()
{ 

    BoardInit();	// Configuración de la placa
    PinMuxConfig();	// Pinmux donde se configuras los puertos para los LED como salida digital

    // Apagamos los LED
    GPIOPinWrite(GPIOA1_BASE,GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1,0);


	/* creamos la tarea para el semaforo */
	if (xTaskCreate( SemaforoBlink, "Semaforo", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL )!=pdPASS)
		while (1);

    vTaskStartScheduler(); // Inicia el planificador de tareas

}

Os animo a que participéis, ya que es un proyecto, además de interesante, bastante divertido.

Sé el primero en comentar en "Semáforos y más semáforos"

Deja un comentario.

Tu dirección de correo no será publicada.


*