Autor Tema: Programa de CCS para Pic16F876  (Leído 15098 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Programa de CCS para Pic16F876
« en: 27 de Abril de 2006, 08:51:36 »
Hola, estoy realizando un proyecto para la universidad.

Soy nueva en esto, es la primera vez que programo un pic. Estoy usando el lenguaje CCS C, pero no acabo de enterarme del todo.

Mi intención es hacer un contador de pulsos de 8 bits por la entrada del timer0 y enviar lo contado mediante tramas por la uart a una freq. de 20Hz

En realidad tengo dos entradas de pulsos pero solo tengo que contar una y ver el desfase entre las dos. formar la trama y enviarla a través de la uart.

Me he estado mirando el manual del CCS C pero no acabo de verlo claro; también he buscado por el foro pero no encuentro un programa en el que me pueda basar.

Si alguien me puede ayudar o decirme como aprender un poco de este lenguaje para hacerlo yo misma se lo agradeceré

Gracias

Cris.     :g)

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Programa de CCS para Pic16F876
« Respuesta #1 en: 27 de Abril de 2006, 09:29:07 »
Hola cris, bienvenida al foro.

Te queria preguntar si tienes dudas respecto a como programar en C o a como resolver el problema?

Es decir si lo que no te sale es el programa pero sabes que modulos usar y que pasos seguir entonces es mas facil, simplemente posteas tu solucion y te damos una mano para codificarla.

Si lo que necesitas son sugerencias sobre como resolver el problema, seria importante que especifiques por ejemplo

1) como son esos pulsos? Siempre iguales, de ancho variable? frecuencia?
2) viene uno despues de otro siempre?
3) Esa trama que debes armar es para pasarla a una PC? o a otro PIC? Aqui la cosa cambia por el tema de si lo quieres pasar como hexa o en ASCII

Fijate, este link tal vez te de unas ideas

http://www.todopic.com.ar/foros/index.php?topic=11443.0


Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #2 en: 28 de Abril de 2006, 05:48:02 »
hola maunix,

Mis dudas son porque se programar en C pero nunca he programado un PIC y no conozco bien las diferencias entre el C normal y el CCS C que usan aqui.

de las preguntas que me haces pues:

1) los pulsos son siempre iguales y con el mismo ancho, lo unico que varia es la frecuencia, pero lo importante es que 20 veces por segundo tengo que capturar el numero total de pulsos que me llegan y enviarlo

2)respecto a si biene uno despues de otro, si te refieres a que si es una señal continua, pues si, ya que la señal biene de un odometro, (un contador de vueltas para una rueda, que nos da unos 100 pulsos por vuelta)

3) la trama es para pasarla a un TAG que controla todo el sistema, pero no es en hexa sino en ASCII, aunque además del dato contado, la trama se compone de un caracter de principio y de final de trama (que es el mismo) y de la direcció.

4) lo de la dirección es la diferencia de fase entre las dos señales que recibo. solo tengo que contar una porque las señales son iguales, pero tengo que saber que desfase tienen para conocer la dirección en la que gira el odometro

Gracias por responder tan rapido,

P.D: he leido en un post que existe un manual del CCS C en castellano que es muy bueno, pero no lo he encontrado. En otra pag. web encontre uno escrito por Andrés Cánovas y reeditado por Victor Dorado, pero no se si es el mismo del que hablais. Por el momento me estoy leiendo este pero no acabo de encontrar como implementar este codigo.

Saludos

Cris

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Programa de CCS para Pic16F876
« Respuesta #3 en: 28 de Abril de 2006, 08:42:00 »
Entiendo tus inconvenientes.  Si vienes de un C para pc, usar un c para microcontroladores te puede sonar 'poco amigable' al principio  pero es porque no tienes un sistema operativo de fondo que te haga 'casi todo' sino que lo debes hacer tu misma.  Dialogas 'directamente' con el hardware , con la asignación de memoria, de puertos, periféricos, etc.  Esta es la mayor diferencia no tanto en la sintaxis (más alla que haya compiladores que sean mas o menos ANSI Compliant).

Es un programa realizable pero no es tan simple por el tema de que estas muy ajustada con los tiempos.

1) y 2)
Más alla de que la señal sea lenta, deberás ser muy precisa a la hora de medir el famoso 'desfasaje' del que me hablas.  Si tienes 100 pulsos por vuelta y tienes ademas por ejemplo 10 vueltas por segundo.  Estarás midiendo 1000 pulsos por segundo.  Esto te da que en 1 mseg debes medir el desfasaje.
Cual es la velocidad máxima que puedes tener? Esto te definirá el mínimo ancho de pulso.

3)
Sumado a esto, si envias los datos cada 1/20 segundos y en ascii con un inicio de trama y un final de trama, tendras no menos de 10 bytes.
Esto te da 1/20 seg = 5 mseg.
En 5 mseg tienes que enviar 10 bytes (sino se te estará superponiendo una trama con la anterior).  Para ello debes transmitir un byte cada 500useg.
Un byte de usart te consume al menos 10 bits.  Si en 500useg transmites 10bits, necesitas 50useg por bit.  Esto te da que 1seg/50useg = 20000bps de comunicación.

Estos son valores 'minimos', debiendo tu software funcionar más rápido para ello.

4) Esto depende del punto 1.  Además piensa que además de medir este desfase debes tener en cuenta que hay una demora en convertir los caracteres a ASCII.  Esto si te lo hace el C es algo lento, ojo con eso.

Luego de esto, podemos ir al código. 

a) Configuras por ejemplo el timer2 para una base de tiempo de 5mseg.  Para ello tal vez debas cambiar algun prescaler (no he hecho las cuentas) y cargar en el TMR2 el valor de pulsos que te llevará llegar a 5mseg con el clock que uses.  Si por ejemplo usas 20Mhz, seran 2500 pulsos (es decir que necistarás prescaler de 16 ya que el TMR2 es de 8 bits).  Esto me da una cuenta de 2500/16 = 156 pulsos.  Si el timer tiene 255 como valor máximo , le deberás cargar 99 para que pasados 156 pulsos del timer se encienda el TMR2IF por overflow y sepas que transcurrieron 5mseg

b) Puedes usar el módulo de captura (CCP) , tanto el CCP1 como el CCP2.  Para ello la señal tendría que ingresar por el pin RC1 y RC2.
Podrias por ejemplo cnofigurar el CCP1 para que resetee el timer al ingresar un flanco en alto y el CCP2 para que solo capture.  Al terminar la captura con el CCP2 tendrás el dato de la diferencia entre pulsos en el CCPR2. 

c) Luego incrementas el contador de pulsos entrantes en 1. 

d) Conviertes todo en ASCII

e) Debes armar una trama con algun buffer por la usart.  Si la transmisión la debes hacer 'mientras' mides, se complica bastante la cosa y debieras usar si o si interrupciones.


Espero haberte dado una mano

Sobre los tutoriales, te sugiero preguntes directamente sobre el tema o que hagas una búsqueda ya que hay bastante info acá sobre el CCS. 



- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #4 en: 02 de Mayo de 2006, 08:30:40 »
hola maunix,

Agradezco mucho tu ayuda, aunque para serte sincera hay algunas palabras que has dicho que no me suenan para nada :P
pero supongo que cuando empiece a programar el pic me serviran de mucha ayuda.

en respuesta a las preguntas que me formulavas,

1 y 2) la verdad es que la velocidad max. es de 100Km/h eso me da 198943.68 vueltas/hora aprox. lo que nos da 19894368 pulsos por hora. Aunque es un valor teorico, se que con esa rueda sera imposible que se pueda llegar a esas velocidades. Estos calculos nos da unos 5526 pulsos por segundo, /20 nos da 277 pulsos por trama. pero variarán en frecuencia según la velocidad de la rueda.

Con estos calculos me da que el contador deberia ser de 9 bits, pero lo realizaré de 8 bits (que creo que será mas sencillo), ya que tengo la seguridad de que no pasaremos de los 50Km/h.

4) La demora para convertir los caracteres a ASCII los puede hacer el propio pic? porque si por C es algo lento a lo mejor me afecta en las tramas, y la captura de estas tramas se ha de hacer lo más cercano posible a tiempo real.

Lo del CCP1 y CCP2 no lo he acabado de entender pero supongo que es por lo que tu decias al principio, yo al estar acostrumbrada al C de pc, no acabo de ver como programar todos los periféricos y puertos del pic en cuestión.

Gracias por todo,

Cris

Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #5 en: 03 de Mayo de 2006, 08:04:34 »
hola maunix,

me acabo de dar cuenta de que no te dije una cosa importante que me preguntas al final

"Si la transmisión la debes hacer 'mientras' mides, se complica bastante la cosa y debieras usar si o si interrupciones."

pues si, la transmisión se ha de hacer a la vez que mido, en realidad nunca ha de parar de contar porque sino se perderian pulsos y con lo cual se perderia datos para saber la distancia recorrida.

como se programa con interrupciones?

Tienes o sabes donde puedo encontrar, un codigo parecido para basarme a la hora de programar mi codigo?

Saludos,

Cris

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Programa de CCS para Pic16F876
« Respuesta #6 en: 04 de Mayo de 2006, 18:52:35 »
Cris, antes que nada no tengo ni conozco un codigo similar ya que las cosas similares que hice han sido en ensamblador, encima en los pics los 18F uso el C18 que difiere bastante con el CCS.

De todas espero poderte ayudar con algunas ideas.

Veo que estas muy limitada con los tiempos y encima deberas hacer muchas cosas.
Te aconsejo que uses un PIC18Fxxx que son mas veloces y con el PLL activado pueden ejecutar a 40Mhz (10Mips) todos los modelos y algunos hasta 48Mhz (12Mips).  Esto te va a permitir estar mas olgada con el diseño en el tema de los tiempos.

En cuanto a la transmision por interrupcion, debes hacer lo siguiente

1) Armar toda la trama que enviaras (esto incluye convertir en ascii lo que haya que convertir en ASCII)
2) Poner cada byte a transmitir en algun buffer de n bytes de largo que seria un buffer temporal
3) La interrupcion de salida debiera habilitarse al iniciar la trasnmision de una nueva trama
4) Al iniciarse la trasnmision de la nueva trama se mueve la trama temporal al buffer de transmision y se pone el contador del byte a trasnmitir a 0.  A medida que se ejecuta la interrupcion el contador ira creciendo y se debe deshabilitar la interrupcion cuando se llegue a la cantidad de bytes del buffer a trasnmitir.


Esta forma tiene que andar, teniendo cuidado de que siempre se haya terminado de trasnmitir antes de que se inicie una nueva trasnmision.  Te aconsejo ademas usar un baudeaje alto que te permita en esos 1/20 seg poder enviar todos los datos que te queden en la trama, sino tendras un desbordamiento por querer enviar mas rapido de lo que se puede fisicamente.

Como te daras cuenta no es algo tan simple lo que pretendes hacer, no es que no lo sepas o que lo sepas es que es algo que se ajusta mucho con los tiempos y termina complicando el softwware.

En cuanto al modulo de captura, que es lo que no has entendido?  No te puedo ayudar con las instrucciones para configurar el CCP con el CCS pero si para entender el manual.

Saludos




hola maunix,

me acabo de dar cuenta de que no te dije una cosa importante que me preguntas al final

"Si la transmisión la debes hacer 'mientras' mides, se complica bastante la cosa y debieras usar si o si interrupciones."

pues si, la transmisión se ha de hacer a la vez que mido, en realidad nunca ha de parar de contar porque sino se perderian pulsos y con lo cual se perderia datos para saber la distancia recorrida.

como se programa con interrupciones?

Tienes o sabes donde puedo encontrar, un codigo parecido para basarme a la hora de programar mi codigo?

Saludos,

Cris

Hola

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Programa de CCS para Pic16F876
« Respuesta #7 en: 05 de Mayo de 2006, 10:41:26 »
Cristina
Por los datos que dás tu odómetro es un encoder, de que tipo:
en cuadratura?
con código de Grey?
Esta diferencia determina como tu rutina debe discernir en que sentido está girando el encoder

Cuál es la dimensión que querés medir?:
la velocidad (o sea el tiempo que hay entre dos pulsos sucesivos)
la distancia (o sea la cantidad de pulsos que hay en un determinado lapso de tiempo)
Esta diferencia determina como se comporta la rutina que tenés que hacer y que periférico usar.

Lo que yo haría es una interrupción por flanco de pulso, en ese momento me fijo en que estado está la otra entrada del encoder para saber en que sentido está girando, con ese dato incrementar o decrementar un contador con signo y luego de un cierto tiempo interrumpir y mandar el valor del contador que indica cuanta distancia relativa recorrió.

Un dato importante a tener en cuenta es el radio de la rueda ligada al odómetro para saber cuantos pulsos dá por cm o metro recorrido.

Si además necesitás mandar los datos en una trama (o sea un buffer de transmisión) necesitás sin remedio hacerlo con interrupciones. Yo hice la sugerencia de un código para recibir y transmitir un buffer en otro post http://www.todopic.com.ar/foros/index.php?topic=11759.0 espero que te sirva.

Saludos
Marcelo


Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #8 en: 09 de Mayo de 2006, 05:52:52 »
Hola marcelo,

Si, el odometro es un tipo de encoder optico, no esta codificado, simplemente nos da 100 pulsos por vuelta la señal principal, y otros 100 pulsos por vuelta desfasados 90º la segunda señal.

Si este desfase es positivo la rueda va para un lado y si es negativo va hacia el otro. En teoria es así de simple ;)

La dimensión a medir es la distancia.

Pero mi problema es que no se programar en CCS, y cada vez estoy mas perdida en el codigo. He intentado programarlo con los consejos que me daba Maunix, pero soy un poco negada en esto. Lo malo es que aquí en mi empresa (estoy haciendo las practicas de final de carrera), ya empiezan ha ponerse nerviosos porque deberia tener algo "palpable" ya desde la semana pasada.

Aqui te pongo el codigo que yo he escrito, pero es tan triste que me da hasta vergüenza poneroslo.  :(

La verdad es que no se como continuarlo y si estoy usando los bloques correctos.



#include <16F876.h>          //libreria que carga el pic a utilizar
#device adc=8              //resolución 8 bits para el comversor ADC

#FUSES HS,NOWDT           // Fusibles, El Contador Watch Dog esta desabilitado

#include <string.h>       //libreria necesaria para trabajar con caracters
#include <stdio.h>        //libreria necesaria para trabajar con la UART

#use delay(clock=20000000)   //Velocidad del cristal
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
//Prepara la UART para trabajar con el protocolo rs232

////////////////////  VARIABLES GLOBALES   /////////////////////////////////////
int Cuenta=0;

////////////////////  FUNCIONES Y RUTINAS //////////////////////////////////////
#int_RTCC
RTCC_isr()
{}

#int_TBE
TBE_isr()
{}

#int_TIMER0
TIMER0_isr()
{ set_timer0(50);  // resetea el contador cada 50ms  20 veces por segundo
}

///////////////////// PROGRAMA PRINCIPAL ///////////////////////////////////////

void main()
{ setup_adc_ports(NO_ANALOGS);  //Puertos desconectados
   setup_adc(ADC_OFF);
   setup_spi(FALSE);

   setup_counters(RTCC_EXT_L_TO_H|RTCC_DIV_1);
   set_timer0(0);
   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1); //timers 0 conectado

   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);            //Timers 1 y 2 desconectados

   enable_interrupts(INT_RTCC);  //se activan las interrupciones
   enable_interrupts(INT_TBE);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   Cuenta=get_timer0();
}


Saludos,

Cris.

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Programa de CCS para Pic16F876
« Respuesta #9 en: 09 de Mayo de 2006, 12:24:46 »
Cris
Ante todo yo puedo darte recomendaciones de acuerdo a mi experiencia personal, pero por supuesto vos tenés que depurar el código y hacerlo funcionar.
Un encoder en cuadratura (señales desfasadas 90º) tiene una salida como esta:
           *************                                       
           *                   *                                       
 *******                   ********                               
                                                   giro horario (aumento)       
 ************                    ****                               
                     *                   *                                   
                      ************                                   

                   *************                                   
                   *                   *                                   
 ***********                    ****                               
                                                  giro antihorario (decremento)
 *******                     ********                               
            *                    *                                       
             *************                                       

Por lo que si vos tomás en el flanco ascendente de la señal superior el estado de la inferior sabes para que lado está girando el encoder.
Te sugiero entonces que coloques la entrada del encoder en el pin RB0 del controlador (entrada de interrupción externa), luegos en la sección que defines los periféricos:

Código: [Seleccionar]
   ext_int_edge(L_TO_H);      //definir el flanco de interrupción
   enable_interrupts(INT_EXT);//encender la interrupción
   enable_interrupts(GLOBAL);

y defines la rutina cuando se produce una interrupción

Código: [Seleccionar]
#INT_EXT
void ext_isr(){

}

Dentro de esta rutina deberías incrementar o decrementar un contador global con signo (para mediciones relativas) que dependiendo de la cantidad máxima de pulsos prevista debería ser de 8, 16 ó 32 bits.

suponiendo que sea de 16 bits:

Código: [Seleccionar]
static signed int16 cuenta;
y dentro de la rutina quedaría algo como esto
Código: [Seleccionar]
if(input(PIN_B1)){ //suponiendo que la otra entrada del encoder está en RB1
cuenta += 1; //de acuerdo a su estado considera la rotación en un sentido
}else{
cuenta -= 1; //u otro
}

Después de un cierto tiempo, que podés manejar con un contador (yo te recomendaria el Timer 1, que tiene mayor definición) necesitarías convertir pulsos a distancia (de acuerdo a la geometría del sensor) actualizar la cuenta de un contador global, convertirla a ASCII y enviarla por RS232 (creo que no me olvido de ningún paso). En los que tengas dudas consultame y te puedo sugerir algo.

Comentarios sobre tu código:
RS232 con 9 bits?, lo normal son 8

no creo que necesites, en principio por lo menos
#include <string.h>       //libreria necesaria para trabajar con caracters
#include <stdio.h>        //libreria necesaria para trabajar con la UART

podés no necesitar #int_TBE, eso depende de la rutina de transmisión


Espero ser de ayuda, saludos
Marcelo

PD: como práctica inicial sobre controladores es medio complejo el problema (desde mi punto de vista), creo que deberías ir paso a paso y una vez que logres que funcione una etapa (por ejemplo la cuenta de pulsos del encoder) pasar a la siguiente (ejemp. convertir pulsos en distancias) y así hasta conseguir que el sistema en conjunto funcione. Si estás aprendiendo supongo que no pueden exigirte que programes como la mejor, pero esto es solo una apreciación personal.


Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #10 en: 10 de Mayo de 2006, 08:09:28 »
Marcelo

Primero darte las gracias, porque me estas ayudando mucho  :g)

He seguido tus recomendaciones, no se si lo he hecho bien  :lol:  pero ahora el CCS me da un error al compilar

"Unknown device type -Try PCM"   

y no me deja ver si hay errores en el codigo o no. Yo tengo un CCS original con licencia y todo en orden; no hay ningún software pirata en mi ordenador ya que es una empresa de investigación subcontratada por la universidad.

Tampoco se si estoy llamando bién a las funciones, ya que el CCS se parece poco al borland C que yo habia programado. Y a lo mejor estoy usando algunas funciones o llamando a algúna parte del programa que no toca.

Este es el codigo que tengo ahora pero que no me deja compilar.

#include <16F876.h>          //libreria que carga el pic a utilizar
#device adc=8              //resolución 8 bits para el comversor ADC

#FUSES HS,NOWDT           // Fusibles, El Contador Watch Dog esta desabilitado

#include <string.h>       //libreria necesaria para trabajar con caracters
#include <stdio.h>        //libreria necesaria para trabajar con la UART

#use delay(clock=20000000)   //Velocidad del cristal
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//Prepara la UART para trabajar con el protocolo rs232

/////////////////////  ENTRADAS ////////////////////////////////////////////////

#define odometro_A  PIN_B0        //la entrada del encoder en el pin RB0
#define odometro_B  PIN_B1        //(entrada de interrupción externa)

////////////////////   SALIDAS /////////////////////////////////////////////////

#define salida PIN_B2

////////////////////  VARIABLES GLOBALES y CONSTANTES  /////////////////////////
#define freq         50   // resetea el contador cada 50ms  20 veces por segundo
//int16 Cuenta=0;
static signed int16 cuenta;
int sentido=0;


////////////////////  FUNCIONES Y RUTINAS //////////////////////////////////////
#INT_EXT
void ext_isr()
{
  if(input(odometro_B))   //la otra entrada del encoder está en RB1
  { cuenta += 1;
    sentido = 1;         //de acuerdo a su estado se considera la rotación en un sentido
  }else{
    cuenta += 1;
    sentido = 2;        //u otro
   }
}

#int_TBE
TBE_isr()
{signed int16 numero;
 int direccion;
 char num[8],ascii;
 
 ascii="A";    //letra que concadenar en la trama
 numero=direccion=0;     //inicializamos los valores de las variables.   
 
 numero=cuenta;         //copiamos el valor del contador
 direccion=sentido;     //almacenamos el sentido de la rueda
 
 cuenta=sentido=0;      //inicializamos el contador
 
 if(sentido==1)
 {sprintf(num,"%u",numero};
  num=strcat (num, "1"); //introducimos el sentido en la trama
  num=strcat (ascii, num);
  num=strcat (num, ascii);}
 else
 {if(sentido==2)
  {sprintf(num,"%u",numero};
   num=strcat (num, "2"); //introducimos el sentido en la trama
   num=strcat (ascii, num);
   num=strcat (num, ascii);}
 }
}

///////////////////// PROGRAMA PRINCIPAL ///////////////////////////////////////

void main()
{
   setup_adc_ports(NO_ANALOGS);  //Puertos desconectados
   setup_adc(ADC_OFF);
   setup_spi(FALSE);

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //timers 0 conectado
   setup_timer_1(T1_EXTERNAL);
   setup_timer_2(T2_DISABLED,0,1);            //Timer 2 desconectado

   enable_interrupts(INT_RTCC);  //se activan las interrupciones
   enable_interrupts(INT_TBE);
   enable_interrupts(INT_TIMER0);
   
   ext_int_edge(L_TO_H);      //definir el flanco de interrupción
   enable_interrupts(INT_EXT);//encender la interrupción
   enable_interrupts(GLOBAL);

 ext_isr();
 TBE_isr();

}


También tengo otras dudas  :P.

Una vez generado el archivo que quiero enviar por la UART, como le indico que me lo envie?
Y otra cosa necesito que me reinicie el contador y me envie por la UART 20 veces por segundo, cada  50us, eso como se lo indico en el codigo?

Yo creia que se le havia de indicar de esta forma
   set_timer0(50); 
Pero lo he de incluir en el mail? o en el void ext_isr() ?

Saludos
Cris


P.D: te debo una birra por la ayuda jeje :D


Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Programa de CCS para Pic16F876
« Respuesta #11 en: 10 de Mayo de 2006, 08:29:29 »
Una vez generado el archivo que quiero enviar por la UART, como le indico que me lo envie?
Y otra cosa necesito que me reinicie el contador y me envie por la UART 20 veces por segundo, cada  50us, eso como se lo indico en el codigo?

Yo creia que se le havia de indicar de esta forma
   set_timer0(50); 
Pero lo he de incluir en el mail? o en el void ext_isr() ?

Hols cris.  Puedes configurar la usart para un baudeaje determinado y habilitar la interrupción de transmisión.

Luego en el bloque de atención de la rutina de tranmisión vas enviando cada byte de la trama a enviar.  Para eso utilizas un puntero que te vaya diciendo que byte debes enviar.

Respeto a los 50 useg entre datos, esto será algo complicado.  Si quieres enviar 1 dato cada 50useg, como el byte tiene 10 bits (bit start - 8 bit datos - bit stop) cada bit tendrá una duración de 5useg.  1/5useg = 200.000bps  .  Si bien el pic puede enviar a esa velocidad, vas a tener problemas del lado del PC para sincronizarte a dicha velocidad.

Puedes ajustar el baudeaje para que te de justamente transmitir toda tu trama en el tiempo que tienes que son 5mseg por trama (para enviarla 20 veces por segundo).

Esto como verás se empieza a complicar como te expliqué al principio.  Tienes muchas cosas que hacer en tiempos muy justos y estas llegando a un punto donde la cosa se complica más y mas, sobre todo si hay que hacer las conversiones a ascii que mencionaramos en posts anteriores.

Como consejo... creo que los requerimientos son algo 'exigentes' para un PIC16 programado en C.  No digo que sea imposible, pero a priori mi intuición me dice que habría realmente que hacer un gran esfuerzo para cumplir los requerimientos que te han pedido.

saludos



- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Programa de CCS para Pic16F876
« Respuesta #12 en: 10 de Mayo de 2006, 10:30:30 »
Hola Cris
Te tomo la palabra por lo de la birra.
No sé donde vos vivís, pero acá 20 veces por segundo son 50ms (milisegundos) no 50us (microsegundos), 50us son 20 veces por ms o sea 20 KHz.

Lo que yo haría es setear el timer 1 para que te interrumpa cada 50ms.

Los timer de los controladores PIC tienen la "particularidad" de contar hacia adelante (1, 2, 3...) y producen una interrupción cuando desbordan (cuando la cuenta pasa de 255 a 0 en los de 8 bits y de 65535 a 0 en los de 16 bits), por lo tanto para que el timer te produzca una interrupción cada x ms (o cada x us) es necesario que le cargues al contador del mismo un valor tal que desde este valor hasta 65536 tarde el tiempo que necesitas.
Por supuesto el tiempo depende de la frecuencia del reloj (cada ciclo de máquina tarda 4 ciclos de reloj) y del prescaler que utilices.

Para que el compilador calcule el solito la constante para cargar en el timer declará los siguiente:
Código: [Seleccionar]
#define delayTMR1us(x) (int16)(65536 - (x * 0.625))Luego para hacer un retardo de 50ms declaras lo siguiente
Código: [Seleccionar]
set_timer1(delayTMR1us(50000));En las definiciones, cuando arranca el sistema:
Código: [Seleccionar]
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //activar el timer
set_timer1(delayTMR1us(50000)); //el compilador te pone la constante adecuada
enable_interrupts(INT_TIMER1); //habilitar la interrupción
y por supuesto no te olvides (si no, no funciona ninguan interrupción)
Código: [Seleccionar]
enable_interrupts(GLOBAL);Luego si es aceptable una latencia en la transmisión en la rutina de interrupción ya solo activaría una bandera que le indicara al procedimiento de transmisión (que pondría en el cuerpo principal del programa, dentro de un loop infinito) que se active, y así no se bloqueen las interrupciones (hemos de suponer que el encoder sigue andando).
Código: [Seleccionar]
static short int transmitir;

#int_TIMER1
void TIMER1_isr(){

set_timer1(delayTMR1us(50000)); //recargar otros 50ms
transmitir = 1; //indicar transmitir
}

y en el cuerpo principal del programa
Código: [Seleccionar]
void main(void){
//loop infinito
for(;;){
//hacer cosas...
//si se activa la bandera de transmitir
//es que pasaron 50ms (confiá en el timer)
if(transmitir){
//hacer todos los procesos de transmisión

//listo, borrar la bandera para que no se
//transmita hasta que pasen otros 50ms
transmitir = 0;
}
//hacer más cosas...
}
}
Espero que te ayude, saludos
Marcelo


PD: de la PC al microcontrolador hay la misma diferencia del 1er mundo al 3ro. En PC los recursos son ilimitados y los gastas sin miramientos (una variable de 32 bits que solo vá a tener dos valores, por ejemplo). En los controladores los recursos son escasísimos y los tenes que usar discretamente porque enseguida se acaban si no sos cuidadosa con la programación.

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Programa de CCS para Pic16F876
« Respuesta #13 en: 10 de Mayo de 2006, 11:11:40 »
Agrego y para que no se mezcle con lo del código. Armá el código de a una parte, usá el simulador del MPLAB, usá los estimulos de pines (si disponés del Proteus usalo) y fijate que funcione de a una rutina y una vez que funcione pasá a la etapa siguiente. Querer hacer todo de una es practicamente imposible (salvo que sea algo muy sencillo, que no es tu caso).
Fijate que funcionen las interrupciones, fijate que puedas contar pulsos, fijate que puedas producir una interrupción ciclica con los 20Hz que necesitas (podes activar un LED o producir un pulso en un pin y verlo en el osciloscopio) depurá la rutina y una vez que funcione te preocupás de transformar hexa en ascii y después te preocupas de como transmitirlo.

Saludos
Marcelo

Desconectado cristina_26

  • PIC10
  • *
  • Mensajes: 16
Re: Programa de CCS para Pic16F876
« Respuesta #14 en: 11 de Mayo de 2006, 05:57:25 »
Hola,

Vale tenéis razón jeje, me equivoqué al escribirlo, son 50ms  :P pero no me lo tengáis en cuenta XD

He introducido las variaciones del código que me dijiste, pero sigo sin solucionar el problema que me da el compilador

"Unknown device type -Try PCM" 

y así no puedo comprobar los cambios del código ni nada, si tengo mplab y proteus pero necesito compilar primero en CCS para poder usarlo en el resto de los programas no?


Ya pensaba en ir introduciendo el código poco a poco e ir probándolo por partes pero igualmente no encuentro ninguna rutina para usar en la UART en la cual le indique que variable quiero enviar y cuando.

Otra cosa, para llamar a las funciones, dentro del bucle for(;;) he de introducir
 
 ext_isr();
 TBE_isr();

y así se llaman directamente, tal y como funciona en el Borland C? o hay alguna subrutina especial para llamarlas?
o al ser hardware que ya tiene el PIC, no hace falta llamarlas?

La verdad es que eso de pensar en la diferencia entre programar un PIC y un PC es abismal.

Saludos

Cris :g)