LusoRobótica - Robótica em Português

Software => C/C++ => Tópico iniciado por: senso em 18 de Agosto de 2013, 17:35

Título: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 17:35
Boas tardes, visto que eu e PIC's nunca corre bem quanto tento brincar com eles, ando já á uns quantos dias a tentar meter a UART de um PIC24FJ64GA002 a funcionar, mas após seguir este tutorial, ler muitos posts no forum da Microchip, ler as datasheets um monte de vezes, o chip para a execução.
Para saber que ele deixa de correr o código, estou a fazer toogle a um pino, assim que meto lá o UartPut o pino fica high e de lá nunca mais desce.
O código é este:

Código: [Seleccione]
/*
 * File:   main.c
 * Author: tiago
 *
 * Created on 31 de Julho de 2013, 2:52
 */

#include <stdio.h>
#include <stdlib.h>
#include <p24FJ64GA002.h>
#include <xc.h>

// CONFIG2
#pragma config POSCMOD = HS             // Primary Oscillator Select (HS Oscillator mode selected)
#pragma config I2C1SEL = PRI            // I2C1 Pin Location Select (Use default SCL1/SDA1 pins)
#pragma config IOL1WAY = ON             // IOLOCK Protection (Once IOLOCK is set, cannot be changed)
#pragma config OSCIOFNC = OFF            // Primary Oscillator Output Function (OSC2/CLKO/RC15 functions as port I/O (RC15))
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor (Clock switching and Fail-Safe Clock Monitor are disabled)
#pragma config FNOSC = PRI           // Oscillator Select (Primary Oscillator with PLL module (HSPLL, ECPLL))
#pragma config SOSCSEL = SOSC           // Sec Oscillator Select (Default Secondary Oscillator (SOSC))
#pragma config WUTSEL = LEG             // Wake-up timer Select (Legacy Wake-up Timer)
#pragma config IESO = ON                // Internal External Switch Over Mode (IESO mode (Two-Speed Start-up) enabled)

// CONFIG1
#pragma config WDTPS = PS32768          // Watchdog Timer Postscaler (1:32,768)
#pragma config FWPSA = PR128            // WDT Prescaler (Prescaler ratio of 1:128)
#pragma config WINDIS = ON              // Watchdog Timer Window (Standard Watchdog Timer enabled,(Windowed-mode is disabled))
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog Timer is disabled)
#pragma config ICS = PGx1               // Comm Channel Select (Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1)
#pragma config GWRP = OFF               // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF                // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = ON              // JTAG Port Enable (JTAG port is enabled)

void init(void);
void UART1PutChar(char Ch);
char UART1GetChar(void);

int main(int argc, char** argv) {

    init();

    while(1){
        PORTBbits.RB15 = 0;  //Toogle RB15
        PORTBbits.RB15 = 1;
        UART1PutChar('U');
    }

    return (EXIT_SUCCESS);
}

void init(void){

    AD1PCFG = 0xFFFF;

     /* OSCCONbits.COSC = 0b010;
    OSCCONbits.NOSC = 0b010;
    CLKDIVbits.DOZE = 0b001;    //Clock is 16Mhz * 4 / 2
    CLKDIVbits.DOZEN = 0;       //Enable DOZE divider*/

    RPINR18bits.U1RXR = 2;     //Uart RX set to pin RB2
    RPOR1bits.RP2R  = 3;       //UART1 transmit set to RB3
    U1BRG = 25;                 //Baud rate set for 38400
    //U1STA = 0x8400; //set interrupts
    U1STAbits.URXISEL0 = 0;
    U1STAbits.URXISEL1 = 1;
    U1MODEbits.RTSMD = 1;   //UART in simplex mode
    U1STAbits.UTXEN = 1; //Enable uart control of the pins, really?? how many enables does this crap need?
    U1MODEbits.UARTEN = 1;      //Enable the UART module
    //reset RX interrupt flag
    IFS0bits.U1RXIF = 0;

    TRISBbits.TRISB15 = 0;  //Set RB15 as output
    TRISBbits.TRISB3 = 0;   //Set RB3 as output
    TRISBbits.TRISB2 = 1;   //Set RB2 as input
}

//UART transmit function, parameter Ch is the character to send
void UART1PutChar(char Ch){
   //transmit ONLY if TX buffer is empty
   while(U1STAbits.UTXBF == 1);
   U1TXREG = Ch;
}

//UART receive function, returns the value received.
char UART1GetChar(void){
   char Temp;
   //wait for buffer to fill up, wait for interrupt
   while(IFS0bits.U1RXIF == 0);
   Temp = U1RXREG;
   //reset interrupt
   IFS0bits.U1RXIF = 0;
   //return my received byte
   return Temp;
}

Alguma ideia de como meter isto a funcionar?
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Njay em 18 de Agosto de 2013, 18:40
Fósnix, antes um MSP430... Parece que vais ter que mudar a tua assinatura, agora que já tocaste num PIC, there's no way back, já tás conspurcado, lol

Quanto ao teu problema não faço ideia... não há nenhum exemplo já feito a ver se funciona e para comparar?
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 18:53
É que eu comprei um pickit3 já á coisa de 2 anos e custa-me ter um pisa-papeis de 50€ lol, e pedi uns samples, já tive o IDE da Microchip instalado meia duzia de vezes, peguei nisto porque vou forçosamente usar PIC's na universidade, mas sempre que pego nisto ou acabo por dar com um bug estupido no compilador, bug no IDE, ou estas coisas de o chip nunca falar comigo, estou quase a desinstalar novamente esta treta toda e enfiar tudo no lixo..
Tenho cá uns MSP430 tenho, e cada vez mais acredito que é avr's para o low cost, e stm32f4 para a brutidade e não há cá andar com estes chips manhosos de 16 bits..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Hugu em 18 de Agosto de 2013, 19:58
tb podias ter feito a troca que se tinha mandado prá fabrica trocar! tb foi burrice tua deixares e aceitares o pickit assim co o recebeste!..  ???

Posso tentar fazer a devoluçao e pedir a troca do programador...acho que foi à mouser que o comprei.. se tiveres a caixa ou o plastico ainda com os codigos deles acho que devem-no trocar na boa.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 20:21
Já o troquei á muito tempo, está a funcionar perfeiramente, lê lá o tópico todo e volta a pensar na resposta.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: jm_araujo em 18 de Agosto de 2013, 20:36
Nunca programei essas PICs, mas achei estranho: não tens de definir o tristate dos portos antes de dar o enable à UART?
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 20:43
Isto?
TRISBbits.TRISB15 = 0;  //Set RB15 as output
TRISBbits.TRISB3 = 0;   //Set RB3 as output
TRISBbits.TRISB2 = 1;   //Set RB2 as input

Como é tipico nem nos foruns da microchip arranjo solução, coisas esquesitas que só me acontecem quando pego em PIC's lol.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: jm_araujo em 18 de Agosto de 2013, 20:48
Sim, isso. :)
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 20:55
Já está lá na parte do init..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: jm_araujo em 18 de Agosto de 2013, 21:02
Eu vi que estão no init(), mas está DEPOIS de atribuires os portos à UART e dares o respectivo enable. ;)


Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 21:06
Mas não faço nada com a uart antes disso?
Se fizer diferença a ordem do TRIS deixo mesmo de usar pic's, isso é simplesmente estupido..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: gadelhas em 18 de Agosto de 2013, 21:40
Ecomo é que sabes que nunca desce? Estás a ver com um osciloscopio?
Pergunto isto porque se não tiveres uns delays entre o High e o Low desse pino, visualmente não vais saber se ele desliga ou não!

    while(1){
        PORTBbits.RB15 = 0;  //Toogle RB15
        PORTBbits.RB15 = 1;
        UART1PutChar('U');
    }


Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 18 de Agosto de 2013, 21:50
Osciloscópio sim, sem o Putchar faz uma onda quadrada, com ele, passa de low para high e ai fica até lhe mandar um reset.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Sérgio_Sena em 18 de Agosto de 2013, 21:56
Ve la se o anexo te ajuda.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: gadelhas em 18 de Agosto de 2013, 22:04
Não tenho aqui nenhum PIC24, só PIC32, mas experimenta isto

UART1PutChar(1);
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: jm_araujo em 19 de Agosto de 2013, 11:13
Outra ideia:
De certeza que fica bloqueado em high? Confirma se não tens dados na saída da UART (RB3).
O código como está vai encher o buffer de saída logo no inicio, e depois bloqueia na função UART1PutChar :
Código: [Seleccione]
while(U1STAbits.UTXBF == 1);à espera que o buffer tenha vaga. Os pulsos na saída só vão acontecer uma vez cada carater enviado, o que dá um período de uns 260us (10bits/38400bps=260us), muito longo em relação ao tamanho do pulso.
Para teres pulsos com duty de 50%, muda o ciclo principal para:
Código: [Seleccione]
    while(1){
        PORTBbits.RB15 = 0;  //Toogle RB15
        UART1PutChar('U');   //LINHA ADICIONADA PARA DUTY CYCLE DE 50%
        PORTBbits.RB15 = 1;
        UART1PutChar('U');
    }
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 19 de Agosto de 2013, 13:33
Sim, fica para sempre a High, o osciloscópio não mente, e não tenho nada no TX, nada de nada.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: beirao em 19 de Agosto de 2013, 14:31
Não tens de definir os bits UEN1:UEN0 do registo U1MODE ? em princípio não é preciso, mas..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 20 de Agosto de 2013, 03:53
Posso declarar explicitamente como 00, porque o que quero é isto no UEN:
00 = UxTX and UxRX pins are enabled and used; UxCTS, UxRTS and BCLKx pins are controlled by
port latches

Amanhã já me vou debruçar mais um bocadinho, se continuar teimoso é STM32 for the win e esqueço de vez esta coisa..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 22 de Agosto de 2013, 00:22
Boas


Estive a ver o teu código e a configuração parece-me bem. Penso que o teu problema estará no putChar que  fica em ciclo infinito no while e nunca chega a escrever o carater na UART. A minha função de escrita na UART é esta, experimenta algo parecido só tens que mudar a condição do while.

Código: [Seleccione]
void printU1(char * str) {
    unsigned int i;

    i = 0;
    while (str[i] != '\0') {
        IFS0bits.U1TXIF = 0;
        U1TXREG = str[i];
        i++;
        while (IFS0bits.U1TXIF == 0);
    }
}

Experimenta, se não der assim eu arranjo-te a parte de inicialização e também e aí tem que dar :-)
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 23 de Agosto de 2013, 02:38
Mas supostamente tens de fazer a verificação para saber se o buffer de transmissão está ou não cheio, assim arriscaste a ter um buffer over-run, ou não?
Podes postar a parte da inicialização se não te importares?
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 23 de Agosto de 2013, 10:01
Na verdade não, cada vez que carregas um caracter no buffer, esperas que seja enviado. Essa flag indica precisamente isso. Eu uso exactamente o que está aí para enviar strings e funciona bem. De qualquer forma, o teu código devia funcionar também, há algo que está a escapar.

Código: [Seleccione]
//UART1 configuration

    // Assign U1RX To Pin RP1
    RPINR18bits.U1RXR = 1;
    // Assign U1TX To Pin RP0
    RPOR0bits.RP0R = 3;

    U1BRG = 100; //38400
    U1MODE = 0;
    U1STA = 0;
    U1MODEbits.UEN1 = 0; // no flow control
    U1MODEbits.UEN0 = 0;
    U1MODEbits.BRGH = 1;

    U1MODEbits.UARTEN = 1;
    U1STAbits.UTXEN = 1;
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 01 de Setembro de 2013, 20:45
Pic arrumado, continua a não dar sinal de vida, se retirar o tal while não transmite nada lol, vou assumir que os 3 pic24 que aqui tenho por algum alinhamento cósmico estão estragados(apesar de nunca usados) e esquecer isto, demasiado tempo perdido meh..
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Sérgio_Sena em 01 de Setembro de 2013, 20:56
Pic arrumado, continua a não dar sinal de vida, se retirar o tal while não transmite nada lol, vou assumir que os 3 pic24 que aqui tenho por algum alinhamento cósmico estão estragados(apesar de nunca usados) e esquecer isto, demasiado tempo perdido meh..

Camarada, viste o codigo q te mandei ?

Eh precoce desistir de um problema tao simples. Trabalhar na industria nao pertmite isso, especialmente qd obrigatoriamente tens q trablahar com micro X ou Y ou Z.

Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 01 de Setembro de 2013, 21:07
Pic arrumado, continua a não dar sinal de vida, se retirar o tal while não transmite nada lol, vou assumir que os 3 pic24 que aqui tenho por algum alinhamento cósmico estão estragados(apesar de nunca usados) e esquecer isto, demasiado tempo perdido meh..

Mandei-te o código exactamente como tenho a funcionar. Já viste a configuração do pinos? Penso que por defeito alguns pinos estão em modo analógico, poderá ser isso.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 01 de Setembro de 2013, 21:12
É deste registo que falo, experimenta.


Código: [Seleccione]
//PORTS configuration
    AD1PCFG = 0b1110111111001100;
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 01 de Setembro de 2013, 22:12
Sim Asena, vi o código, tentei MUITAS coisas.
Eu sei que ambiente de trabalho posso ser obrigado a usar X ou Y, a questão é que já usei PIC32 e um PIC18F qualquer coisa e funcionaram perfeitamente bem, foi ler datasheet e usar, como estes não funcionam e já cá andam em casa á uns 2 anos, foi tudo para o lixo.
Nunca tive nenhum problema em saltar para outro micro, agora estes fazem-me perder tempo demais para meter uma simples uart a funcionar.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: senso em 01 de Setembro de 2013, 22:15
É deste registo que falo, experimenta.


Código: [Seleccione]
//PORTS configuration
    AD1PCFG = 0b1110111111001100;

Estava assim:
AD1PCFG = 0xFFFF;
Logo disso não devia ser o problema, até porque podia fazer toogle/high/low a qualquer pino no porto da uart e funcionava, logo estavam a funcionar em modo digital.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 01 de Setembro de 2013, 22:52
É estranho porque não tive qualquer problema em por a UART a rolar. Quando tiver um pouco de tempo mando-te um projecto a funcionar e é so programaro PIC, assim tem que funcionar.
Título: Re: PIC24FJ64GA002 UART não quer falar comigo
Enviado por: Samy74 em 02 de Setembro de 2013, 14:44
Aqui fica o prometido, os pinos TX e RX estão no mesmos da programação, assim pode-se usar o mesmo pente para programar e para debug. Copy paste e tem que funcionar

Código: [Seleccione]
/*************************************************
 * File:   main.c
 * Author: Samuel Matos
 *************************************************/

#include <p24FJ64GA002.h>

#define F_CPU 16000 // FOSC/2 (kHz)

#define T1_PRE 8
#define T1_INT 5 //ms
#define KT1 (unsigned int) (F_CPU/T1_PRE)*T1_INT

_CONFIG1(
        JTAGEN_OFF /*Jtag OFF*/
        & GCP_ON /*Code protect on*/
        & GWRP_OFF /*Write protect off*/
        & BKBUG_OFF /*Backgroud debug off*/
        & COE_OFF /*Chip on emulation off*/
        & ICS_PGx1 /*EMUC/EMUD share PGC1/PGD1*/
        & FWDTEN_OFF) /*Watchdog timer disabled*/
/*& WINDIS_OFF Windowed WDT disabled*/


_CONFIG2(IESO_OFF & FNOSC_FRCPLL & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_SEC & POSCMOD_NONE)


typedef enum {
    bFALSE,
    bTRUE
} boolean;

void printU1(char * str);
void initPic(void);


boolean timeTick5ms;

int main(void) {

    unsigned char aux = 0;

    initPic();

    while (1) {

        if (timeTick5ms == bTRUE) {
            timeTick5ms = bFALSE;
            aux++;
        }



        if (aux == 200) {
            aux = 0;

            printU1("Teste\r\n");

        }
    }

}

void printU1(char * str) {
    unsigned char i;

    i = 0;
    while (str[i] != '\0') {
        IFS0bits.U1TXIF = 0;
        U1TXREG = str[i];
        i++;
        while (IFS0bits.U1TXIF == 0);
    }
}

void initPic(void) {

    // Clock

    CLKDIVbits.RCDIV = 0; // 8MHz

    //PORTS configuration
    AD1PCFG = 0b1110111111001100;

    TRISA = 0b00011;
    TRISB = 0b0001001100001111;

    //UART1 configuration

    // Assign U1RX To Pin RP1
    RPINR18bits.U1RXR = 1;
    // Assign U1TX To Pin RP0
    RPOR0bits.RP0R = 3;

    U1BRG = 100; //38400
    U1MODE = 0;
    U1STA = 0;
    U1MODEbits.UEN1 = 0; // no flow control
    U1MODEbits.UEN0 = 0;
    U1MODEbits.BRGH = 1;

    U1MODEbits.UARTEN = 1;
    U1STAbits.UTXEN = 1;


    //Timer1
    T1CONbits.TSIDL = 1;
    T1CONbits.TCKPS1 = 0;
    T1CONbits.TCKPS0 = 1; //Prescaler 1/8
    // T1CONbits.T32 = 0;
    T1CONbits.TCS = 0;
    T1CONbits.TON = 1;

    PR1 = KT1;



    // Interrupts
    IFS0bits.U1RXIF = 0; // UART1
    IEC0bits.U1RXIE = 1;

    IFS0bits.T1IF = 0;
    IEC0bits.T1IE = 1; // Timer 1 interrupt

}

void __attribute__((__interrupt__, auto_psv)) _T1Interrupt(void) {

    PR1 = KT1;
    IFS0bits.T1IF = 0;
    timeTick5ms = bTRUE;
}

void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {

    IFS0bits.U1RXIF = 0;

    if (U1STAbits.OERR == 1) {
        U1STAbits.OERR = 0;
    } else {
        U1TXREG = U1RXREG; //mirror
    }
}



(https://dl.dropboxusercontent.com/u/5042323/Teste.jpg)