TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: lovando en 24 de Enero de 2006, 08:54:00
-
Hola Amigos
Se me ha presentado un problema.
Tengo un 628 con 2 puertos seriales, uno por el USART por harware y otro usando interrupcion externa en RB0 para recepcion y el RB4 como XMIT.
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B4,rcv=PIN_B0,bits=8,stream=PC,errors)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=PC2,errors)
Ambos puertos usan MAX232, correctamente configurados y probados satisfactoriamente.
Sucede que he usado el INTRC_IO como reloj a 4 MHz, y el USART por hardware funciona perfecto, pero el RS232 por software entrega caracteres ilegibles...
Pensando que el MAX232 estaba malo, intercambie ambos puertos en ambos MAX232, y siempre el usart por harware funcion bien, a diferencia del usart por software.....
Despues cambie el pin RB4 por el RB5, RB6 y RB7, siempre con los mismos resultados..
Lo ultimo que hice fue usar el RB4 como xmit pero esta vez usando
#fuses XT
Con esto ambos puertos funciona a la perfeccion....
#include <16F628.h>
//#fuses INTRC_IO
#fuses XT
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOPROTECT
#fuses MCLR
#fuses NOLVP
#fuses NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B4,rcv=PIN_B0,bits=8,stream=PC,errors)
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,stream=r520m,errors)
//
// baud=38400 maximo usando 4 Mhz
//
////////////////////////////////////////////////////////////////////////////////
Alguien me podría orientar sobre esta situacion, o tiene alguna idea de lo que está pasando...
Muchas gracias
-
Tal ves el problema sea que no puedes tener 2 usart simultaneamente activas, sea tanto por hardware como sofware.
Cuando utilizas las directivas asi la ultima transmite y recibe, en el manual de CCS dice: " This directive take effect until another RS232 directive is encountered". Lo mismo que me parece es tu problema
#use rs232(baud=9600..............)
{
programa utiliza el usart1
}
#users232(baud=9600...............)
{
Programa utiliza usart2
}
Prueba asi utilizando la directiva previo a utilizar la otra usart.
Saludos
-
Gracias amigo kruskal por tu sugerencia.
Habia pensado en eso, pero simulado en proteus mi programa funciona a la perfeccion. LO raro es que con INTRC_IO no funciona, pero usando un cristal ambos puertos operan normal.
Ademas, los puertos son usados de la sgte manera:
fprintf(PC2,"Probando PC2
"
;
fprintf(PC,"Probando PC
"
;
Usando el stream se llama automaticamente la configuracion deseada
Gracias
-
Mi inicio en este foro fue exactamente con el mismo tema: Un 16F628 que no comunicaba usando el Oscilador Interno.
Me aconsejaron usar un cristal y fue mano de santo, todo iba a la perfección.
Parece ser que el oscilador interno funciona bien siempre y cuando no se le pida precisión, que es realmente lo que le hace falta a las comunicaciones.
Leyendo sobre la UART en el datasheet del 628 comprobé que según el BPRG usado y el BAUDRATE seleccionado había una tasa de error en la velocidad de transmisión/recepción que había que tener en cuenta a la hora de comprobar la estabilidad de la comunicación, si a este error le sumamos el propio del oscilador interno puede ser, y estoy convencido de ello, de que la comunicación esté siempre al borde de abismo del error. De ahí que recibas algo pero no sea inteligible.
Es normal que la UART obtenga mejores resultados que la comunicación realizada por software, ya que tiene todo un hardware específico dedicado en exclusiva a ese asunto en concreo, mientras que el simulado por soft aumenta, aún mas si cabe, el error acumulando a los propios los debidos a que no tomamos en cuenta, por ejemplo, lo que tardan las distintas instrucciones en ejecutarse ... etc.
Conclusión: A mi 16F628 le puse un cristal de 4Mhz y un par de condensadores y empezó a hablar con el PC hasta por los codos. 
-
El registro OSCTUNE (dirección 0x90) se usa para calibrar la frecuencia exacta del oscilador interno,si quieres que la frecuencia esté centrada en el valor que has seleccionado mediante el registro OSCCON (0x8F),se debe volcar sobre OSCTUNE el valor 0x00.Supongo que ya habrás configurado el oscilador interno mediante el manejo directo de estos registros o usando la función setup_oscillator().Si no es así,creo que deberías hacerlo porque si no me equivoco,no es suficiente con el #use delay(clock=4000000)
-
Escrito originalmente por Modulay
El registro OSCTUNE (dirección 0x90) se usa para calibrar la frecuencia exacta del oscilador interno,si quieres que la frecuencia esté centrada en el valor que has seleccionado mediante el registro OSCCON (0x8F),se debe volcar sobre OSCTUNE el valor 0x00.Supongo que ya habrás configurado el oscilador interno mediante el manejo directo de estos registros o usando la función setup_oscillator().Si no es así,creo que deberías hacerlo porque si no me equivoco,no es suficiente con el #use delay(clock=4000000)
No he podido dar con esto..tienes algun ejemplo por ahi?
Gracias
-
Para fijar la frecuencia del oscilador interno a 4 MHz,primero define las etiquetas de los registros:
#byte OSCCON = 0x8F
#byte OSCTUNE = 0x90
...y después,les vuelcas los valores que te interesan:
OSCCON = 0x60; // Para fijar el oscilador a 4 MHz
OSCTUNE = 0; // Para calibrar la frecuencia a 4MHz "exactos"
También se puede hacer,dependiendo de la versión del compilador,con la siguiente función:
setup_oscillator(OSC_INTRC | OSC_4MHZ | OSC_STATE_STABLE);
Suerte
-
Como va lovando.
Conseguiste solucionarlo?
-
Hola
Gracias por tu preocupación.
Lo cierto es que aún no lo probado..estoy un poco atareado con el diseño de un codigo para leer una trama que recibo de un modem por int_rda, aunque la almaceno en un buffer correctamente, aún no la tengo muy depurada, asi que estoy usando por ahora el cristal para tener los 2 uart operando normalmente...espero estos dias meterle mano al codigo que me has posteado.-
Apenas tenga algo lo contaré
Gracias
-
Hola
Hasta el momento probe con la funcion setup_oscillator(OSC_4MHZ), pero el compilador no soportra esa instruccion para el 16F628, no obstante, para el 16F628A y el 648A si...
esto es lo que tengo, aun sin probar, cuando llegue a casa lo probaré..
#include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOPROTECT,NOMCLR,NOLVP,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B0, STREAM=COM_PC) //RS232 por software.
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, STREAM=modem ) //modem usando el UART
void main() {
setup_oscillator( OSC_4MHZ );
//....codigo
}
Esto es asi, puesto que 16F628A.h trae
////////////////////////////////////////////////////////////////// INTERNAL RC
// Constants used in setup_oscillator() are:
#define OSC_48KHZ 0
#define OSC_4MHZ 8
en cambio el 16F628.h no dice nada al respecto...
Esto es compilado por CCS 3.242....
Modulay, la opciona manual que haz detallado tambien compila, pero pasa esto:
....................
.................... #byte OSCCON = 0x8F
.................... #byte OSCTUNE = 0x90
....................
....................
y mas abajo dice
....................
.................... OSCCON = 0x60; // Para fijar el oscilador a 4 MHz
*
00D6: MOVLW 60
00D7: BSF 03.5
00D8: MOVWF 0F
.................... OSCTUNE = 0; // Para calibrar la frecuencia a 4MHz "exactos"
00D9: CLRF 10
....................
....................
Segun lo anterior, el valor 0x60 es pasado al registro 0x0F ==>TMR1H...siendo que debiera pasarlo a la direccion 0x8F ==>OSCCAL
La direccion 0x90 no parece estar implementada en el chip...asi que OSCTUNE es limpiada usano CLRF 10.....
Puede ser un bug del compilador....porque no esta la instruccion para pasar al banco 1, donde esta el OSCCAL
Espero vuestros comentarios
___________________________________________-
Editado:
------------------------------------------------------
Revisando me di cuenta que efectivamente los registros definidos son los que
estan siendo utlizados por el compilador, puesto que accediendo al banco1 puedo llegar al registro haciendo 0x8F o 0x0F, da lo mismo....
-------------------------------------------------------------
Note: OSCCAL is used to remove process variation from the internal RC oscillator of the
device. The OSCCAL value should not be modified from the Microchip supplied
value, and all timing critical functions should be adjusted by the application software.
Asi, segun el manual de referencia de la familia de PICs de medio rango (33023a.pdf), OSSCAL debiera tener un valor de 0x70, y no 0x60 como sugieres....con los bits de offset en 0...
Sobre el OSCTUNE no he encontrado nada....
Espero tus comentarios
-
Con tanta cosa terminé hechandome el 16F628...ahora está en el basurero...
Bueno, finalmente, con un 648A, 628A, he tenido buenos resultados usando el INTRC_IO...solo fue necesario hacer
#include <16F648A.h>
#fuses INTRC_IO
#use delay(4000000)
#use rs232(baud=9600, xmit=PIN_B5, rcv=PIN_B0, STREAM=pc) //RS232 por software.
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, STREAM=modem) //usando USART
Con esto, el rs232 por software funciona de maravillas....
Asi que no puedo decir que sucede con un 628 si se usa el INTRC_IO....
Tambien funciona haciendo un:
setup_oscillator(OSC_4MHZ);
aunque esta ultima sentencia solo funciona en algunos chips, hay que verificarlo revisando el device.h
De todas maneras muchas gracias por la colaboración...
Saludos
-
Mirando la data del 628 me doy cuenta de que los datos que te di son válidos para el 16F88 que es con el que yo he usado este recurso,pero no para el 628.
Ambos tienen oscilador interno,pero el del 16f628 es de una frecuencia fija de 4 MHz,mientras que la frecuencia del oscilador del 16F88 es configurable mediante los registros de los que hemos hablado.Con esto,el mapa de memoria del uno es diferente al del otro,quizá por eso el compilador te hacía cosas raras,ya que las direcciones 0x8F y 0x90 no están implementadas en el mapa del 628