PIC32 UART: регистр U1RXREG никогда не содержит никаких значений, кроме 0 - PullRequest
1 голос
/ 05 марта 2020

Я приложил изображение, показывающее показания моего осциллографа, из кода ниже. Контекст: у меня есть Pi и PI C, которые должны общаться через соединение UART. Я реализовал свое собственное управление потоком, которое можно увидеть на прикрепленном изображении [RTS = Желтая трассировка, CTS = Голубая трасса, Rx = Зеленая трассировка]. Код проходит и попадает в окончательный оператор регистра переключателя, который включает светодиод. Но когда я отлаживаю код, никакие значения (ну, единственное значение, которое считывается равным нулю) не считываются. Сначала я подумал, что неправильно настроил мои часы PI C (которые используются для получения скорости передачи в бодах) , но я не думаю, что это так. Во-вторых, я через буфер FIFO был заполнен только нулями, и, учитывая, что я отправляю только четыре пакета информации на PI C, а мой FIFO имеет 4 регистра глубиной, что было причиной того, что эта информация не появлялась. Поэтому я выполнил код, который удаляет фиктивные байты, но это не сработало.

Все, что получено: 0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> < 0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> <0> et c

Я выбрал правильные настройки: скорость передачи данных: 9600 бит данных: 8 четность: нет стоп-битов: 1

Если кто-то захочет потратить некоторое время на просмотр моего кода, вы можете увидеть какие-либо очевидные ошибки?

https://i.stack.imgur.com/aQoAL.jpg

Пример минимальной воспроизводимости

#  include <xc.h>
#  include <math.h>
#  include <stdio.h>
#  include <stdio.h>

//Configuration Bits 
#pragma config FNOSC = FRCPLL    // Internal Fast RC Oscillator (8MHz)
#pragma config FPLLIDIV = DIV_2  // Divide FRC before PLL (Now 4MHz)
#pragma config FPLLMUL = MUL_20  // PLL Multiply (Now 80MHz)
#pragma config FPLLODIV = DIV_2  // Divide After PLL (Now 40MHz)
#pragma config FPBDIV = DIV_1    // Pheripheral Bus Clock (At 40KHz)

#pragma config FWDTEN = OFF      // Watchdog Timer Disabled 
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select 
#pragma config JTAGEN = OFF      // Disable JTAG 
#pragma config FSOSCEN = OFF     // Disable Secondary Oscillator 

//*****************************UART Functions*********************************** 

void UART_Config (void)                 // Baude Rate of 9600, 8-Bit Data , 1 Stop Bit                                           
{   
    U1MODEbits.BRGH = 0;           
    U1BRG = 259;                         //U1BRG = (40M/ (16 * 9.6k))) - 1
    U1MODEbits.SIDL = 0;                 // Continue operation in SLEEP mode
    U1MODEbits.IREN = 0;                 // IrDA is disabled
    U1MODEbits.RTSMD = 0;                // U1RTS pin is in Flow Control mode   
    U1MODEbits.UEN = 0b00;               // U1TX, U1RX are enabled
    U1MODEbits.WAKE = 1;                 // Wake-up enabled
    U1MODEbits.LPBACK = 0;               // Loopback mode is disabled
    U1MODEbits.RXINV = 0;                // U1RX IDLE state is '1'
    U1MODEbits.PDSEL = 0b00;             // 8-bit data, no parity
    U1MODEbits.STSEL = 0;                // 1 stop bit
    U1STAbits.UTXINV = 0;                // U1TX IDLE state is '1'
    U1MODEbits.ON = 1;                   // UART1 is enabled
    U1STAbits.URXEN = 1;                 // UART1 receiver is enabled
    U1STAbits.UTXEN = 1;                 // UART1 transmitter is enabled
}

void Send_UART_Data(unsigned int c)     // PIC Sending Data for Pi to Read 
{
    U1STAbits.UTXEN = 1;                // Make sure transmitter is enabled
    // while(CTS)                       // Optional CTS (Clear to Send) use
    while(U1STAbits.UTXBF);             // Wait while buffer is full
    U1TXREG = c;                        // Transmit character
}

int Read_UART_Data (void)               // PIC Reading Sent Data from Pi 
{
    int c;

    while(!U1STAbits.URXDA)             // Wait for information to be received

    c = (int)U1RXREG;                    // Convert Character to Value
    return c; 
}

ADC_To_UART (unsigned int ADC)
{
    unsigned int temp_A = 0x00;
    unsigned int temp_B = 0x00;
                          // Splitting a 10 Bit Word Into 2 Bytes [aa aaaa aabb]
                          // Start Bit = 1 , Stop Bit = 0 
                          // UART Transmission Pattern [1 aaaa aaaa 0 0000 00 bb]
    temp_A = ADC >> 2;    // MSB(8 Bits) ~ ADC[9:2] [aaaa aaaa]   
    temp_B = ADC & 0x003; // LSB(2 Bits) ~ ADC[1:0] [0000 00bb]

    Send_UART_Data(temp_A);
    Send_UART_Data(temp_B);
}
[enter image description here][1]
//*********************Enumerated Variable Declaration**************************
//Program Flow Control
enum Comm_State {Phase1A, Phase1B, Phase1C, Phase1D, Phase1E, Phase2A, Phase2B, Phase2C, Phase2D, Phase2E, Phase2F, Phase2G};

//******************************************************************************
//********************************MAIN******************************************

int main( )
{   
    //***************************Configuration**********************************
    // I/O Definitions 
    #define UART_TRIS_RX       TRISBbits.TRISB13 // UART RX - Reciever Pin (PPS) 
    #define UART_TRIS_TX       TRISBbits.TRISB15 // UART TX - Transmission Pin (PPS) 
    #define UART_TRIS_CTS_PIC  TRISAbits.TRISA4  // UART CTS_1 - Clear to Send - Output [CTS PIC]
    #define UART_TRIS_RTS_PIC  TRISBbits.TRISB4  // UART RTS_1 - Ready to Send - Output [RTS PIC]
    #define UART_TRIS_CTS_PI   TRISAbits.TRISA3  // UART CTS_2 - Clear to Send - Input  [CTS PI]
    #define UART_TRIS_RTS_PI   TRISAbits.TRISA2  // UART_RTS_2 - Ready to Send - Input  [RTS PI]

    #define SPI_TRIS_SCK       TRISBbits.TRISB14  // SPI SCK - Serial Clock Pin      (PPS?)
    #define SPI_TRIS_SDO       TRISBbits.TRISB6   // SPI SDO - Serial Data Out Pin   (PPS?)
    #define SPI_TRIS_CS_1      TRISBbits.TRISB8   // SPI CS1 - DAC 2 Chip Select Pin (PPS?)
    #define SPI_TRIS_CS_2      TRISBbits.TRISB7   // SPI CS2 - DAC 1 Chip Select Pin (PPS?)

    #define AN4_TRIS           TRISBbits.TRISB2   // Analogue Read 3
    #define AN3_TRIS           TRISBbits.TRISB1   // Analogue Read 2
    #define AN2_TRIS           TRISBbits.TRISB0   // Analogue Read 1
    #define V_REF_TRIS_Plus    TRISAbits.TRISA0   // Analogue V_REF(+) (Forms VRange)
    #define V_REF_TRIS_Minus   TRISAbits.TRISA1   // Analogue V_REF(-) (Forms VRange)

    #define Reg_Enable_TRIS_D  TRISBbits.TRISB9   // Regulator Digital Control (Output) 
    #define Reg_Enable_TRIS_M  TRISBbits.TRISB12  // Regulator Button (Input)

    // Port Input/Output Configuration [TRISB]

    TRISB = 0x1004;           // All of PortB set as Outputs Except for RB12 (Reg Enable) and RB2 (Input -> Analogue Input (Voltage)) (Port B) = (0000 ... 0100)
    TRISA = 0x0003;           // Set up A0 [Pin 2] and A1 [Pin 3] as V_REF(+) and V_REF(-) Respectively (Port B) = (0000 ... 0011) 

    UART_TRIS_RX  = 1;        // UART Receiver ~ Input  
    UART_TRIS_TX  = 0;        // UART Transmission ~ Output 
    UART_TRIS_CTS_PIC = 0;    // UART "CTS_PIC" ~ Output
    UART_TRIS_RTS_PIC = 0;    // UART "RTS_PIC" ~ Output
    UART_TRIS_CTS_PI = 1;     // UART "CTS_PI" ~ Input
    UART_TRIS_RTS_PI = 1;     // UART "RTS_PI" ~ Input 

    SPI_TRIS_SCK  = 0;        // SPI Clock ~ Output
    SPI_TRIS_SDO  = 0;        // SPI Data Output ~ Output 
    SPI_TRIS_CS_1 = 0;        // SPI Chip Select 1 ~ Output 
    SPI_TRIS_CS_2 = 0;        // SPI Chip Select 2 ~ Output 

    AN4_TRIS = 1;             // Analogue Read In ~ Input       
    AN3_TRIS = 1;             // Analogue Read In ~ Input
    AN2_TRIS = 1;             // Analogue Read In ~ Input
    V_REF_TRIS_Plus = 1;      // V_Ref(+) ~ Input  
    V_REF_TRIS_Minus = 1;     // V_Ref(-) Differential Measurements ~ Input

    Reg_Enable_TRIS_D = 0;    // Regulator Digital Control (Output) 
    Reg_Enable_TRIS_M = 1;    // Regulator Switch Control (Input)

    // Peripheral Pin Select Configurations
    U1RXR  = 0x0011;          // UART PPS Mapping 
    RPB15R = 0x0001;          // UART PPS Mapping 

    // Analogue Pin Configurations  
    ANSELB = 0x0028;           // RB0 RB1 RB2 = AN2 AN3 AN4 [0001 1100]  
    ANSELA = 0x0000;           // Set all Analogue Inputs of Port A Off

    //**************Sub-System Configurations*********************************//

    // UART Control Configure 
    UART_Config();                              //UART Control Configure      
    #define PIC_CTS  LATAbits.LATA4             // Output Set  Definition [1]
    #define PIC_RTS  LATBbits.LATB4             // Output Set  Definition [2]
    #define PI_CTS   PORTAbits.RA3              // Input  Read Definition [2]
    #define PI_RTS   PORTAbits.RA2              // Input  Read Definition [1]

    // Analogue Control Configure  
    ADC_Config();                               // Configure ADC 
    AD1CON1SET = 0x8000;                        // Enable ADC

    //***************Variable Declarations************************************//

    enum Comm_State Communication_State = Phase1A;        //Controller Variable 

    unsigned int temp1 = 0;
    unsigned int Comms_Flag_1 = 0;
    unsigned int ConFlag = 1; 
    unsigned int i = 1; 

    unsigned int UART_ADC_CV_1 = 0;
    unsigned int UART_ADC_CV_2 = 0;
    unsigned int ADC_CV = 0;
    unsigned int UART_ADC_CC_1 = 0;
    unsigned int UART_ADC_CC_2 = 0;
    unsigned int ADC_CC = 0;

    unsigned int DAC_CV = 0;

    float I_CC = 0; 
    float V_CV = 0;

    //***************Program Flow - Switch State Controlled*******************//

    while(1)
    {
        switch (Communication_State)
        {
            case Phase1A:  // Check For Pi Ready to Send CV ADC Value

                //PIC_CTS = 0; 
                //Pic_Refresh();
                PIC_RTS = 0; 
                PIC_CTS = 1;

                if (PI_RTS == 1)
                {
                    PIC_CTS = 0;
                    Communication_State = Phase1B;
                }

                break;

            case Phase1B:  // Receive CV ~ 12 Bit ADC Value [Two Data Packets with 0.01 Second Delay]

                ConFlag = 1; 
                i = 1; 

                while (ConFlag == 1)
                {
                    if (PI_RTS == 1 && i == 1)
                    {
                        UART_ADC_CV_1 = Read_UART_Data();   //Data Packet 1 Returned - MSB(Bit 15) to Bit 8
                        i++;
                    }

                    else if (PI_RTS == 1 && i == 2)
                    {
                        UART_ADC_CV_2 = Read_UART_Data();   //Data Packet 2 Returned - Bit (7)) to LSB(Bit 0)
                    }
                    else 
                    {
                        ConFlag = 0;
                    }
                }

                Communication_State = Phase1C;
                break;

            case Phase1C:  // Check for CC Value

                delay();        //Ensure that Pi_RTS has gone low after sending last Transmission (Prevents Code from Running Away)
                PIC_CTS = 1;

                if (PI_RTS == 1)
                {
                    PIC_CTS = 0; 
                    Communication_State = Phase1D;
                }

                break;

            case Phase1D:   // Receive CC Value [Two Data Packets with 0.01 Second Delay]

                ConFlag = 1; 
                i = 1; 

                while (ConFlag == 1)
                {
                    if (PI_RTS == 1 && i == 1)
                    {
                        UART_ADC_CC_1 = Read_UART_Data();   //Data Packet 1 Returned - MSB(Bit 15) to Bit 8
                        i++;
                    }

                    else if (PI_RTS == 1 && i == 2)
                    {
                        UART_ADC_CC_2 = Read_UART_Data();   //Data Packet 2 Returned - Bit (7)) to LSB(Bit 0)
                    }
                    else 
                    {
                        ConFlag = 0;
                    }
                }

                Communication_State = Phase1E;
                break;

            case Phase1E:  // Calculations 

                // CV Calculations 
                temp1 = UART_ADC_CV_1 << 8;
                ADC_CV = temp1 + UART_ADC_CV_2;
                V_CV = ADC_CV * (4.096/4096);
                DAC_CV = ADC_CV | 4096;
                Comms_Flag_1 = SPI_Transfer(DAC_CV ,1);    // Data Transmitted to DAC 1, Upon Transmission LED Turns Green (No Acknowledgement)

                // CC Calculations 
                temp1 = UART_ADC_CC_1 << 8;
                ADC_CC = temp1 + UART_ADC_CC_2;
                I_CC = ADC_CC * (4.096/4096);

                Communication_State = Phase2A;

                break;

            case Phase2A:

                while(1)
                {
                    LATBbits.LATB5 = 1;
                }

                break;

        }

    }

    return 1;
}

1 Ответ

1 голос
/ 05 марта 2020

В Read_UART_Data у вас есть:

while(!U1STAbits.URXDA)
c = (int)U1RXREG;

Я думаю, вы пропустили точку с запятой, потому что это на самом деле:

while (!U1STAbits.URXDA)
    c = (int) U1RXREG;

Это означает, что c установлен только , когда приемник UART не готов.


Я думаю, вы имели в виду:

while (!U1STAbits.URXDA);
c = (int) U1RXREG;
...