TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: UDMIGUEL en 26 de Julio de 2010, 16:49:48
-
hola
soy novato en el foro, y he estado leyendo varios ejemplos relacionados con este tema
pero aun no doy con el problema
tengo que implementar 2 rs232 en un mismo pic
(uno por hardware y el otro por software)
el inconveniente es que el de hardware funciona correctamente, pero el de software no...
se pierden datos y los que llegan algunas veces son erroneos
segun lo que he leido, es inconveniente del reloj
(aunque todos afirman que con reloj externo nunca presenta problema, y a mi incluso con reloj externo tampoco me funciona)
otra cosa que debo aclarar es que por el momento estoy haciendo todas mis pruebas en simulacion
si alguien puede ayudarme, le envio el archivo ccs y el de proteus
muchas gracias
-
Primero, la velocidad de comunicacion depende del cristal que utilices, no puedes poner cualquiera.
Segundo, no importa que hagas mientras atiendes las comunicaciones (burda mentira), debes asegurarte de atender bien las comunicaciones y no cometer errores.
Elige una velocidad baja para el puerto que atiendes por software y una alta para el de hardware.
Si ademas por el de software solo envias y recibes poca informacion mejor, de otro modo te conviene habilitar una interrupcion para el que ahora atiende el software.
-
gracias por responderme MGLSOFT
mira, te comento que primero me lanze a armar todo el programa
(un pic toma los datos de un modulo gps, y los envia a otro pic)
pero como se me presentaron los problemas que ya mencione, ahora estoy revisando con una simple prueba de leer lo que llega
y enviarlo inmediatamente
aqui el codigo
#include <16F628A.h>
#fuses INTRC_IO
#use delay(clock=4000000)
#use rs232(baud=4800, xmit=PIN_A1, rcv=PIN_A0, bits=8, stream=GPS) //RS232 por software.
#use rs232(baud=4800, xmit=PIN_B2, rcv=PIN_B1, bits=8, stream=CENTRAL) //usando USART
char valor;
void main(){
while (true){
valor = fgetc(GPS);
fputc(valor,GPS);
}
}
pero aun asi, planteando esta prueba sencilla, sigue leyendo caracteres incorrectos
donde esta el error?
gracias
-
bueno, acabo de realizar una prueba mas que se me ha ocurrido
primero tomo 10 datos, y luego si publico los 10
al parecer, ay si lee correctamente
:-/ :-/ :-/
lo que me causa curiosidad es que por el rs232 de hardware, yo puedo leer el dato, analizarlo y trasmitir, uno a uno
mientras que por el rs232 de software, me veo obligado a leer todo primero, y luego si analizar y trasmitir
esto es asi?
o existe una forma de configurar el rs232 de software, para que "iguale el rendimiento" del de hardware?
desde ya, muchas gracias por la atencion y las respuestas
-
Saludos!
Revisa el sitio del maestro RedPic: http://picmania.garcia-cuervo.net/proyectos_aux_rs232_x_2.php
Espero que te ayude. Yo lo he usado y funciona a las mil maravillas.
-
gracias xp8100
ya habia tenido la oportunidad de revisar ese sitio
muy interesante
la cosa es que segun veo el maestro RedPic utiliza el segundo rs232 solo para trasmision
en mi caso lo necesito para recepcion
por el momento la unica solucion que he encontrado a punta de pruebitas es la que comentaba anteriormente
leer todos los datos, y luego analizar y enviar
talvez sea una limitante del rs232 por software
(pero eso es lo que quiero rectificar, porque es solo mi teoria)
y ademas, me serviria mas si puediera configurar esto, ya que me liberaria ram
muchas gracias por la ayuda
-
Buenas, ahun soy un poco inexperto en el tema, pero yo entiendo que el problema que puedas tener por soft es que una vez recibido el primer Byte y lo intentas reenviar inmediatamente, ya te esta llegando el segundo Byte y al intentar leer el 2º ya solo coges los ultimos bits de este y los primeros del 3º y asi susecivamente.
Te digo esto pq es lo que me pasó a mi cuando empece con la programación en (ASM) e intentaba enviar una trama del PC al pic y que este me lo devolviera. En aquella usaba la rutina que me venia de ejemplo en el libro (pic16f84 desarollo de proyectos) la manera en que pude solucionarlo fue modificando la libreria (asm). De toda variación que recibía en el puerto de entrada la tramitaba al de salida y a parte de eso, tuve que acortar el tiempo de espera entre lectura de bits.
En C creo creo que el tema es mas complicado por el tema del control de tiempos, ya que los calculos creo que son mas o menos a papel y luego ajustar los retardos con el simulador.
Has provado me mezclar soft y usart? es decir, recibir el dato por sof y enviarlo por usart y por otro lado recibir por usart y enviar por soft. Nunca lo he provado, ni siquiera se si podria solucionar el problema ya que no se como funciona realmente el usart ya que siempre lo he manejado con las librerias.
Un saludo
-
gracias por tu respuesta tannke
yo tambien veo el problema por el mismo lado
(cuestion de tiempos)
me causo curiosidad la prueba que sugerias
(mezclar el de software con el de hardware)
y acabo de realizarla, pero aun los mismo inconvenientes...
creo que voy a optar definitivamente por una rutina de solo lectura almacenando en un vector
(hasta donde la ram me lo permita)
y luego si hago el analisis y envio
muchas gracias a todos por sus respuestas :mrgreen:
-
Hola a todos,
estoy intentando implementar dos rs232 en un 16F877 y no consigo hacer que funcione el que hago por software, creo que me dejo alguna configuración de timers o algo así, pero no se el que... :5] :5] :5]
Esta es la definición que hago de los puertos,
#use rs232(baud=600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,stream=PUERTO_PC) // Hardware
#use rs232(baud=600,parity=N,bits=8,stop=1,xmit=PIN_B4,rcv=PIN_B5,stream=PUERTO_RF) // Software
ejemplo de como lo utilizo...
#int_RDA
void RDA_isr(void)
{
if(kbhit(PUERTO_RF))
{
dato_rx=getc(PUERTO_RF);
...
...fin
Alguien me puede comentar si hay que configurar algo mas?!?!?!
gracias y un saludo...
-
Hola.
Con que cristal estas trabajando? Como lees el dato de la USART por soft?
Puedes subir el resto del codigo? Normalmente no da problemas el trabajar 2 USART.
Saludos
-
Hola.
Con que cristal estas trabajando? Como lees el dato de la USART por soft?
Puedes subir el resto del codigo? Normalmente no da problemas el trabajar 2 USART.
Saludos
Hola MLO__, el xtal es de 4MHz, aquí va el código...
lo que hago de momento es enviar del PC al PIC una cadena de caracteres con una 'Z' como final de trama, el PIC la envía al LCD y la retorna por el RS-232 otra vez al PC para ver el correcto funcionamiento.
#include "16F877.h"
#include <string.h>
#include <stdlib.h>
//Configuramos el reloj a 4MHz
#use delay(clock=4000000)
#include "lcd.c"
//Configuramos los parámetros del puerto RS-232
#use rs232(baud=600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,stream=PUERTO_PC)
#use rs232(baud=600,parity=N,bits=8,stop=1,xmit=PIN_B4,rcv=PIN_B5,stream=PUERTO_RF)
#byte porta=0x05
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08
//Configuramos los fuses adecuados
#fuses NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
char dato_rx;
char cadena_rx[10];
int1 flag_rx=0, p_to_m, s_to_m, trama_completa, trama_ok;
int8 incremento_cadena=0;
void borrar_lcd()
{
lcd_gotoxy(1,1);
printf(lcd_putc," ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
lcd_gotoxy(1,1);
}
void inicializar_pcb(void)
{
lcd_init();
dato_rx=32; flag_rx=0; p_to_m=0; s_to_m=0; trama_completa=0; trama_ok=0;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
void anadir_buffer(char b)
{
if(b==0x5A) //mira si el dato recibido es una 'Z' de final de trama
{
flag_rx=1;
}
else
{
cadena_rx[incremento_cadena]=b;
incremento_cadena++;
}
}
void borrar_buffer(void)
{
int8 index=0;
for(index=0;index<10;index++)
{
cadena_rx[index]=0;
}
incremento_cadena=0;
}
void mostrar_cadena(void)
{
int index=0;
for(index=0;index<incremento_cadena;index++)
{
printf(lcd_putc,"%c",cadena_rx[index]);
printf(cadena_rx[index],PUERTO_PC);
}
}
#int_RDA
void RDA_isr(void)
{
if(kbhit(PUERTO_PC))
{
dato_rx=getc(PUERTO_PC);
anadir_buffer(dato_rx);
}
}
//Programa principal
void main(void)
{
borrar_buffer();
inicializar_pcb();
while(TRUE)
{
if(flag_rx==1)
{
mostrar_cadena();
borrar_buffer();
flag_rx=0;
delay_ms(1000);
borrar_lcd();
}
}
}
si utilizo el USART por HW que trae el pic no tengo problema y funciona correctamente (PUERTO_PC), pero si utilizo la USART por SW (PUERTO_RF) no se entera de nada...
gracias y un saludo...
-
Hola.
La función para enviar datos cuando usas mas de una USART es fprintf(). En el código no veo que uses la USART para PUERTO_RF.
Saludos
-
Hola.
La función para enviar datos cuando usas mas de una USART es fprintf(). En el código no veo que uses la USART para PUERTO_RF.
Saludos
Buenas, de momento no la utilizo porque lo que hago es ir cambiando PUERTO_PC por PUERTO_RF para probar que funcionen los dos USART. He cambiado por fprintf() y me continua fallando :x :x :x Funciona con cualquier velocidad de transmisión?!?!?! o hay que tener algo en cuenta a la hora de seleccionar la velocidad?!?!!?
gracias...
-
ok, ya he conseguido hacer que reciba por el USART por software, el problema estaba en que cambiada directamente PUERTO_PC por PUERTO_RF, y la interrupción del puerto serie, con los pines de del USART por software no se ejecutaba...
voy a probar de utilizar el pin de la INT_EXT como pin de rcv del serie, para ver si puedo detectar la llegada de datos con la interrupción... os cuento
un saludo...
-
funciona!!! he utilizado el pin RB0 de la interrupción externa por flanco de bajada para detectar la llegada de datos por el USART por software.
Ahora tengo funcionando dos USART's y las dos con interrupciones, una la propia del puerto serie y la otra con la interrupción externa.
#include "16F877.h"
...
#INT_EXT
void IntRB0(void)
{
if(kbhit(PUERTO_RF))
{
dato_rx=getc(PUERTO_RF);
anadir_buffer(dato_rx);
}
}
#int_RDA
void RDA_isr(void)
{
if(kbhit(PUERTO_PC))
{
dato_rx=getc(PUERTO_PC);
anadir_buffer(dato_rx);
}
}
main()
...
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
...
}
gracias y un saludo,