TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Siempre aprendiz en 05 de Mayo de 2008, 14:34:00
-
Buenas. Como veis son novel en esto y me he astascado en lo mas sencillo de todo, crear dos puertos serie en un triste 16f876
Lo único que quiero que haga es que envíe y reciba por dos puertos serie.
El programa que tengo escrito es este:
#include <stdio.h>
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=COM_A)
#use rs232(baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8,stream=COM_B)
char recibido;
#int_RDA
void RDA_isr(void)
{
disable_interrupts(INT_RDA);
recibido=getc(COM_A);
putc(recibido,COM_A);
enable_interrupts(INT_RDA);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
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);
// TODO: USER CODE!!
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
set_tris_c(0b10101010);
while(1)
{
if(input(PIN_B0))
{
output_high(PIN_B1);
}else{
output_low(PIN_B1);
}
if( kbhit(COM_B) )
{
recibido=getc(COM_B);
putc(recibido,COM_B);
}
}
}
Ahora explico lo que me ocurre.
- Simulándolo el puerto COM_B funciona de maravilla pero el COM_A no funciona.
- Montado físicamente el COM_A funciona de maravilla pero el COM_B no funciona.
Las entradas del PIC no están rotas porque se han comprobado varias veces leyendo si estaban a '1' o a '0'
Si alguien es tan amable de ayudarme a crear dos puertos serie se lo agradecería
PD: Compilador CCS
-
Hola.
Hay que tener especial cuidado en la definicion de las subfunciones las cuales usan uno de los COM, el stream no mas no es suficiente (a mi me paso igual)
En el ejemplo del CCS EX_ENCRY.c esta el manejo de dos USART (una es por soft y la otra es por hard)
Adjunto parte del codigo que use en algo similar (basada en el manejo de interrupciones del gran RedRaven).
#include <18F452.h>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, BORV45, PUT, NOLVP
#use delay(clock=4M)
#include "DS1302.C"
#include "LCDD.C"
#include "KBDB.C"
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)// puerto 1 //////////////////////////////////////////////////////////////////////
int const lenbuff=32;
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último carácter recibido
int1 flagcommand=0; // Flag para indicar comando disponible
char bgetc1()
{
char c;
c=getc();
return(c);
}
void putc1(char c)
{
putc(c);
}
void inicbuff(void)// Inicia a \0 cbuff ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////-------------------
{
int i;
for(i=0;i<lenbuff;i++)
{ // Bucle que pone a 0 todos los
cbuff[i]=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el índice de siguiente
// carácter
}
void addcbuff(char c)// Añade a cbuff ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////-----------------------
{
switch(c)
{
case '\r': // Enter -> Habilita Flag para procesar
flagcommand=true; // Comando en Main
break;
case '\n':
flagcommand=true;
break;
case ' ':
break;
default:
cbuff[xbuff++]=c; // Añade carácter recibido al Buffer
}
}
#int_rda
void serial_isr() // Interrupción recepción serie USART ///////////////////////////////////////////////////////////////////////////////////////////////
{
rcvchar=0x00; // Inicializo carácter recibido
if(kbhit())
{ // Si hay algo pendiente de recibir ...
rcvchar=bgetc1(); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer
}
}
#use rs232(baud=9600, xmit=PIN_C4, rcv=PIN_C5, bits=8, parity=N)// puerto 2 //////////////////////////////////////////////////////////////////
char bgetc2()
{
char c;
while(!kbhit());
c=getc();
return(c);
}
void putc2(char c)
{
putc(c);
}
Ya en el main hago lo siguiente:
void main (void)
{
while(true)
{
printf(putc1,"com1\r\n");
printf(putc2,"com2\r\n");
}
}
Toca colocar despues de la directiva #use rs232... las funciones concernientes a ese stream.
La simulacion de todo el programa corre muy bien (lo estan montando en HW en estos dias, asi que no se si funcione en hard, pero, casi siempre, lo que me ha salido en proteus me ha salido en en hard, asi que estoy muuuuy confiado ...... :D la verdad espero que si salga!!!! si no, no hay pago!!!!! :D :D :D :D )
La razon de que en hard te corra bien el COM_A, creo que es que la interrupcion esta conectada justamente a esos pines el c6 y el c7 y porque en soft corre al reves? creo que es porque despues de definir el #use rs232 para el COM_B, esta definido la funcion de interrupcion.
Prueba a ver y me cuentas.
Saludos
-
Otro punto de vista:
Si lo quieres hacer totalmente por interrupción (los 2 RS232) uno hazlo por hard empleando interrupción RDA y el otro RS232 hazlo por software empleando interrupción RB0.
La forma de hacerlo está en el ejemplo EX_ENCRY.c
-
Oye gran pocher.
Cuando yo simule el EX_ENCRY.C el puerto que se manejaba con la interrupcion de RB0, me salian unos caracteres raros (segun el ejemplo estaban encriptados). Hay alguna manera de usar esa interrupcion, pero que no me afecte el string?? Pues, como para tener las 2 usart normales, porque tal como lo pintan en el ejemplo se necesitaria otro pic para decodificar y enviar al PC.
Saludos
-
Gracias por hablarme del EX_ENCRY.C, hay que ver tan cerca que lo tenía y no me dí cuenta.
Ahora bien, me ha asaltado la misma duda que a MLO__ ¿Como podemos hacer que no salga encriptado?
Inocente de mí he creido que copiando y pegando el que no se encripta (y cambiando los sufijos de las variables y funciones) me iba a funcionar pero no xD
-
:D :D :D :D :D :D
Yo hice lo mismo!!!!!
Lo que hice finalemente fue ordenar la comunicacion entre los dispositivos (quitando la interrupcion en RB0), y dejar solo la interrupcion RDA. Como solo necesitaba enviar el dato a la PC, entonces fue factible dejarlo asi. Pero en el caso de tener que comunicarme con dos dispositivos en full duplex, tendria serios problemas :shock:
Esperemos la respuesta del maestro pocher
Saludos
-
Grande no. Pocher, con pocher a secas voy que me mato.
Para que os funcione y no encripte los datos, lo único que teneis que añadir es la detección del bit de Start en el main: ext_int_edge(H_TO_L)
-
Ok...
Tu humildad refleja tu conocimiento amigo.... Gracias por el tip. Lo voy a probar ahora mismo
Saludos
-
Gracias.
Ahora he avanzado un poco mas pero poco.
Simulado los dos puertos serie funcionan perfectamente.
Montado físicamente solo me funciona el que va por harware, el otro como si no hiciera nada.
Al final creo que usaré solo el de harware pero controlándolo por medio de dos pines para decirle que los datos que llegan son del pc1, del pc2 o que no tienen que llegar datos
-
y por q no probás con un multiplexor??? si la transmisión de datos no es necesariamente simultánea, yo creo q sería lo mejor. Podrías usar algun pin extra para indicar con quién se va a comunicar.
Saludos!
-
¿y porqué no una simple red RS232? ¿Cuales son los componentes de la red? ¿Quien va a hacer de Master, ó son todos Esclavos? ¿Como funciona la comunicación?
Muchas preguntas, pero necesarias para saber como ayudarte.
-
Me parece raro que no funcione el puerto de soft, yo lo he montado en pics 12F y si funciona (simulacion y hard) no habra algo ahi en la configuracion de la comunicacion?? (como la paridad u otra cosa)
Saludos
-
Cuando iba a contestar, te has adelantado MLO.
Iba a preguntarle lo mismo que tú. Si estaba seguro de tener todo bien conectado, ya que se trata de un ejemplo de CCS y que a la fuerza tiene que funcionar.
-
:mrgreen:
-
Disculpar la tardanza en contestar.
La conexión está bien hecha ya que para confirmarlo, después de muchos intentos, decidí utilizar los mismos pines del max para comprobarlo. (Primero lo probaba con un puerto y luego cambiaba los cables con el otro para descartar malas conexiones)
Me parece que el problema va a ser el propio programador (el harware) ya que muchas veces 'dice' que esta bien grabado pero realmente no lo hace. Además de tener que pasar el programa con el icprog unas 5 ó 6 veces antes de que diga que ha pasado bien.
-
Hola.
Extrano..... que programador tienes?
-
Estoy intentando cambiar el manejo del puerto serie de pines
En lugar de:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Configuracion puerto serie
Utilizo:
#use rs232(baud=9600, xmit=PIN_B1, rcv=PIN_B2) // Configuracion puerto serie
El caso es que si cambio esa linea y coloco el puerto a la escucha en los correspondientes pines no responde. :(
Puede ser que por tener el bootloader no haya posibilidad de cambiar el pinout del puerto serie?¿?
Un saludo.
-
Saludos.
Podrias colocar mas codigo por favor?
-
Hola a todos, me podrian sacarde una duda, yo necesito usar un modulo MemoryStick Datalogger para mi tesis, ya lo probe y funciona bien, pero no se como hacer que el pic se entere si es que existe o no conectada una pen a este modulo.
Buscando por internet, logre ver que otra programador de ccs, usa una interrupcion por recepcion de datos, lo que yo entiendi es que cuando se conecta un pen a este modulo, se produce una interrupcion de recepcion de datos en el pic, pero no se ni cual sea o como verla, me podrian ayudar con esto???
Tambien quisiera saber como crear arrays de caracteres de tamano variable, ya que este modulo me envia respuestas de diferente tamano de bytes y lo que me sucede es que tengo que esperar a que el buffer se llene para que mande el mensaje completo al lcd(2x16), lo que hace que mescle los mensajes.
Gracias por todo y espero su ayuda atentamente.
David Nunez