Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
He creido oportuno abrir un hilo sobre este tema ya que deberemos ir coordinandonos para la realizacion del programa de los cascos ultrasonicos.
Tal como lo veo yo y despues de haber hecho el programa pilot de los actuadores, creo que el flujo del programa podria ser el siguiente:
Se enpezaria con la definicion de variables, puertas, timers, etc y con la programacion de las interrupciones.
Se inicializa la primera cuenta de 10ms.
Inicio del programa
Condicion! ha pasado 0,1 segundos desde la ultima vez? (variable=0/1)
{
Se lanza la señal de puesta en marcha del ultrasonidos:
Se dispara el ultrasonidos, se dan valores a las variables que sean necesario y se activa la interrupcion.
Se analizan los valores de la variable donde se guardan los datos de los ultrasonidos.
Aqui se analizaria el valor de tiempo devuelto por el ultrasonidos y se valoraria de 0 a 4 poniendo este valor en otra variable para su utilizacion por el subprograma correspondiente. De esta forma Ale, puede jugar con los ultrasonidos recibiendo los valores como mas le convenga, pero resumiendolos en esos 5 valores y asi, el subprograma actuadores sabe que valores recibira segun la distancia.
}
subprograma de sonidos, iluminacion y deteccion IR:
Este programa correra cada 10ms con lo cual temporizara la frecuencia de los sonidos (no la frecuencia del sonido) la presencia o no de señal IR y los pasara a los actuadores.
Se van contabilizando los periodos de 10ms al llegar a 100 se aplica la condicion de que han pasado 0,1seg.
Las demas partes del programa que quieran contar tiempos de 10ms en 10ms ponen las rutinas de esas cuentas aqui.
{
Temporizacion 10ms
}
Vuelve a "inicio del programa"
Creo que la interrupcion por temporizacion del ultrasonidos, lo unico que tiene que hacer es poner el valor en una variable y luego ya se analizara en la parte correspondiente, es para no perder tiempo con la interrupcion. Con esto caca 10ms tenemos actualizacion de sonido e IR y cada 0,1 segundos actualizacion de distancia.
En ralidad, por ejemplo, la cosa iria asi
se lanza el ultrasonido (cada 0,1 seg)
Se analiza el dato ultrasonico de la vez anterior (cada 0,1 seg)
Los actuadores actuan (cada 10ms)
En cualquier momento se produce la interrupcion por el eco. (una vez cada 0,1 seg) El resto del tiempo hasta 0,1 seg. el ultra descansa.
Pasamos a perder tiempo 10ms (cada 10ms)
Bueno ya os pasare esto en formato programa, solo mi parte y el espacio donde iria situado lo otro, en ASM, es como programo yo.
Este es el codigo que probare cuando vuelva a Sevilla, pero segun el Mplab deberia de funcionar xD
//Codigo para probar el funcionamiento de los medidores de distancia
//por ultrasonidos SFR05
//Hecho por Garrocha @gmail.com
//Licencia Creative Commons en la versión Attribution and Share Alike.
//Es decir se permite copiar, modificar y distribuir este material
//siempre que se reconozca al autor y se mantenga la misma licencia
//En caso de existir compilador GNU capaz de compilar este codigo se
//aplicara licencia GNU-GPL
#include <pic>
#define PB(port,bit) ((unsigned)&(port)*8+(bit))
#define MIFLAG(direccion,bit) ((direccion)*8+(bit))
#define MEMFLAG 0x21 //Byte destinado a flags
void disparo (void);
void simplifica (void);
//---
static bit Sonar @ PB(PORTB,0);
static bit gatillo @ PB(PORTB,1);
static bit damedat @ PB(PORTB,2);
//---
char DatoL @ 0x22; // en 0x22 guardaremos el valor en bruto de la distancia
char DatoH @ 0x23;
char Resultado @ 0x60;
char Contador @ 0x24;
bit Flagtmr @ MIFLAG(MEMFLAG,0); //Lo usaremos de referencia para saber si el tmr esta funcionando 1=Si 0=No
main(void)
{
//---
TRISB|=00000110; //Configuracion del TRISB para que funcione el gatillo
TRISC=0; //A = Salida, solo para este prog
//---
TRISB&=0b11111110; //Patila RB0 como salida
Sonar=0; // y a cero
TMR1H=0; //Limpiamos el timer1 "porsiacaso"
TMR1L=0; //Parte alta y baja
Flagtmr=0; //y demas variables
Resultado=0;
while(1) //Bucle infinito para que el programa este siempre ejecutandose
{ //Esto es un programa de prueba de las funciones
PORTC=Resultado;
if(gatillo)
{
disparo(); //Funcion que activa al sonar
}
if(damedat)
{
simplifica(); //Funcion que transforma el dato del sonar en un valor entre 0 y 4
}
}
}
void disparo (void)
{
//Poner RC0 a 1 durante al menos 10uS
//10uS=1/10^5 S = 0,1MHz, como tenemos un reloj de 4Mhz, el tiempo de insruccion
//es de 1uS, basta con gastar 10 instruccione para que el sonar se de por enterado
//Para ello usaremos un bucle para sumar hasta 10, de todas formas en asm seran unas
//cuantas lineas mas, asi que no hay problema
for(Contador=0;Contador<=10;Contador++)
{
Sonar=1;
};
Sonar=0; //Ponemos a cero
TRISB|=1; //y configuramos RB2 como entrada
//Ea, ya hemos dao la orden al sensor de que haga la medición
//ahora activaremos la interrupción para la recepcion
RBIE=1; //Interrupcion en caso de cambio del RB0
INTEDG=1; //En flanco ascendente
INTE=1; //Damos permiso a las interrupciones externas (como lo es la patilla RB0)
GIE=1; //Global
//Hasta aqui todo lo necesario para poner en marcha el sonar
//a partir de aqui todo el trabajo es de las interrupciones
}
void simplifica (void)
{
Resultado=4; //Primero esta lejisimos y despues vamos recortando
if(DatoH<=9){Resultado=3;}
if(DatoH<=6){Resultado=2;}
if(DatoH<=3){Resultado=1;}
if(DatoL<=12){Resultado=0;} //Si el resultado da menor de 10uS entonces hay algo mal
}
static void interrupt ISR(void)
{
if(INTF&Flagtmr) //Si se nos activa la interrupcion externa y el contador esta corriendo
{
T1CON&=0b111110; //Desactivamos el timer1
DatoL=TMR1L; //Copiamos el valor de TMR1 a "dato"
DatoH=TMR1H;
TMR1H=0; //Limpiamos los registros
TMR1L=0;
INTF=0;
Flagtmr=0;
}
if(INTF&!Flagtmr) //Si se activa la interrupcion externa, pero no esta corriendo el contador
{
TMR1H=0; //Limpiamos los registros
TMR1L=0;
T1CON=0b110001;
INTEDG=0; //Cambiamos la interrupcion a flanco descendente
INTF=0;
Flagtmr=1; //Activamos el flag del contador
}
}
