TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cristina_26 en 27 de Abril de 2006, 08:51:36

Título: Programa de CCS para Pic16F876
Publicado por: cristina_26 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)
Título: Re: Programa de CCS para Pic16F876
Publicado por: maunix 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 (http://www.todopic.com.ar/foros/index.php?topic=11443.0)


Saludos
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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
Título: Re: Programa de CCS para Pic16F876
Publicado por: maunix 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. 



Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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
Título: Re: Programa de CCS para Pic16F876
Publicado por: maunix 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

Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba 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

Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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.
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba 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.

Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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

Título: Re: Programa de CCS para Pic16F876
Publicado por: maunix 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



Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba 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.
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba 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
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 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)
Título: Re: Programa de CCS para Pic16F876
Publicado por: Flugplatz en 11 de Mayo de 2006, 07:45:20

"Unknown device type -Try PCM" 


Menu -> View -> Toolbars -> Compiler Select

Te saldrá en la parte superior una Toolbar más que contiene una lista desplegable ...

Si usas el 16FXXX tienes que seleccionar  "Microchip 14 Bit"
Si usas el 18FXXX tienes que seleccionar  "Microchip PIC18"

Aunque tiene pinta de que no has empezado el programa con el include del micro que vas a usar, así que, te recomiendo que revises si has puesto todo lo que hace falta para que se compile correctamente el proyecto.

De todas formas, es mejor que para empezar a usar el CCS utilizes el Project Wizard

Menu -> Project -> New -> Pic Wizard

De esta forma te configura todo como hace falta y te inicializa el micro con todo lo que le pongas.

Aquí te pongo un ejemplo de como quedaría un proyecto con el 16F628A. Aunque el Wizzard lo divide en dos archivos, entre los dos, el projecto tiene que tener todo esto:

Código: [Seleccionar]
#include <16F628A.h>

#FUSES NOWDT                  //No Watch Dog Timer
#FUSES HS                    //High speed Osc (> 4mhz)
#FUSES PUT                    //Power Up Timer
#FUSES NOPROTECT              //Code not protected from reading
#FUSES NOBROWNOUT            //No brownout reset
#FUSES MCLR                  //Master Clear pin enabled
#FUSES NOLVP                  //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                  //No EE protection

#use delay(clock=20000000)

#int_TIMER1
TIMER1_isr()
{
//prueba asm
#asm
   nop
#endasm
}

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   setup_oscillator(False);
   while(true) //bucle infinito
   {
    }
}

Un saludo
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 11 de Mayo de 2006, 08:11:09
hola Flugplatz

La opción que tu me dices no la puedo seleccionar ya que solo me sale  Microchip 12 bits. y no me deja seleccionar otra opción, y eso que tengo el software original y he instalado todo el pack completo.

por otro lado, si que tengo puesto el include del PIC que estoy utilizando, en mi caso es el pic16F876 pero cuando me sale el error, precisamente me queda seleccionado:

#device PIC16F876

del archivo 16F876.h  y no del mío (en mi código también esta cargado)

Ya empecé el proyecto con el Wizard pero ni así conseguí que me dejara compilar.

Os incluyo el código actual que no me deja compilar y del cual gran parte he de agradecer ha maunix y Marcelo que sin su ayuda aun estaría buscando que includes había de utilizar.


#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
#define delayTMR1us(x) (int16)(65536 - (x * 0.625)) //Para que el compilador
 //       calcule el solito la constante para cargar en el timer

static signed int16 cuenta;
static short int transmitir;
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_TIMER1
void TIMER1_isr(){

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

#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(void)
{
   setup_adc_ports(NO_ANALOGS);  //Puertos desconectados
   setup_adc(ADC_OFF);
   setup_spi(FALSE);

   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //activar el timer1
    set_timer1(delayTMR1us(50000));

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //timers 0 conectado
   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);
   enable_interrupts(INT_TIMER1);

   ext_int_edge(L_TO_H);      //definir el flanco de interrupción
   enable_interrupts(INT_EXT);//encender la interrupción
   enable_interrupts(GLOBAL);

for(;;)   //loop infinito
   {ext_isr();
     TBE_isr();
     //aqui se ha de activar la bandera de transmisión
    if(transmitir)
       {//hacer los procesos de transmisión
        //borrar la bandera de transmisión para que no se transmita hasta
        //pasados otros 50ms

        transmitir = 0; }
   }
}


Ahora estoy preparando otro ordenador para instalar tanto el CCS como el proteus ya que en este no acaban de funcionar correctamente y empiezo a sospechar que no todo es culpa mia  :P  sino que este ordenador tiene gran parte de culpa  :-/


Saludos
Cris :g)
Título: Re: Programa de CCS para Pic16F876
Publicado por: Flugplatz en 11 de Mayo de 2006, 08:38:02
Hola ...

Lo siento ...  :? ... si solo te sale Microchip 12 Bit en la lista, es que tienes mal instalado el CCS.

Antes de seguir haciendo el programa intenta arreglar el CCS ... ahora mismo solo tienes el compilador PCB. Para el 16F876 necesitas el PCM y para el 18F252 el PCH

o sea, este:

http://www.ccsinfo.com/product_info.php?cPath=Store&products_id=PCW_full (http://www.ccsinfo.com/product_info.php?cPath=Store&products_id=PCW_full)

o este:

http://www.ccsinfo.com/product_info.php?cPath=Store_Software_Compilers&products_id=PCWH_full (http://www.ccsinfo.com/product_info.php?cPath=Store_Software_Compilers&products_id=PCWH_full)


Prueba a generar un proyecto sencillo para el 12C508 y a ver si te lo compila ...

un saludo
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba en 11 de Mayo de 2006, 09:06:24
Cris
Como no progresamos te hice un programa con lo que te sugerí hasta ahora, compila OK. Te toca a vos simularlo (e emularlo)y verificar que funcione.
Debería hacer estas dos cosas: contar pulsos del encoder en la variable cuenta (se supone que el encoder está coenctado a RB0 y RB1) y cada 50ms cambia el estado de RB2. Lo que falta por hacer es todo lo demás pero si esto no funciona que es lo básico...
La conversión hex a ascii, la creación de un buffer, la transmisión del buffer, etc. por ahora no debería preocuparte. Que esta parte funcione, por el resto Dios proveerá.

Saludos
Marcelo

Código: [Seleccionar]
#include <16F876.h>
#device adc=8

#FUSES NOWDT                  //No Watch Dog Timer
#FUSES HS                    //High speed Osc (> 4mhz)
#FUSES NOPUT                  //No Power Up Timer
#FUSES NOPROTECT              //Code not protected from reading
#FUSES BROWNOUT              //Reset when brownout detected
#FUSES NOLVP                  //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                  //No EE protection
#FUSES NOWRT                  //Program memory not write protected
#FUSES NODEBUG                //No Debug mode for ICD

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define delayTMR1us(x) (int16)(65536 - (x * 0.625))

static signed int16 cuenta;
#INT_EXT
void ext_isr(){
//suponiendo que la otra entrada del encoder está en RB1
if(input(PIN_B1)){
//de acuerdo a su estado considera la rotación en un sentido
cuenta++;
}else{
//u otro
cuenta--;
}
}

static short int transmitir;
#int_TIMER1
void TIMER1_isr(){
//recargar otros 50ms
set_timer1(delayTMR1us(50000));
//indicar transmitir
transmitir = 1;
}

void main() {
short int testBit = 0;

setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_2(T2_DISABLED,0,1);

//activar el timer 1 (%8)
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
//el compilador te pone la constante adecuada
set_timer1(delayTMR1us(50000));
//habilitar la interrupción
enable_interrupts(INT_TIMER1);

//definir el flanco de interrupción
ext_int_edge(L_TO_H);
//encender la interrupción externa
enable_interrupts(INT_EXT);
//activa todas las interrupciones
enable_interrupts(GLOBAL);

output_bit(PIN_B2, testBit);


//loop infinito
for(;;){
//hacer cosas...
//si se activa la bandera de transmitir
//es que pasaron 50ms
if(transmitir){
//por hacer: todos los procesos de transmisión
//un test para ver si funciona
//cada vez que pasa por acá le cambia el estado
//al pin RB2
if(testBit){
testBit = 0;
}else{
testBit = 1;
}
output_bit(PIN_B2, testBit);


//listo, borrar la bandera para que no se
//transmita hasta que pasen otros 50ms
transmitir = 0;
}
//hacer más cosas...
}
}
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 16 de Mayo de 2006, 05:45:41
Hi,

Muchas gracias marcelo, pero no puedo compilarlo aun, Flugplatz tiene razón necesito la PCW, haber si está en el paquete que nos enviaron los del CCS porque sino.... voy a tener algunos problemas jeje

El codigo tal y como lo pones tu, es más facil de entender ;). Así que espero que cuando tenga el PCW me compile OK.

Vosotros sabeis si puedo cargar directamente el codigo en el Mplab o en el proteus? o necesito obligatoriamente crear el archivo .hex??

Saludos

Cris :g)
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 17 de Mayo de 2006, 07:56:24
buenas,

Ya he conseguido que el compilador CCS me funcione, y el codigo me compila bien.

Ya he generado los archivos .hex

pero no consigo que la licencia del proteus se me instale correctamente, conoceis algun programa de simulación tipo proteus que sea gratuito? porque no puedo seguir comprando software sin entregar nada que funcione.

Segun tu codigo, supongo que el RB0 esta conectado el contador y en el RB1 esta conectado la segunda señal para detectar la dirección, verdad?

Me puedes explicar como se hace para enviar algo através de la UART? se puede enviar directamente un vector string?

necesito saber como implementarlo please.

Saludos

Cris
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba en 19 de Mayo de 2006, 09:38:30
Cris
Para transformar un número hexadecimal en BCD podés usar el siguiente algoritmo (es muy rápido, yo solo le hice la implementación para CCS).
Lo primero es la declaración de las variables, es un poco complex pero sirve para convertir variables de 8 y 16 bits. Utiliza 5 bytes de RAM y devuelve BCD empaquetado.

Código: [Seleccionar]
//Estructuras para el convertidor
//de binario a BCD
struct _NIBBLES{
byte _nibbleLongA:4;
byte _nibbleLongB:4;
byte _nibbleLongC:4;
byte _nibbleLongD:4;
byte _nibbleA:4;
byte _nibbleB:4;
byte _nibbleC:4;
byte _nibbleD:4;
byte _nibbleE:4;
};

struct BCD_BYTES{
int _binLbyte;
int _binHbyte;
int BCDbyteA;
int BCDbyteB;
int BCDbyteC;
};

union bin2BCD{
unsigned long _bin16;
struct _NIBBLES _nibble;
struct BCD_BYTES _byte;
};

//variable global de 5 bytes para la conversión
//binaria a BCD (hasta 65535) es una union que
//permite direccionar cada uno de los bytes y
//los nibbles para poder efectuar el algoritmo
//descripto
static union bin2BCD bin_2_BCD;


//Rutina para convertir la variable de intensidad de binario a BCD
//From: http://www.telesys.ru/wwwboards/mcontrol/20/messages/261.shtml
//A simple algorithm to convert binary to BCD is:
//1. Add 3 to every BCD nibble that's >=5
//2. Shift left
//Repeat until binary portion is all 0000

//convierte el dato binario en decimal
void convert2BCD(void){
int i;
bin_2_BCD._byte.BCDbyteA = 0;
bin_2_BCD._byte.BCDbyteB = 0;
bin_2_BCD._byte.BCDbyteC = 0;
for(i=0; i<16; i++){
if (bin_2_BCD._nibble._nibbleA > 4) bin_2_BCD._nibble._nibbleA += 3;
if (bin_2_BCD._nibble._nibbleB > 4) bin_2_BCD._nibble._nibbleB += 3;
if (bin_2_BCD._nibble._nibbleC > 4) bin_2_BCD._nibble._nibbleC += 3;
if (bin_2_BCD._nibble._nibbleD > 4) bin_2_BCD._nibble._nibbleD += 3;
if (bin_2_BCD._nibble._nibbleE > 4) bin_2_BCD._nibble._nibbleE += 3;
shift_left(&bin_2_BCD,5,0);
}
}
[code]

La implementación es la siguiente:
[code]
bin_2_BCD._bin16 = variableHex; //variable long (2 bytes)
convert2BCD();

//o
bin_2_BCD._byte._binLbyte = variableHex1; //variable byte
convert2BCD();

//luego de la conversión cada digito BCD particular está disponible en:
//bin_2_BCD._nibble._nibbleE -> mayor peso relativo
//bin_2_BCD._nibble._nibbleD
//bin_2_BCD._nibble._nibbleC
//bin_2_BCD._nibble._nibbleB
//bin_2_BCD._nibble._nibbleA -> menor peso relativo

//o en su versión empaquetada
//bin_2_BCD._byte.BCDbyteC
//bin_2_BCD._byte.BCDbyteB
//bin_2_BCD._byte.BCDbyteA
[code]

Para covertir a ASCII solo le debes sumar a cada nibble 0x30 y listo.
Para enviar por la USART en la próxima te comento como lo hago yo, seguramente habrá otras formas (y mejores).

Saludos
Marcelo

PD: es correcto, el encoder está conectado en RB0 y RB1 (RB0 es el que produce la interrupción)

[/code][/code][/code]
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 22 de Mayo de 2006, 08:41:28
Hola marcelo,

1)No acabo de entender para que necesito transformar un hexadecimal a BCD, ni donde se ha de introducir el 0X30
Supongo que es para adaptar la información del contador y de la dirección para enviarlo por la UART. Y para pasar de entero de 16 bits a ASCII con poco coste de la memoria del chip. ( si no es así dimelo porque a lo mejor estoy muy perdida)

2)Tu conoces algun simulador tipo Proteus que sea gratuito o que te den una licencia para un mes??

3)La UART al ser un "periferico" (ya se que esta dentro del xip, pero es a la vez independiente), se le puede poner la información en un registro y programando este, que se envie periodicamente lo que haya en ese registro independientemente de si se ha actualizado o no?? o se ha de ir ejecutando alguna sentecia para el envio?

Ya se que en un foro nunca se debe dar prisas, ni nada parecido pero agradeceria que me ayudaras a que me funcionara todo esto antes del jueves, ya que el viernes tengo una auditoria con los encargados del proyecto y les tengo que enseñar un codigo que funcione y si es posible alguna simulación, aunque tranquilo no quieren ver el proyecto finalizado sino los avances que he ido haciendo y me gustaria quedar lo mejor posible  :mrgreen:  please   :g)


Porcierto, ya he podido arreglar el CCS (simplemente estaba mal instalado) y los dos codigos (tanto el que tu me diste como el que yo habia puesto) se han compilado perfectamente, lo malo es que sin el proteus no puedo comprobar como funcionan, pero algo es algo. Hoy me ha llegado la placa de entrenamiento y si no consigo un programa tipo proteus, supongo que podre probar los codigos directamente sobre el microcontrolador, ya te contare al respecto ;)

Saludos

Cris
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba en 22 de Mayo de 2006, 11:00:03
Cris
Si mal no leí en uno de tus primeros mensajes necesitabas enviar la información via RS232 en formato ASCII y como los contadores internos trabajan en hexadecimal obviamente primero tenés que transformarlo a BCD y luego sumarle 0x30 a cada dígito para transformarlo en su caracter ASCII correpondiente (el dígito 0 en ASCII es 0x30), ahora si podés mandar el hexadecimal entonces no necesitas hacer nada de esto.

Podés usar el simulador del MPLAB (que es gratuito) que en la últimas versiones (yo uso la v7.31) es bastante elaborado y para un código poco complejo como el tuyo creo que te serviria bastante bien, inclusive puede simular entradas y salidas de la UART.

Para activar el simulador: Debugger -> Select tool -> MPLAB SIM
Para activar la simulación de la UART: Debugger -> Settings -> Uart1 IO, esto hace que en la ventana Output aparezca una pestaña extra que muestra los carateres enviados por el periferico.

Y respecto al envío de caracteres si vos implementás la rutina de enviar un buffer de datos que te envié dentro del programa que ya te habia posteado antes vas a ver en el simulador que cada 50ms se te envía el buffer completo, si vos no cambias los datos del buffer siempre manda lo mismo (la rutina no destuye el contenido del buffer).

Saludos
Marcelo
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 23 de Mayo de 2006, 06:09:50
Marcelo

Tienes razón lo que pasa es que no sabia que era necesario hacer ese paso,
La versión que yo tengo del MPlab es la 7.20 así que haré la simulación por el MPLAB finalmente

He seleccionado el MPLAB SIM tal y como me explicas, y he activado la UART1 IO

Pero me da dos errores

en la pestaña del MPLAB SIM me da el siguiente error:
 "CORE-E0002: Stack under flow error occurred from instruction at 0x002007"

y en la pesataña Build me pone

 "Clean: Deleting intermediary and output files.
  Clean: Done.
  Couldn't locate build tool.  Check tool locations.
  BUILD FAILED: Tue May 23 11:02:41 2006"

Ya tengo seleccionado el chip correctamente en Configure-> select device  que en mi caso es el PIC16F876

Sabes a que se deben esos errores?

Saludos
Cris  :g)

Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 23 de Mayo de 2006, 06:55:54
Marcelo

Déjalo, soy un poco despistada y no había cargado bien el archivo .hex y por eso me daban esos errores, ya los he solucionado  :P a veces no se ni donde tengo la cabeza jajaja

Ya he podido cargar bien el código y realizar la simulación, pero tengo dos dudas

1. Cuando tengo la pestaña Special Function Registers, para poder ver durante la ejecución los registros, Cual es el registro de la UART?

2. Se puede simular la señal de entrada? porque sino no se si esta funcionando correctamente, debería crear algún tipo de archivo que fuera la simulación de las señales de entrada?? con el matlab o Octabe?  o el propio Mplab te permite darle las características de las señales de entrada?

Saludos

Cris :g)

P.D: no hagas caso del post anterior ya que todos los errores que me salían era por haber cargado mal el archivo, es que es la primera vez que utilizo el mplab y los tutoriales que tengo no me hablaban de esos errores.
Título: Re: Programa de CCS para Pic16F876
Publicado por: marcegoncba en 23 de Mayo de 2006, 10:07:23
Cris
Podés hacer todo el proyecto dentro del MPLAB, incluyendo la compilación. Necesitás el plugin para enlazar el compilador con el MPLAB, lo podés bajar en http://www.ccsinfo.com/downloads/mplab-ccs-plugin-install.exe.
Luego creá el proyecto con: Project -> Project wizard, elegís el dispositivo y como lenguaje el "CCS C Compiler for PIC12/14/16/18" y luego los pasos que siguen (que son obvios y no necesitan explicación).
Para compilar Project -> Build All o presionas F10
Para verificar tiempos Debugger -> Stopwatch
Para simular entradas Debugger -> Stimulus Controller
Si activas el monitor de USART se abre una nueva pestaña en la ventana Output que te permite ver los carateres "enviados" por la USART
Para ir paso a paso, preionas F8 (y si querés ingresar dentro de las rutinas F7). Para que arranque hasta el próximo breakpoint F9, para detener la ejecución F5 y para resetear F6 (cada vez que compiles se resetea automáticamente).
Para ver el estado de las variables internas View -> Watch y etc., etc., etc. Por razones obvias no te puedo dar detalles de todas las funcinalidades porque son muchas, estas son las básicas (podes leer el help para una referencia completa).

Espero que te vaya muy bien en tu auditoria y que todo esto te haya servido. Saludos desde Argentina y nos estamos viendo.
Marcelo
Título: Re: Programa de CCS para Pic16F876
Publicado por: cristina_26 en 24 de Mayo de 2006, 07:19:06
Marcelo

Gracias, por todo.

Ya te contaré la semana que biene como me ha ido la auditoria, al final será el viernes porque mañana vienen a filmar el laboratorio de una TV y se ha aplazado (al menos tengo un dia extra) jejeje.

Lo de como funciona el MPlab lo habia aprendido de una guia rápida que me encontré por internet.

Y me he vuelto a leer todo desde el principio y he entendido algunas cosas que me explicabas en los primeros mensajes, así que creo que conseguiré que me funcione para el viernes.

Gracias por todo, ya te contaré

Saludos desde Barcelona  :g)

Cris