Autor Tema: [RESUELTO]intercambiar puertos de UART con PIC24FJ con PPS  (Leído 2358 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado richardjr

  • PIC12
  • **
  • Mensajes: 69
[RESUELTO]intercambiar puertos de UART con PIC24FJ con PPS
« en: 28 de Diciembre de 2010, 11:01:24 »
Hola a todos, estos ultimos dias he estado renegando con esta caracteristica tan interesante que traen los ultimos pics que han venido saliendo: la PPS. Por medio de esta prestacion, podemos seleccionar por que puerto tendra salida o entrada nuestra uart, spi, entre otros modulos que por lo general vienen con pines fijos. Esto abre una gran flexibilidad en el diseño!.
Ahora bien, estoy teniendo problemas para usar esto. Dejo aqui mi codigo (en CCS):

El encabezado:
Código: [Seleccionar]
#include <24FJ64GA004.h>
#include <stdlib.h>
#include <string.h>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES PR                       //Primary Oscillator
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES I2C1SELD              
#FUSES SOSC_SEC              
#FUSES WUT_DEFAULT          
          
    
#word RPOR0=0x6C0           //registro de configuracion de salida para RP0/1
#word RPOR7=0x6CE           //registro de configuracion de salida para RP14/15
#word RPINR18L = 0x6A4      //registro de configuracion de entrada para U1RXd
#bit    IOLOCK  = 0x742.6

#use delay(clock=20000000)
#pin_select U1TX =PIN_B15
#pin_select U1RX=PIN_B1
#use rs232(UART1,baud=4800,parity=N,bits=8,ERRORS)


Y el cuerpo del codigo: Un bucle infinito de prueba que deberia transmitir en forma alternada entre dos puertos dos mensajes distintos, usando una misma UART

Código: [Seleccionar]
while(1)
{


setup_uart(FALSE);
    
delay_ms(10);

unlockIO();
    
RPOR0 = 0x0000; // "Desconecto" RB0 de TX_UART1
RPOR7 = 0x0300; // UART1 TXD1 ---> RP15 RB15
lockIO();

setup_uart(TRUE);      
      
delay_ms(10);
    
printf ("\n \r Ahora transmito por RB15");

delay_ms(50);
      

setup_uart(FALSE);


unlockIO();
      
      
      RPOR7 = 0x0000; "Desconecto" RB15 de TX_UART1
      RPOR0 = 0x0003; // UART1 TXD1 ---> RP0 RB0
    
lockIO() ;

setup_uart(TRUE);    

delay_ms(10);
      
printf ("\n \r Ahora transmito por RB0");


delay_ms(50);
          
      

}


/********************************
* Function: lockIO
* Preconditions: None.
* Overview: This executes the necessary process to set the IOLOCK bit
* to lock I/O mapping from being modified.
* Input: None.
* Output: None.
********************************/

void lockIO(){


#asm
mov #0x742,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1]
mov.b w3,[w1]
bset 0x742,#6
#endasm
}

/********************************
* Function: unlockIO
* Preconditions: None.
* Overview: This executes the necessary process to clear the IOLOCK
* bit to allow I/O mapping to be modified.
* Input: None.
* Output: None.
********************************/

void unlockIO(){

#asm
mov #0x742,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1]
mov.b w3,[w1]
bclr 0x742,#6
#endasm

}


Mi problema es el siguiente: Por mas que cambie el puerto por el que deberia transmitir UART1, se transmite en los dos puertos a la vez. Dicho de otra forma: Si conecto una virtual terminal en cada puerto de salida, en vez de leer siempre en una terminal:
"
Ahora transmito por RB0
Ahora transmito por RB0
Ahora transmito por RB0
...
"
y en la otra terminal:

"
Ahora transmito por RB15
Ahora transmito por RB15
Ahora transmito por RB15
...
"

lo que veo en ambas terminales es:

"
Ahora transmito por RB0
Ahora transmito por RB15
Ahora transmito por RB0
Ahora transmito por RB0
Ahora transmito por RB15
...
"
Es como si en algun momento se hizo el cambio de puerto pero ademas  la configuracion inicial se mantuvo... Alguien podra darme una mano con esto? Ya he comprobado que los registros de OSCCON y de RPORx se escriben correctamente... tambien he seguido paso a paso los cambios de estado en los bits de configuracion de la uart sin mayor suerte...
Como siempre, cualquier ayuda, sera mas que bienvenida!

Saludos!
« Última modificación: 29 de Diciembre de 2010, 12:55:14 por richardjr »

Desconectado richardjr

  • PIC12
  • **
  • Mensajes: 69
Re: [RESUELTO]intercambiar puertos de UART con PIC24FJ con PPS
« Respuesta #1 en: 29 de Diciembre de 2010, 12:54:37 »
Bueno, despues de renegar un poco, aca dejo puesto un codigo funcional:

Este programa usa una sola UART y escribe en distintos puertos usando la funcion PPS. Esto es solo con propositos de testeo de esta caracteristica y puede sera adaptado para otras funciones.

El problema era que una vez que lo debugue a fondo con el ICD2, encontre que no se estaban escribiendo los datos en  OSCCON, como dice microchip, es una rutina de tiempo critico... probablemente no lo estaba haciendo bien. Despues de todo, este punto no es relevante, ya que por defecto IOLOCK viene puesto a cero, con lo cual tenemos total libertad de cambiar los registros del PPS.

El .h
Código: [Seleccionar]



#include <24FJ64GA102.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
//#FUSES DEBUG                    //Debug mode for use with ICD
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES PR                       //Primary Oscillator
#FUSES NOCKSNOFSM            
#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES WPFP4                
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOWPCFG              
#FUSES NOWPDIS              
#FUSES SOSC_HIGH            
#FUSES WUT_DEFAULT          
#FUSES DSWDT                
#FUSES DSBOR                
#FUSES RTCOSC_SOSC          
#FUSES DSWDTCK_LPRC          
#FUSES WPOSTS1                  //Watch Dog Timer PostScalar 1:1
#FUSES I2C1SELD              
#FUSES WPFP



#word RPOR2=0x6C4           //registro de configuracion de salida para RP4/5
#word RPOR7=0x6CE           //registro de configuracion de salida para RP14/1,5
#word RPINR18L = 0x6A4      //registro de configuracion de entrada para U1RXd
#bit    IOLOCK  = 0x742.6


#use delay(clock=4000000)
#pin_select U1TX =PIN_B4
#pin_select U1RX=PIN_B3
#use rs232(UART1,baud=4800,parity=N,bits=8,ERRORS)

Y el main


Código: [Seleccionar]
void main()
{
    setup_spi( FALSE );
    setup_spi2( FALSE );


    setup_wdt(WDT_OFF);
    setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
    set_tris_b(0x00);

    while (1)
    {

        setup_uart(FALSE);
        delay_ms(10);
      
        RPOR7 = 0x0000;
        RPOR2 = 0x0300; // UART1 TXD1 ---> RP5 RB5
  
      
        setup_uart(TRUE);

        delay_ms(10);

        printf ("\n \r Ahora transmito por RB5");
        
        delay_ms(50);

        setup_uart(FALSE);
        delay_ms(10);
        
      
        RPOR2 = 0x0000;
        RPOR7 = 0x0300; // UART1 TXD1 ---> RP15 RB15

      

        setup_uart(TRUE);
        delay_ms(10);

        printf ("\n \r Ahora transmito por RB15");
        
  
        delay_ms(50);




    }

}

« Última modificación: 29 de Diciembre de 2010, 13:02:11 por richardjr »