Autor Tema: Concurrencia en CCS PICC  (Leído 8051 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #15 en: 19 de Diciembre de 2004, 13:23:00 »
Pacala podrias postear o enviarme algun programa de los que has hecho que realice concurrencia simulada con un solo PIC, a ser posible que sea sencillo, y si viniera con comentarios para poder entenderlo seria genial. Porque por el momento no me planteo migrar a C18 o Hi-tech, ya que de momento CCS me ha dado muy buenos resultados.

X cierto, tambien seria interesante saber si existe algun metodo para sincronizar procesos o programas ejecutados cada uno en un PIC, para poder realizar concurrencia real.

Respecto a La teoria del GRAFCET, me la voy a imprimir y echarla un vistazo, que suena bastante interesante.


Un saludo Giño

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Concurrencia en CCS PICC
« Respuesta #16 en: 19 de Diciembre de 2004, 14:03:00 »
Añadido...

http://personal.auna.com/asencio5/Ejemplos%20C/PROYECTOS/

Con respecto a lo de inicializar la eeprom,no se si se tratará de lo mismo,pero el ejemplo i2c de migsantiago carga un archivo .bin de datos iniciales en la eeprom:

http://personal.auna.com/asencio5/Ejemplos%20C/I2C/

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Concurrencia en CCS PICC
« Respuesta #17 en: 20 de Diciembre de 2004, 02:56:00 »
No, no es lo mismo, con PROTEUS no se le puede dar un fichero .bin de inicializacion como ocurre con memorias I2C.

Se puede hacer con el programa grabador o bien por software en el mismo programa, pensando un poquito.

En el programa de la memoria I2C de migsantiago no se enciende la barra de LEDs porque esta puesta al reves. En versiones anteriores para que funcionara era necesario meterle PULLUPs, en la SP5 con RES tambien funciona.

Un saludo

PD. Estoy vaguete, ¿como se hacia en XP para que aparecieran los acentos y los Alt Gr?

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #18 en: 20 de Diciembre de 2004, 04:31:00 »
Pocher, supongo que te refieres a las opciones de idioma.
Tienes que entrar en panel de control, escoger la opción Opciones regionales, de idioma y de fecha y hora, luego escoges Configuración regional y de idioma, y por último en el desplegable escoge el idioma que corresponda a tu teclado.

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #19 en: 20 de Diciembre de 2004, 08:49:00 »
Hola Pocher, prueba a meterte en el panel de control / opciones de accesibilidad, y desactiva filter keys, toggle keys y sticky keys, que se activan mediante ciertas combinaciones de teclas, y a mi ya me ha pasado mas de una vez, activar algo de eso sin darme cuenta.

Ademas, tambien hay algo que odio de windows Xp, y es lo relacionado con la tecla SHIFT, que no se pq algunas veces al pulsarla una vez, se kedan activados los caracteres secundarios de cada tecla (p.ej. si pulsas el 1, te sale !).

Espero haber sido de ayuda, un saludo Giño

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Concurrencia en CCS PICC
« Respuesta #20 en: 20 de Diciembre de 2004, 09:38:00 »
Ya está, se arregló.

No me pregunteis porqué, pero lo he solucionado cambiando de Español(alfabetización tradicional) a Español(alfabetización internacional). No sé porqué con la primera opción no salía bien. Enfin.

Saludos

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #21 en: 21 de Diciembre de 2004, 05:12:00 »
Ayer, estuve dandole vueltas a como podria realizar concurrencia simulada (ejecutar varios procesos simultaneamente con un solo procesador o microcontrolador en este caso, sin que se solapen en el tiempo), y creo saber como realizar una libreria para CCS PICC que implemente una de las herramientas mas usadas en concurrencia, los semaforos. Cuando tenga algo mas sobre esto, os mantendre informados, si alguien esta interesado en ayudarme con este proyecto que me envie un privado, a fin de no saturar de mensajes sobre lo mismo el foro

Saludos Giño

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Concurrencia en CCS PICC
« Respuesta #22 en: 21 de Diciembre de 2004, 08:24:00 »
Eso sería precisamente lo interesante,tornar,entre todos pueden surgir muchisimas mas ideas que entre uno o dos.Ese es el propósito de este foro y de muchos otros supongo que también.A mí por ejemplo me interesa el tema.Como ha comentado pacalaconcurso,el uso del timer interno del pic podría servir para la temporización de los "cuantos".Eso del semáforo no tengo idea de lo que es,pero imagino que será algún tipo de implementación para cerrar o dar paso a un proceso ¿no?.No sé que les parecerá a los demás,pero creo que para ir probando estaría bien escoger un pic con una generosa memoria de programa,como un 18.
Qué les parece

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #23 en: 21 de Diciembre de 2004, 09:42:00 »
Yo imagino que la programación por semáforos es igual que la programación por estados. Y si eso se puede meter en una librería mejor que mejor.

En cualquier caso, creo que es un tema con interés suficiente como para "saturar" el foro, así que yo votaría porque se siga discutiendo aquí.

¿Un PIC con mucha memoria?, pues no sé si será necesario. Supongo que dependerá del proyecto que se acometa ¿no?.

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: Concurrencia en CCS PICC
« Respuesta #24 en: 21 de Diciembre de 2004, 12:52:00 »
a ver, a ver......
no os metais en el diseño de un kernel del copon.... pensad que las cosas cuanto mas sencillas mejor....

por partes, por ejemplo, vamos a hacer un par de tareas que se deben ejecutar de forma paralela:

un led debe hacer una intermitencia de 1 segundo y otro led debe hacer una intermitencia de 300 milisegundos, ademas si pulso una entrada se debe activar un tercer ledSonrisa Gigante...

solo se puede usar un timer (ya vereis por que....) y no usar interrupcion para la entrada (esto es para joder un poco la cosaMuchas risasMuchas risasMuchas risas).

si pongo directamente el codigo greo que no tiene graciaIdea

saludossssssss

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Concurrencia en CCS PICC
« Respuesta #25 en: 21 de Diciembre de 2004, 13:00:00 »
jajaaja ya tenemos deberes chicos.Y yo que pensaba que me iba a pasar estos dias a la pachorra.
Con un solo timer se me ocurre utilizar el "tiempo de proceso" como base de tiempos para generar los retardos,incrementando dos variables,una por cada led,en cada desbordamiento del timer,y comprobando cada vez si la variable ha alcanzado un valor concreto para prender su led.Aunque no estoy muy seguro de que esto sea concurrente

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Concurrencia en CCS PICC
« Respuesta #26 en: 22 de Diciembre de 2004, 00:18:00 »
50ms sería el número clave.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #27 en: 22 de Diciembre de 2004, 05:48:00 »
Pues me ha costado un rato, pero aquí os he subido el ejercicio que ha propuesto Pacala con su simulación Proteus:
http://miarroba.com/foros/ver.php?foroid=348538&temaid=2665537

Este es el código:
Codigo:
#include <16F876.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)

#byte port_b = 6
#define INTS_POR_50ms 49      // (4000000/(4*4*256))/20
#define PASOS_LED1 20         // 1 seg = 50 ms * 20 pasos
#define PASOS_LED2 6          // 300 ms = 50 ms * 6 pasos

BYTE  ms50;                   // Contador de tramos de 50ms
BYTE  cuenta_ints;            // Contador de interrupciones
BYTE  cuenta_led1;            // Contador ciclos LED1: 1 segundo
BYTE  cuenta_led2;            // Contador ciclos LED2: 300 ms


#int_rtcc                  
void interrupcion() {               // aquí entra 49 veces cada 50ms        
    if(--cuenta_ints==0) {          // decrementamos el contador y si es 0 entramos
      cuenta_ints=INTS_POR_50ms;    // volvemos a setear el contador
      if (--cuenta_led1==0) {       // decrementamos el contador de LED1 y si es 0 entramos
         cuenta_led1=PASOS_LED1;    // volvemos a setear el contador de LED1
         output_bit (PIN_B0,!bit_test(port_b,0));  // e invertimos su estado
      }
      if (--cuenta_led2==0) {       // decrementamos el contador de LED2 y si es 0 entramos
         cuenta_led2=PASOS_LED2;    // volvemos a setear el contador de LED2
         output_bit (PIN_B1,!bit_test(port_b,1));  // e invertimos su estado
      }
      output_bit(PIN_B2,!bit_test(port_b,3));   // si se ha pulsado, encendemos LED3
    }
}

void main() {
   cuenta_ints=INTS_POR_50ms;    // se inicializan los contadores
   cuenta_led1=PASOS_LED1;
   cuenta_led2=PASOS_LED2;
   set_timer0(0);                // se arranca el timer
   setup_counters( RTCC_INTERNAL, RTCC_DIV_4 | RTCC_8_BIT);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   while (TRUE){};               // y se deja el micro rulando
}


Pocher, le he hecho usando una base de tiempos de 50ms siguiendo tu sugerencia, pero no entiendo porque esa base de tiempos es clave. Creo que también podría funcionar con cualquier divisor de ambos periodos: 1000ms y 300ms

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #28 en: 22 de Diciembre de 2004, 06:00:00 »
Respecto a los 50ms o 100ms que decis, creo que es demasiado tiempo, puesto que una instruccion con un reloj de 4Mhz tarda en ejecutarse un micro-segundo, por lo que en 50ms, se ejecutarian unas 50.000 instrucciones que seguramente seria todo un proceso entero y no obtendriamos ninguna concurrencia.

Como dice pacala, deberiamos ir por partes, lo primero en lo que estoy trabajando es en ejecutar interrupciones por desbordamiento del TIMER0 cada pocos micro-segundos, para ello uso un divisor de frecuencias=1, y en la salida de la interrupcion pongo el timer0 a 255, ya que el desbordamiento se produce cuando pasa de 255 a 256. Haciendo esto, consigo que se ejecute la interrupcion cada 15-20 instrucciones con un reloj a 4 MHz.

Anoche hice un programa muy simple, que realizaba siempre la misma instruccion (sumar 1 a un contador) en un bucle infinito, y la interrupcion cuando se ejecutaba ponia dicho contador a 0, asi podiamos ver en un LCD (este ejercicio en Proteus funcionaba bastante bien y era bastante explicativo) el numero de instrucciones que se ejecutaban antes de llegar a una interrupcion.

Todo se basa en la siguiente formula:

Temporizacion=4 * Tosc *(256 - valor inicial del Timer)*Divisor de Frecuencia

Y con las variables que jugamos principalmente son "valor inicial del Timer" y "Divisor de Frecuencia", ya que el periodo del oscilador (Tosc), al ser el inverso de la frecuencia, creo que si le bajamos, disminuye nuestra temporizacion, pero subimos la frecuencia, por lo que se ejecutarian las instrucciones mas rapido, y por tanto no adelantamos nada.

A menor temporizacion del TIMER0, se podria obtener una mayor concurrencia SIMULADA (puesto que estamos trabajando solo con un micro).

El siguiente paso a mi juicio, seria hacer que con cada interrupcion se vaya modificando el vector de interrupcion, para conseguir tener en vez de rutinas de interrupcion, procesos que se ejecutan de forma concurrente. Es decir, usar como rutina de interrupcion, algo tan simple como un ORG(usando directivas de ensamblador) hacia la direccion de memoria del siguiente proceso, y a la vez una modificacion de la direccion de memoria 004 donde se encuentra el vector de interrupcion con el ORG al proximo proceso que se debera ejecutar concurrentemente, y por ultimo inicializacion del TIMER0 a 255,y otro cambio del vector, y todo esto de manera ciclica para conseguir la concurrencia. Es decir, nuestro proceso de interrupcion kedaria asi:

#INT_RTCC
void cambio_proceso()
{
uso de una sentencia ORG para tras la interrupcion dirigirnos al siguiente proceso ;

modificacion de la sentencia anterior, para que el ORG apunte al proceso que se ejecutara cuando se produzca la siguiente interrupcion;

Inicializacion del TIMER0 a 255 para conseguir una mayor concurrencia SIMULADA;
}

Una vez que tuvieramos concurrencia simulada, pasariamos a implementar los semaforos, para sincronizar los procesos concurrentes

Todo esto lo he pensado, leyendo unos pocos libros, y haciendo 20 o 30 programas en C, asi que no soy ni mucho menos un experto en el tema, es simplemente una idea que puede no llevar a ninguna parte.


Un saludo Sonrisa

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #29 en: 22 de Diciembre de 2004, 06:52:00 »
Siguiendo los consejos del amigo Modulay, he modificado el código descargando de trabajo a la interrupción y trasladando el mismo al bucle principal del programa:

Codigo:
#include <16F876.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)

#byte port_b = 6
#define INTS_POR_50ms 49      // (4000000/(4*4*256))/20
#define PASOS_LED1 20         // 1 seg = 50 ms * 20 pasos
#define PASOS_LED2 6          // 300 ms = 50 ms * 6 pasos

BYTE  ms50;                   // Contador de tramos de 50ms
BYTE  cuenta_ints;            // Contador de interrupciones
BYTE  cuenta_led1;            // Contador ciclos LED1: 1 segundo
BYTE  cuenta_led2;            // Contador ciclos LED2: 300 ms


#int_rtcc
void interrupcion() {               // aquí entra 49 veces cada 50ms
      --cuenta_ints;                // decrementamos el contador y si es 0 entramos
}

void main() {
   cuenta_ints=INTS_POR_50ms;    // se inicializan los contadores
   cuenta_led1=PASOS_LED1;
   cuenta_led2=PASOS_LED2;
   set_timer0(0);                // se arranca el timer
   setup_counters( RTCC_INTERNAL, RTCC_DIV_4 | RTCC_8_BIT);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   while (TRUE){
       if(cuenta_ints==0) {          // decrementamos el contador y si es 0 entramos
         cuenta_ints=INTS_POR_50ms;
         if (--cuenta_led1==0) {         // si es 0 entramos
            cuenta_led1=PASOS_LED1;    // volvemos a setear el contador de LED1
            output_bit (PIN_B0,!bit_test(port_b,0));  // e invertimos su estado
         }
         if (--cuenta_led2==0) {         // si es 0 entramos
            cuenta_led2=PASOS_LED2;    // volvemos a setear el contador de LED2
            output_bit (PIN_B1,!bit_test(port_b,1));  // e invertimos su estado
         }
        }
      output_bit(PIN_B2,!bit_test(port_b,3));   // si se ha pulsado, encendemos LED3
   };
}


Editado: se reduce aún más la carga de la interrupción


 

anything