TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: camigod en 29 de Noviembre de 2008, 13:20:05
-
Buenos dias a todos,
Estoy iniciando en el tema de los Micros, y he ido haciendo pruebas para sacar un proyecto de un contador, la logica es sencilla, el usuario digita por medio de un teclado el avance por pulso, este registro se graba en la memoria del PIC, y por medio de un Menu en un LCD 2x16, puedo ir observando el conteo ascendente.
El programa esta hecho aunque con otras cosas que no entran al caso ahora, e incluso tengo la baquela y el proyecto andando correctamente, pero ahora me surge una duda. Puedo manejar dos contadores simultaneos utilizando multitask?, el proyecto maneja dos optoacopladores de herradura para leer cada pulso, pero como la programacion es lineal, y es necesario generar retardos para limpiar el ruido de dichos sensores, se genera el problema de que no pueden haber pulsos simultaneos... es decir el sistema colapsa cuando se genera una señal en ambos sensores... y solo cuenta la que primero ocurre.
He leido los ejemplos de CCS, y hay algunos que me dan una orientacion de por donde continuar, pero aun no esta todo claro, agradeceria a quien pueda darme una mano, e igualmente si tienen alguna inquietud, estoy para ayudarles.
Gracias
-
Hola.
Lo que a mi se me ocurre es llevar la cuenta del tiempo de antirrebotes con un timer (por medio de interupciones) y de esa manera se podria estar mas pendiente por si pulsan el otro boton. Aunque el tiempo de antirrebotes es muy pequeno (150 - 250 mS).
Saludos
-
Puedes hacer rutinas antirrebotes y demás retardos en forma de programación lineal sin perder tiempo ni demorar tus demás procesos, y sin nececidad de utilizar interrupciones. Ocupas una base de tiempo y cada vez que tengas que hacer tu ruina antirrebotes vas decrementando un contador (previamente inicializado cuando se generó el rebote por primera vez). Mientras el contador no llegue a cero no vuelves a entrar en la rutina antirrebotes.
-
Primero que todo gracias por interesarse en el tema,
Estuve mirando el ejemplo de CCS y logre construir un programa utilizando multitarea :-/ (el programa incrementaba variables y las mostraba en una parte del LCD, cada variable se maneja por aparte... pero al montarlo y ponerlo en practica con los sensores... ocurria el mismo problema :Djejeje Ahora si estoy en problemas...
Y pues leyendo sus respuestas, MLO_ la verdad como dije soy nuevo en el tema de los PIC, muy nuevo... y no se manejar muy bien los timers asi que no entiendo a que te refieres, y jacrmr, creo que no me entendiste, porque para los retardos estoy utilizando la instruccion delay_ms()... que viene con el compilador... el codigo de lectura de pulso es algo asi:
IF( input(PIN_A0) != 1){
delay_ms(200); //El tiempo lo he variado hasta llegar a un punto critico que es mas o menos 150 ms
i++; //Incremento una variable
}
Entonces basicamente pregunto si ocurrio un pulso, llamo un "retardo" de 200ms para que no se siga escuchando a ese PIN en ese tiempo... e incremento mi variable... con eso logro contar correctamente...
Un saludo, seguire publicando lo que ocurra con el proyecto
-
A proposito, el ejemplo del CCS se llama ex_rtos_demo1_tasks.C
Utilizando dicho ejemplo construi este programa para incrementar 3 variables y mostrar el incremento en el LCD, la configuracion de las librerias del lcd y demas configuracion no la escribo, pero este esta funcionando bien.
#use rtos(timer=0,minor_cycle=100ms)
int j=0, k=0, l=0;
#task(rate=1000ms,max=100ms)
void The_first_rtos_task ( )
{
j++;
lcd_gotoxy(1,1);
printf(lcd_putc,"%u",j);
}
#task(rate=500ms,max=100ms)
void The_second_rtos_task ( )
{
k= k+2;
lcd_gotoxy(1,14);
printf(lcd_putc,"%u",k);
}
#task(rate=100ms,max=100ms)
void The_third_rtos_task ( )
{
l= l+3;
lcd_gotoxy(2,1);
printf(lcd_putc,"%u",l);
}
void main ( )
{
rtos_run ( );
}
El codigo compilo, y se puede ver en el LCD como las variables se incrementan simultaneamente...
Mas o menos e logrado entender las instrucciones de los #task, asi que si tienen alguna duda o sujerencia para mejorar el codigo y acercarlo mas a lo que deseo, espero sus respuestas ansiosamente
-
Hola.
Pues seria mas o menos asi:
* Configuro el Timer para crear una base de tiempo, por ejemplo 1mS.
* Activo las interrupciones del timer configurado, de esta manera, se que cada milisegundo, el PIC atendera la interrupcion.
* En el codigo de la interrupcion pongo un bucle para que contabilice los 200mS, una vez terminada la cuenta, habilito un variable o flag, que me avise que pasaron los 200mS.
* En el programa principal, luego de leer el estado del pin ( if(!input(pin_a0)) ), pondria un ciclo while cuyo condicional seria el flag que se cambia con la interrupcion.
* Dentro de este ciclo while pongo el codigo de leer el estado del otro pulsador.
saludos
-
MLO__ Ley tu respuesta, pero si el PIC atiende la interrupcion cada ms, y la interrupcion me genera un retardo de 200ms... eso no implicaria que cada ms se retardaria 200ms???
-
Hola.
No. El proceso de la interrupcion tomo solo unos uS. Dentro de la interrupcion voy sumando una variable, la cual cuando llegue a 200 habilitara el flag que ya ha sumado el tiempo que requiero.
Cada milisegundo se entra a la interrupcion y aumenta la variable (la interrupcion tomaria unos cuantos uS), de ahi sale de la interrupcion, sigue con el proceso normalmente en el main.
Saludos
-
mmm ahora entiendo...
Es decir, este es el codigo que tengo:
while(1){
if(input(PIN_A0)!= 1){
delay_ms(200);
i=i+1; //CONTADOR DE PULSOS
printf(lcd_putc,"%u",i);
}
if(input(PIN_A1)!= 1){
delay_ms(200);
cont=cont+1; //SEGUNDO CONTADOR DE PULSOS
printf(lcd_putc,"%u",cont);
}
}
Pero pues obviamente, si uno de los dos sensores se activa, el PIC dura 200ms sin hacer NADA y no escucha a ninguno de los dos sensores hasta que terminan esos 200ms y realiza el conteo.
Entonces la nueva idea seria la siguiente:
while(1){
si se habilita el primer sensor & una variable de control esta en 1
aumento la variable
variable de control=0
habilito las interrup. del timer //Esta parte la he leido y se que se puede hacer pero no se como :-)
si se habilita el otro sensor & otra variable de control esta en 1
aumento la variable
variable de control=0
habilito las int.. de otro timer
}
En el codigo de las interrupciones... como dice MLO__ aumentaria una variable hasta 200... si llega a 200 pongo la variable de control a 1
Ahora voy a leer sobre timers... porque la verdad no se como configurarlos, muchas gracias MLO__ seguire publicando mis avances.
-
Ok.
Quedamos al pendiente de tus avances
Saludos
-
Hola a todos como estan?
Estuve leyendo sobre timers y su configuracion en este mismo foro, pero hubieron varias cosas que no entendi, por otro lado implementando los conceptos de multitarea... logre reconsruir el codigo (basandome en el ejemplo de CCS). Y funciona de maravilla!!! :P, les doy el codigo ya que veo que por ningun lado se encuentra informacion acerca de este metodo. Espero que les sirva.
#include <18f4550.h>
#fuses WDT,NOPROTECT,NOCPD,NOLVP,NOPBADEN,INTRC_IO,MCLR,BROWNOUT,BORV20,NOPUT
#use delay(clock=4000000)
#include <lcd.c>
#use rtos(timer=0,minor_cycle=7ms)
int i=0, j=0,control=0,control2=0;
#task(rate=7ms,max=7ms)
// the function can be called anything that a standard function can be called
void The_first_rtos_task ( )
{
if(input(PIN_A0)!=1 & (control==0)){
i= i+1;
control=1;
rtos_yield ( );
}
}
#task(rate=7ms,max=7ms)
void The_second_rtos_task ( )
{
if(input(PIN_A1)!=1 & (control2==0)){
j= j+2;
control2 = 1;
rtos_yield ( );
}
}
#task(rate=7ms,max=7ms)
void The_other_rtos_task ( )
{
rtos_await(input(PIN_A0)==1 );
control = 0;
}
#task(rate=7ms,max=7ms)
void The_other2_rtos_task ( )
{
rtos_await(input(PIN_A1)==1 );
control2 = 0;
}
#task(rate=350ms,max=7ms)
void The_third_rtos_task ( )
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%u",i);
lcd_gotoxy(15,1);
printf(lcd_putc,"%u",j);
}
void main(void)
{
set_tris_a (0xFF); // Configura los pines del puerto A como entradas
//Inicio LCD
lcd_init();
rtos_run ( );
}
Muchas gracias a todos, y cuenten conmigo para futuros proyectos ya que este tema de los PICS me quedo gustando... :D
Saludos
-
Me ha gustado mucho la evolución de este hilo, y cómo se han encontrado varias opciones para solucionar el problema de la multitarea.
La solución que plantea MLO con los Timers es la que yo habría planteado (y de hecho he usado) al no haberme metido aún con el tema de los RTOS.
Pero la elegante solución que has publicado usando el RTOS de CCS me gusta, sigo teniendo ese tema como asignatura pendiente y no me gustaría demorar demasiado su aprendizaje.
Y sí que hay publicado en el foro sobre este tema. Te dejo el link al master que nos hizo mi paisano Reinier: Sistemas operativos en PIC (http://www.todopic.com.ar/foros/index.php?topic=15876.0)
-
Hola.
Gracias maestro.
Yo tambien he estado al pendiente de usar los RTOS. Muy bueno el link, no lo habia visto (de hecho no habia investigado lo del RTOS) pero ya me entro la espinita de usarlo y haber si le dedico un tiempo en estos dias .... claro que con las fiestas encima ... mhh ... y el ron y el bullicio .... mejor lo dejo para enero!!
Saludos
-
Hola,
Yo tampoco habia encontrado el link, lo estare leyendo para aprender mucho mas, les agradesco todo y me alegra haber podido colaborar con este tema
Hasta luego.