Hola a todos!! bueno después de estar unos cuantos días liado con las clases y demás por fin puedo volver a escribir algo. En esta ocasión voy a proponeros un pequeño proyecto que de irá ampliando a medida que vayamos aprendiendo cosas. El proyecto que os propongo es el control de un cruce de semáforos mediante el pic18f2550 (valdría cualquier pic de la gama 18f), que, en este caso, funcione con un reloj de 8MHz. Este proyecto que puede parecer sencillo podemos complicarlo todo lo que queramos, desde añadirle sensores que alteren el ciclo normal, por ejemplo cuando hay un atasco, o conectarlo al PC de manera que podamos monitorizar e incluso controlar el cruce.
En esta primera entrega vamos a hacer que los semáforos funcionen de manera cíclica como puede funcionar cualquier cruce de semáforos en la realidad.
Cruce de semáforos |
Como veis en la imagen, es un cruce bastante sencillo que consta de 2 semáforos para los vehículos, y dos semáforos para los peatones. Existe una calle principal, donde se supone que hay mas afluente de vehículos, y una calle secundaria, cada una de ellas con 1 semáforos para vehículos y otro semáforo para peatones.
En la siguiente tabla podéis ver la asignación que hemos hecho de los puertos a cada una de las salidas, y las que activaremos en cada ciclo.
Tabla asignación puertos y ciclos |
Como Veis, utilizamos el puerto B entero, y dos salidas del puerto C. Como suponemos que la calle principal tiene más afluente de vehículos que la secundaria, la luz verde de esta (Verde Coches Primaria VCP) dura mas tiempo que su análoga en la secundaria. hay dos tiempos que se repiten que corresponden al momento en que se encienden las luces ámbar.
A continuación tenéis el código que he utilizado.
#-------------------------------------------------------------
#include <p18F2550.h>
// Bits de configuración
#pragma config WDT=OFF
#pragma config FOSC=HS
#pragma config DEBUG=OFF
#pragma config LVP=OFF
#pragma config MCLRE = OFF
void main (void)
{
TRISB=0; //PUERTO C COMO SALIDA
TRISCbits.TRISC0=0; //BIT 0 PUERTO B COMO SALIDA
TRISCbits.TRISC1=0; //BIT 1 PUERTO B COMO SALIDA
T0CON=0x87; //MODO 16 BITS,FUENTE OSCILADOR,PREES.256
PORTB=0x32; //INICIALIZAMOS EL PUERTO B PARA PRIMER CICLO
PORTC=0x01; //INICIALIZAMOS EL PUERTO C PARA PRIMER CICLO
TMR0H=26473>>8;
TMR0L=26473; //CARGAMOS EL VALOR PARA EL PRIMER CICLO(5s)
while (1){
while(INTCONbits.TMR0IF==0); //ESPERAMOS A QUE CUENTE
if(INTCONbits.TMR0IF){
PORTB=0x52;
PORTC=0x01; //SEGUNDO CICLO
TMR0H=57723>>8;
TMR0L=57723; //CARGAMOS TEMPORIZACIÓN SEGUNDO CICLO(1s)
INTCONbits.TMR0IF=0; //BORRAMOS FLAG DE TMR0
}
while(INTCONbits.TMR0IF==0); //ESPERAMOS A QUE CUENTE
if(INTCONbits.TMR0IF){
PORTB=0x85;
PORTC=0x02; //TERCER CICLO
TMR0H=42098>>8;
TMR0L=42098; //CARGAMOS TEMPORIZACIÓN TERCER CICLO(3s)
INTCONbits.TMR0IF=0; //BORRAMOS FLAG DE TMR0
}
while(INTCONbits.TMR0IF==0); //ESPERAMOS A QUE CUENTE
if(INTCONbits.TMR0IF){
PORTB=0x89;
PORTC=0x02; //CUARTO CICLO
TMR0H=57723>>8;
TMR0L=57723; //CARGAMOS TEMPORIZACIÓN CUARTO CICLO(1s)
INTCONbits.TMR0IF=0; //BORRAMOS FLAG DE TMR0
}
while(INTCONbits.TMR0IF==0); //ESPERAMOS A QUE CUENTE
if(INTCONbits.TMR0IF){
PORTB=0x32;
PORTC=0x01; //PRIMER CICLO
TMR0H=26473>>8;
TMR0L=26473; //CARGAMOS TEMPORIZACIÓN SEGUNDO CICLO(5s)
INTCONbits.TMR0IF=0; //BORRAMOS FLAG DE TMR0
}
}
}
#-------------------------------------------------------------
El cálculo de los valores de recarga no lo voy a explicar ya que está explicado en esta entrada anterior. Como explicaremos más adelante, este programa es muy poco eficiente ya que mientras estamos esperando a que el temporizador llegue al final, el microcontrolador está detenido, y no podemos, por ejemplo, poner un pulsador de avería que en cualquier momento ponga todos los semáforos en ámbar, problema que solucionaremos cuando expliquemos las interrupciones.
Un saludo
Descargas:
No hay comentarios:
Publicar un comentario