TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: japifer_22 en 29 de Marzo de 2018, 17:44:53
-
Hola a todos, tanto tiempo.
Estos días he vuelto a retomar la programación de los pic. especialmente con el PIC16LF18324 y CCS.
Estoy experimentando con este micro con las Uart por software, en este caso implemento dos uart pero estoy teniendo problemas con la transmisión y recepción de datos. ya que he intentado hacer un simple eco de lo que entra por una uart, sacarlo de forma inmediata por la otra uart, pero en esto pierdo caracteres:
Envio por otro micro esta trama: 123456789
while(TRUE)
if(kbhit(UART_SOFT))
{
byte a = getc(UART_SOFT);
putc(a,RS485);
}
if(kbhit(RS485))
{
byte b = getc(RS485);
putc(b,UART_SOFT);
}
y me retorna esto: 13579
ahora al ver este problema genere otro codigo. Lo que hace es, recepcionar una trama X y pasado un timeout reenviarla por la otra uart. pero en esto, de ves en cuando me quita caracteres. Envio: 123456789 y retorna 7 en otra oportunidad 1234567, etc.
El codigo de esta segunda prueba que me da error es:
#include <main.h>
int1 UART_Read_OK = FALSE;
int1 RS485_Read_OK = FALSE;
#int_timer0
void timer0_isr()
{
UART_Read_OK = TRUE;
}
#int_timer2
void timer2_isr()
{
RS485_Read_OK = TRUE;
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16|RTCC_8_BIT); //4,0 ms overflow
//setup_timer_2(T2_DIV_BY_16,15,16); //256 us overflow, 4,0 ms interrupt
////setup_timer_2(T2_DIV_BY_16,255,1); //4,0 ms overflow, 4,0 ms interrupt
setup_timer_2(T2_DIV_BY_16,249,5); //~4ms interrupts
enable_interrupts(GLOBAL);
output_low(RS485_RX_ENABLE_PIN);
//fprintf(UART_SOFT, "RS-232: Transmision por Uart\n\r");
//fprintf(RS485,"RS485: Transmision por RS-485\n\r");
byte BufferRS485[NbytesBufferRS485];
int RS485_Flag = 0x00;
byte BufferUart[NbytesBufferUart];
int Uart_Flag = 0x00;
while (TRUE)
{
///////////////////////////////////////////////////////////////////
if(kbhit(UART_SOFT))
{
BufferUart[Uart_Flag++] = getc(UART_SOFT);
clear_interrupt(int_timer0);
set_timer0(0);
enable_interrupts(int_timer0);
output_high(LED_GREEN);
}
if(UART_Read_OK)
{
UART_Read_OK = FALSE;
disable_interrupts(int_timer0);
for(int a=0; a<Uart_Flag;a++)
putc(BufferUart[a],RS485);
//fprintf(RS485,"%s",BufferUart);
memset(BufferUart, '\0', Uart_Flag);
Uart_Flag = 0x00;
output_low(LED_GREEN);
}
////////////////////////////////////////////////////////////
if(kbhit(RS485))
{
BufferRS485[RS485_Flag++] = getc(RS485);
clear_interrupt(int_timer2);
set_timer2(0);
enable_interrupts(int_timer2);
output_high(LED_RED);
}
if(RS485_Read_OK)
{
RS485_Read_OK = FALSE;
disable_interrupts(int_timer2);
for(int a=0; a<RS485_Flag;a++)
putc(BufferRS485[a],UART_SOFT);
//fprintf(UART_SOFT,"%s",BufferRS485);
memset(BufferRS485, '\0', RS485_Flag);
RS485_Flag = 0x00;
output_low(LED_RED);
}//*/
}
}
tendran alguna respuesta para mi problema en ambos codigos?
Saludos
-
Simple.. 1 usar por hardware posee ese PIC.
Como podes esperar que una UART por software funcione cuando se encuentra encerrado en un getc() es el problema.
La UART por software tiene muchisimas limitaciones, es pedirle al micro que este siempre leyendo a un pin, y si deja de hacerlo por un rato y y se pierde 1 bit de la transmision ya eso significa que el dato esta perdido.
Para que funcione tu codigo, imagino que el baudrate deberia ser muy bajo.
La otra es hacer que se reciba hasta cierto caracter y luego reenviarlo.
Recomendacion,,, si usas la UART por soft, hacelo para enviar nomas. Y para recibir por hardware, que sea por interrupcion.
-
hola Killerjc, si, se que tiene una usart, el problema de esto es que los pines que necesito que estén en la usar son los pines C5 como TX y C4 como RX, tengo entendido que este micro puedes configurar cada pin... pero no se como hacerlo. tu me podras ayudar con esto..
Saludos!!
-
Según la hoja de datos, hay unos registros que se llaman xxxPPS y RxyPPS, que puedes usar para configurar los pines (página 160-162).
Por ejemplo si quieres configurar C5 como TX el registro a modificar es el RC5PPS y escribir en el el 0b10100
Ya que la hoja de datos menciona que 10100 = Rxy source is TX/CK (1)
Y si quieres C4 por RX, tienes el registro RXPSS, en el cual vas a escribir 0b10100
Ya que la hoja de datos menciona que 10100 = Peripheral input is RC4
-
hola tsk, gracias por el tiempo, voy a revisar lo que me dices, implementa y comento los resultados.
Gracias nuevamente por el tiempo a ambos.
Saludos!!