TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cibgris en 27 de Febrero de 2006, 17:23:00
-
Hola
Tengo una pregunta, que opinan del compilador de c hi tech, pro que no es tan comercial como el ccs
El problema es que yo programaba con el ccs pero tengo que utilizar el pic17c44 y el ccs no lo soporta encontre el hi tech y lo tengo pero no he podido progrmamar mi pic
me lo recomiendan o que puedo hacer? conocen algun otro programador que soporte el 17c44?
-
Hola cibgris, yo programo en Hi-Tech y lo encuentro encuntro bastante mas robusto que el CCS. Es probable que alguno se me vaya a enojar
, pero con CCS trabajas muchas veces con "cajas negras"
El tutorial lo encontras en http://www.htsoft.com/htmlman/picc/
Suerte!!
-
Dejanos conocer mas tu punto de vista del CCS y el HITECH, como es eso de las cajas negras. Animate que este es un foro de intercambio de opiniones y conceptos.
gfp
-
hay pues ya empece con la programacion con hi tech, pero me encuentro con muchos problemas ahora quiero establecer la comunicacion serie pero realmente no le entiendo muy bien al codigo, ustedes me podrian explicar como se establece la comunicacion, creo que mis conceptos sobre puerto serie no son muy buenos el codigo es el siguiente
/* Transmit and Receive port bits */
#define SERIAL_PORT PORTA
#define SERIAL_TRIS TRISA
#define TX_PIN 2
#define RX_PIN 1
/* Xtal frequency */
#define XTAL 4000000
/* Baud rate */
#define BRATE 9600
/* Don"t change anything else */
#define SCALER 10000000
#define ITIME 4*SCALER/XTAL /* Instruction cycle time */
#if BRATE > 1200
#define DLY 3 /* cycles per null loop */
#define TX_OHEAD 13 /* overhead cycles per loop */
#else
#define DLY 9 /* cycles per null loop */
#define TX_OHEAD 14
#endif
#define RX_OHEAD 12 /* receiver overhead per loop */
#define DELAY(ohead) (((SCALER/BRATE)-(ohead*ITIME))/(DLY*ITIME))
static bit TxData @ (unsigned)&SERIAL_PORT*8+TX_PIN; /* Map TxData to pin */
static bit RxData @ (unsigned)&SERIAL_PORT*8+RX_PIN; /* Map RxData to pin */
#define INIT_PORT SERIAL_TRIS = 1<<RX_PIN /* set up I/O direction */
void
putch(char c)
{
unsigned char bitno;
#if BRATE > 1200
unsigned char dly;
#else
unsigned int dly;
#endif
INIT_PORT;
TxData = 0; /* start bit */
bitno = 12;
do {
dly = DELAY(TX_OHEAD); /* wait one bit time */
do
/* waiting in delay loop */ ;
while(--dly);
if(c & 1)
TxData = 1;
if(!(c & 1))
TxData = 0;
c = (c >> 1) | 0x80;
} while(--bitno);
NOP();
}
char
getch(void)
{
unsigned char c, bitno;
#if BRATE > 1200
unsigned char dly;
#else
unsigned int dly;
#endif
for(;
{
while(RxData)
continue; /* wait for start bit */
dly = DELAY(3)/2;
do
/* waiting in delay loop */ ;
while(--dly);
if(RxData)
continue; /* twas just noise */
bitno = 8;
c = 0;
do {
dly = DELAY(RX_OHEAD);
do
/* waiting in delay loop */ ;
while(--dly);
c = (c >> 1) | (RxData << 7);
} while(--bitno);
return c;
}
}
char
getche(void)
{
char c;
putch(c = getch());
return c;
}
Sinceremente entiendo la definicion de variables pero en la parte de DELAY(ohead) (((SCALER/BRATE)-(ohead*ITIME))/(DLY*ITIME))
no comprendo la opercion y me parece que es necasaria para establecer la comunicacion
-
hay pues ya empece con la programacion con hi tech, pero me encuentro con muchos problemas ahora quiero establecer la comunicacion serie pero realmente no le entiendo muy bien al codigo, ustedes me podrian explicar como se establece la comunicacion, creo que mis conceptos sobre puerto serie no son muy buenos el codigo es el siguiente
/* Transmit and Receive port bits */
#define SERIAL_PORT PORTA
#define SERIAL_TRIS TRISA
#define TX_PIN 2
#define RX_PIN 1
/* Xtal frequency */
#define XTAL 4000000
/* Baud rate */
#define BRATE 9600
/* Don"t change anything else */
#define SCALER 10000000
#define ITIME 4*SCALER/XTAL /* Instruction cycle time */
#if BRATE > 1200
#define DLY 3 /* cycles per null loop */
#define TX_OHEAD 13 /* overhead cycles per loop */
#else
#define DLY 9 /* cycles per null loop */
#define TX_OHEAD 14
#endif
#define RX_OHEAD 12 /* receiver overhead per loop */
#define DELAY(ohead) (((SCALER/BRATE)-(ohead*ITIME))/(DLY*ITIME))
static bit TxData @ (unsigned)&SERIAL_PORT*8+TX_PIN; /* Map TxData to pin */
static bit RxData @ (unsigned)&SERIAL_PORT*8+RX_PIN; /* Map RxData to pin */
#define INIT_PORT SERIAL_TRIS = 1<<RX_PIN /* set up I/O direction */
void
putch(char c)
{
unsigned char bitno;
#if BRATE > 1200
unsigned char dly;
#else
unsigned int dly;
#endif
INIT_PORT;
TxData = 0; /* start bit */
bitno = 12;
do {
dly = DELAY(TX_OHEAD); /* wait one bit time */
do
/* waiting in delay loop */ ;
while(--dly);
if(c & 1)
TxData = 1;
if(!(c & 1))
TxData = 0;
c = (c >> 1) | 0x80;
} while(--bitno);
NOP();
}
char
getch(void)
{
unsigned char c, bitno;
#if BRATE > 1200
unsigned char dly;
#else
unsigned int dly;
#endif
for(;
{
while(RxData)
continue; /* wait for start bit */
dly = DELAY(3)/2;
do
/* waiting in delay loop */ ;
while(--dly);
if(RxData)
continue; /* twas just noise */
bitno = 8;
c = 0;
do {
dly = DELAY(RX_OHEAD);
do
/* waiting in delay loop */ ;
while(--dly);
c = (c >> 1) | (RxData << 7);
} while(--bitno);
return c;
}
}
char
getche(void)
{
char c;
putch(c = getch());
return c;
}
Sinceremente entiendo la definicion de variables pero en la parte de DELAY(ohead) (((SCALER/BRATE)-(ohead*ITIME))/(DLY*ITIME))
no comprendo la opercion y me parece que es necasaria para establecer la comunicacion
-
A que te refieres con "cajas negras"?
-
Hola!!
se que este es un hilo muy viejo... pero por desgracia descubri lo que es una "Caja negra".... con dolor
una caja negra es un comando que aparentemente hace todo automaticamente por ti (y no sabes y generalmente no quieres saber como lo hace).
es decir
Datos--->[milagro]---> Resultado
lo que pasa es que a veces esas cajas negras, pueden traicionarte....
fijense...
tengo "algo" que va a ser controlado por el pic...
en CCS llenaba un arreglo y enviaba (via serial) un cierto numero de bytes. ese "algo" los entendia, hacia lo que se le ordenaba y contestaba... pues ¡oh sorpresa! resulta que algo rarisimo pasaba y a veces magicamente, de la serie de bytes el CCS o me modificaba uno de elos o se comia algunos
eso y el hecho de no aceptar pasar parametros constantes a punteros, me decidio usar el HI TECH en lugar de mi amado CCS. lo pedi prestado pues aun no estoy seguro de comprar la licencia.
solo que ahora en el procedimiento getch, identico al mostrado por cibgris, me da problems
es decir, por ejemplo, si en un main.c
digo
Var[0]=getch();
Var[1]=getch();
Var[2]=getch();
Var[3]=getch();
Var[4]=getch();
y estoy absolutamente seguro que ese algo va a contestar 5 bytes. Resulta que mi amigo el PIC solo recibe el caracter 0, el 3 y el 5.... y se queda guindado en Var[3]=....
alguien tiene una idea... de hecho, ese codigo, el presentado por cibgris es perfecto para mi, pues me interesa no manejar el serial por interrupcion, pues
1) deseo tener mas de una comunicacion serial (no simultanea) y
2) si en algun momento se interrumpe, es el apocalipsis
gracias por leer
-
Si te da problemas el gectch, y dices que no te gustan "las cajas negras"
Pues hacelo todo a mano, como me gusta hacerlo a mi...
y pones algo así mejor:
while(!RCIF);
var[0] = RCREG;
while(!RCIF);
var[1] = RCREG;
while(!RCIF);
var[2] = RCREG;
while(!RCIF);
var[3] = RCREG;
while(!RCIF);
var[4] = RCREG;
lo que haria basicamente es esperar a que el buffer del UART reciba algo, y luego lo almacena, ahora si dejas de recibir
pues el programa se quedara ahi, para lo que puedes hacerlo en un bucle while todo esto, y hacerlo funcionar en paralelo
de modo de hacer una funcion "timeout"...
Ahora si lo quieres hacer aun mas acabado, hace un bucle de repeticion y lo haces una funcion de modo que le puedas
especificar cuantas veces quieres que reciba (Cuantos caracteres), el timeout y te ahorras el getch, el problema de que
"se corte el cable" y no usas siquiera el gecth();
-
Es una gran idea..... Rodricity,
pero y si quisiera implementar (como hace mi amigo el CCS) varios puertos Seriales NO uart?
con el getch, me refiero a la rutina que publico cibgris y que él, y el ejemplo que traen el HI-TECH llamo char getch()
y yo, para evitar confusiones llamé char dame_aca()... esta rutina se veia buenisima, pues fijate, pero me da curiosidad en sabe por qué falla
#define SERIAL_PORT PORTC
#define SERIAL_TRIS TRISC
#define TX_PIN 6
#define RX_PIN 7
static bit TxData @ (unsigned)&SERIAL_PORT*8+TX_PIN; /* Map TxData to pin */
static bit RxData @ (unsigned)&SERIAL_PORT*8+RX_PIN; /* Map RxData to pin */
char dame_aca(void) // el original se llamaba getch
{
unsigned char c, bitno;
#if BRATE > 1200
unsigned char dly;
#else
unsigned int dly;
#endif
for(;;) {
while(RxData)
continue; /* wait for start bit */
dly = DELAY(3)/2;
do
/* waiting in delay loop */ ;
while(--dly);
if(RxData)
continue; /* twas just noise */
bitno = 8;
c = 0;
do {
dly = DELAY(RX_OHEAD);
do
/* waiting in delay loop */ ;
while(--dly);
c = (c >> 1) | (RxData << 7);
} while(--bitno);
return c;
}
}
lo grandioso de este codigo es que con cambiar la cabecera, puedes colocar el puerto serial en cualquier par de pines
¿que opinas?
-
offtopic:
las cajas negras que mencionas tougteno, son los llamados BuiltIn, o funciones encapsuladas, yo también me he encontrado con sorpresas, pero nada que no se pueda resolver haciendo la función "a pie"
-
Pues...
Debo aclarar algo, y es que no entiendo practicamente... nada... de tu codigo.
Pero hablando en generalidades, para poder hacer un "uart" en algun otro par de pines, si se puede,
pero el problema seria el "estar pendiente" de hacer una tarea x mientras estas recibiendo.
Es decir, no se puede, necesitarias algun pin con interrupciones, ahora por otro lado, si estuvieses
especificamente escuchando/recibiendo, si se podria implementar...
Bueno, solo con eso puedo ayudarte, implementar un puerto seria en otro par de pines, mediante
codigo si se puede, pero si quieres realmente entender como "funciona" vas a terminar escribiendolo
tu, aunque escribas exactamente lo mismo que intentaste entender, o almenos yo casi siempre
termino asi, si quiero entenderlo debo escribirlo yo mismo... o bien que el creador te explique...
Voy a escribir algun codigo a ver si logro ensamblar un puerto serie en pines que me de la gana...
aunque no le veo mucha utilidad a no ser que tu pic no tenga el puerto ya.
PD: Creo que nunca lo aclaré, yo sali de enseñanza media el año pasado, no se si se entiende, simplemente
estudie en la escuela y yá, aun no entro a la universidad ni nada, asi que si digo alguna parrafada me dicen,
ya que soy bastante limitado de conocimientos, pero creatividad no :D
-
AmigoRodricity,
1.- La intencion es la que cuenta, y en este campo no se necesita un PhD, sino las ganas de hacer (por eso gracias por la respuesta).
2.- Lo que dices es cierto, y precisamente, me interesa en cierto momento que el pic se quede olfateando las respuestas del otro dispositivo y no se mueva hasta que el otro dispositivo me responda, porque si no me responde.... no me serviria de mucho seguir ejecuntando instrucciones.
3.- Claro, no es "mi codigo". tal como dije, lo copie (y está permitido, pues el ejemplo dice para copiar y usar) de un ejemplo basico que trae el HI-TECH 8 y se llama "bit Banging". es complejo y realmente tampoco se a precision como lo hace, pero sé que ejecuta un shitf register (eso es el << y el >>) o corrimiento de bit, para capturar bit por bit y convertirlo en un byte y que toma una muestra cada cierto tiempo calculado a partir de la tasa de transmicion en baudios desde la primera vez que percibe un bit de start.
y PalitroqueZ:
me parece que mas bien es un "Heart-of-the-topic" mas que un off topic... es decir, lo que comentas como que va por el meollo del asunto. De hecho dices, que al fallar los built-in (¿Prefabricados seria la traduccion?), hay que hacerlos a pie. y tu que recomendarias? hacerlo a pie en CCS o en HI TECH? tienes alguna idea fija o ya lo has hecho? siempre pense que la comunicacion serial era lo mas simple... y la he utilizado muchas veces, pero esta vez me he vuelto un embrollo....
si tienes una idea... Bienvenida con bombos y platillos!!!! :mrgreen:
-
Hola Dancrazy
una vez tuve problemas con las funciones SPI que incorporaba el ccs, no se si era un bug ó es que no la supe utilizar, lo cierto es que me puse a estudiar un código que habian hecho en asm y que hacia la comunicación spi y luego la lleve al C y Listo, resolví el problema.
en el hitech (corrijanme) creo que no tiene funciones para enviar datos seriales y las que consiguen por allí son construidas a pie, es decir, lo mismo que había hecho en mi caso.
mi humilde sugerencia es que pruebes la facilidad que te da el compilador, si no te funciona, entonces no quedará de otra que a pie, mi hermano :D
-
Gracias por la respuesta...
Diablos!!! me lo temia....
voy a intentarlo, pero la rutina que mostre anteriormente, funciona muy bien para enviar (desde el PIC) pero falla para recibir...
seguiré buscando ...
-
Muy bueno el hilo, también uso Hi-tech y me gusta mucho este compilador.
El problema para recibir datos seriales sin interrupción es que existe el riesgo de empezar a leer los datos en el momento que no es, el pic esta ejecutando otro código y empezamos a leer los datos seriales un poco tarde, se toma un bit de dato como el bit de inicio y de ahi para delante toda la información llega mal.
Recuerdo que hace tiempo en ensamblador implementé dos puertos seriales en un pic sin usart, lo que hice fue hacer una or con las dos entradas de datos seriales y la salida de la or (or con diodos para no usar compuertas) la conecté a la entrada de interrupción externa, cuando se disparaba la interrupción por flanco de bajada examinaba cual de las dos entradas había provocado la interrupción y empezaba a recibir los datos desde ese pin, la interrupción externa no la reactivaba hasta que no terminara de recibir un dato completo. De esta forma me olvidaba de los puertos seriales a no ser que se presentara una interrupción, el problema es que con este método se le da prioridad al dato que llegue primero y el otro se pierde.
Saludos,
Diego.
-
creo que tu comentario es acertado dhmejia.
teniendo esto (que es lo que tengo)
[PIC]<------->[Modulo]
al que he llamado "modulo", yo le envio una serie de bytes donde va
1.- Formato de envio (como cabecera de mensaje, 2 bytes fijos)
2.- numero de bytes que conforman el comando (1 byte)
3.- Codigo hexa que representa un comando (1 byte)
4.- parametros que acompañan al comando (varios bytes, de ninguno a 16)
5.- codigo de deteccion de error (1 byte)
Todo esto lo recibe el "modulo", via serial (TTL), lo interpreta, ejecuta y responde con otro numero de bytes, cuya cantidad y contenido es predecible.
Pues bien, como ya habia dicho, el PIC envía bien, y el modulo ejecuta y responde bien.
el problema es que de los bytes que esperaba recibir, siempre se "come" (omite) uno
si son 5 bytes recibe el primero, el tercero y el quinto....
y parece ser lo que tu dices... recibe el primer byte de respuesta del "modulo" y mientras lo procesa, llega el segundo, y mi PIC ni se entera, llega el tercero, y ése si lo detecta... mientras procesa ese tercero, llega el cuarto, y el PIC no se entera, termina, llega el quinto y ése tambien lo detecta....
creo que eso es lo que pasa... entonces deberia tratar de lograr que el "modulo" no se apresure tanto y espere un poco mas entre byte y byte. o quizas, colocar un cristal mas rapido ¿10 MHz? pa que el PIC procese a tiempo...
-
Hola
Tengo una pregunta, que opinan del compilador de c hi tech, pro que no es tan comercial como el ccs
El
problema es que yo programaba con el ccs pero tengo que utilizar el pic17c44 y el ccs no lo soporta encontre el hi tech y lo tengo pero no he podido progrmamar mi pic
me lo recomiendan o que puedo hacer? conocen algun otro programador que soporte el 17c44?
El hitech pro tiene su nicho de mercado en entornos de empresas con más dinero y que tal vez trabajen con varios micros. Hitech sale u$s 1000 para los 16F y lo mismo para los 18F... osea, necesitas al menos 2000 u$s para comenzar.
Esa es una gran traba para comenzar, frente a los 200 u$s del ccs.
Ese micro que quieres usar es muy antiguo y fue superado por los 18F. Realmente necesitas usar ese?
Pues hacelo todo a mano, como me gusta hacerlo a mi...
y pones algo así mejor:
while(!RCIF);
var[0] = RCREG;
while(!RCIF);
var[1] = RCREG;
while(!RCIF);
var[2] = RCREG;
while(!RCIF);
var[3] = RCREG;
while(!RCIF);
var[4] = RCREG;
Rodricity ten presente que debieras también leer el flag de error de la usart. Si por alguna razón ocurre un Overrun, dejarás de recibir y nunca saldrá del bucle. El flag rcif no se encenderá mas. Eso solo se soluciona reseteando la usart.
Lo digo por las dudas.
-
Bueno, respondo un poco atrasado...
El otro dia habia implementado un puerto serial a mano en dos pines del puerto B, y utilizaba un timer para controlar los
"pulsos de reloj" de la transmision asincrona, y a la vez que recibia iva devolviendo los mismos valores...
Si quieres te subo el archivo y la simulacion en proteus...
-
¡Fantabuloso! :lol:
(Fantastico+Fabuloso) :o
seria un gran aporte.... :D
claro, podria hacerle yo unas modificaciones, pues mi necesidad es que se comporte como un getc (que no salga del procedimiento hasta que no reciba la respuesta... es decir, si se tarda una hora en recibirlo, pues que se quede una hora esperando). En otros casos eso seria terriblemente ineficiente, pero en este caso es necesario....
gracias!!!
-
subiendolo...
-
Listo, ahí esta.
-
Gracias por el aporte,
estoy probandolo....
se ve bueno....
-
Falta imlementar el "enviar datos"
via algun pin, ya que simplemente esta usando interrupciones del timer para saber "cuando" esta recibiendo cada bit...
Ahora yo creo que se podria hacer eso en un bucle para hacerlo mas eficiente, bueno, eso queda para desarrollarse.
ahi esta el concepto y la idea, falta implementarlo.