PIC32MX795F512H UART связь с RS232

В настоящее время я впервые работаю с микроконтроллером PIC. В коде я указал, какой именно PIC, компилятор и т. Д. Я использую. Может быть, это поможет.

Я пытаюсь настроить связь UART на PIC32 и отправить шестнадцатеричный код, например, 0x41, например, на терминал на моем компьютере через RS232. Для преобразования сигнала из PIC UART в уровни RS232 я использую MAX232EPE.

В настоящий момент я сталкиваюсь с проблемой, что когда я посылаю 0x41, например, из PIC32 в терминал или наоборот, полученные данные не совпадают. Я думаю, что это вызвано ошибкой в ​​моих настройках скорости передачи, но я не уверен. Может ли кто-нибудь просмотреть мой код и посмотреть, может ли кто-нибудь увидеть проблему? Я забыл определить что-то? Я что-то не так определил? Я неправильно рассчитал скорость передачи данных?

PS Я знаю, что получаемые данные не соответствуют отправке данных, потому что я проверил в "вахтах" в режиме отладки в mplab, и когда я передаю данные, отправленные с терминала на PIC32 обратно на терминал, он тоже не совпадает,

Код задержки и прерывания можно игнорировать, они работают должным образом, поэтому я действительно считаю, что проблема связана с начальной настройкой PIC/buad rate.

Я надеюсь, что это достаточно ясно, любая помощь очень ценится

Спасибо,

Смотрите код ниже

/*
The configuration below and in void UART1_Init should set up the UART correctly.
I want to achieve a buadrate of 9600. My external Crystal is 8MHz. So:
FPLLIDIV=2, FPLLMUL=20, FPLLODIV=1, FPBDIV=2, FNOSC=PRIPLL, BRGH = 0, and U1BRG = 259.
This should give me the desired baudrate of 9600.
- ((8MHz / 2) * 20)/2) = 40MHz PBclk.
- U1BRG = (PBclk/(16*Buad rate))-1 so 259
- 16*Buad rate because BRGH = 0

PIC32MX795F512H
MPLAB X IDE V3.26
XC32 Compiler
PICKit3
*/

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

// Give useful names to pins
#define LED1_TRIS   TRISDbits.TRISD6
#define LED1        LATDbits.LATD6
#define UART1TX_TRIS    TRISDbits.TRISD3
#define UART1RX_TRIS    TRISDbits.TRISD2

#define FOSC 8000000                // Crystal frequency = 8 MHz
#define SYS_FREQ (80000000UL)       // SYSCLK is 80 MHz
#define GetSystemClock()       (FOSC) // For delay

#pragma config FPLLIDIV=DIV_2       // PLL Input Divider Value (Divide by 2)
#pragma config FPLLMUL=MUL_20       // Phase-Locked Loop (PPL) muiltiplier, multiplier of 20
#pragma config FPLLODIV=DIV_1       // Postscaler for PLL, output divided by 1
#pragma config FPBDIV=DIV_2         // 2 = PBCLK is SYSCLK divided by 2 (80MHz/2 = 40MHz)
#pragma config FWDTEN=OFF           // Watch Dog Timer (WDT) is not enabled. It can be enabled by software
#pragma config CP=OFF               // Code-Protect, 1 = OFF/Disabled
#pragma config BWP=OFF              // Boot Flash Write-protect, 1 = OFF/Disabled
#pragma config POSCMOD=XT           // Primary oscillator configuration, HS = HS Oscillator mode selection
#pragma config FNOSC=PRIPLL         // Oscillator selection, PRIPLL = Primary Oscillator with PLL module
#pragma config OSCIOFNC=OFF         // CLKO output disabled
#pragma config FSOSCEN=OFF          // Disable secondary Oscillator

int UART_RX_Count;                  // Counter variable for the UART1 receiver interrupt
int UART_TX_Count;                  // Counter varible for the UART1 transmitted interrupt  
unsigned char RD_SER_NUM;           // Variable to store command to read serial number
unsigned char UART_RX_OUTPUT;       // Variable to store the UART output
unsigned char i;

void UART1_Init(void){
// UART1 initialization
    U1MODEbits.ON = 1;          // UART1 is enabled
    U1MODEbits.SIDL = 0;        // Continue operation in idle mode
    U1MODEbits.IREN = 0;        // Disable IrDA (IrDA Encoder and Decoder Enable bit)
    U1MODEbits.RTSMD = 1;       // !U1RTS! pin is in Simplex mode, 0 = !U1RTS! pin is in Flow Control mode
    U1MODEbits.UEN = 0;         // UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/UxBCLK pins are controlled by corresponding bits in the PORTx register
    U1MODEbits.WAKE = 1;        // Enable Wake-up on Start bit Detect During Sleep Mode bit
    U1MODEbits.LPBACK = 0;      // UARTx Loopback Mode Select bit, 0 = disabled, loopback = UxTX output is internally connected to the UxRX input
    U1MODEbits.PDSEL = 2;       // Parity and Data Selection bits, 10 = 8-bit data, odd parity
    U1MODEbits.STSEL = 0;       // Stop Selection bit, 0 = 1 stop bit
    U1MODEbits.BRGH = 0;        // High Baud Rate Enable bit, 0 = Standard Speed mode 16x baud clock enabled
    U1MODEbits.RXINV = 1;       // Receive Polarity Inversion bit, 1 = UxRX Idle state is 0

    U1STAbits.URXEN = 1;        // 1 = UART1 receiver is enabled. U1RX pin is controlled by UARTx (if ON = 1)
    U1STAbits.UTXEN = 1;        // 1 = UART1 transmitter is enabled. U1TX pin is controlled by UARTx (if ON = 1)
    U1STAbits.UTXINV = 1;       // Transmit Polarity Inversion bit, 1 = UxTX Idle state is 0
    U1STAbits.ADM_EN = 0;       // 0 = Automatic Address Detect mode is disabled
    U1BRG = 259;                // Baud Rate Divisor bits (0-15 bits), set baud rate, 9600 @ 40 MHz PBclk

    __builtin_disable_interrupts();     // Tell CPU to stop paying attention to interrupts
    INTCONbits.MVEC = 1;                // Multi Vector interrupts
    U1STAbits.URXISEL = 0;              // 0x = Interrupt flag bit is set when a character is received
    U1STAbits.UTXISEL = 1;              // 01 = Interrupt flag bit is set when all characters have been transmitted
    IPC6bits.U1IP = 5;                  // Set UART1 priority 5 of 7
    IPC6bits.U1IS = 0;                  // Set UART1 sub priority to 0
    IFS0bits.U1RXIF = 0;                // Clear UART1 RX interrupt flag
    IFS0bits.U1TXIF = 0;                // Clear UART1 TX interrupt flag
    IEC0bits.U1RXIE = 1;                // Enable UART1 RX ISR
    __builtin_enable_interrupts();      // Tell CPU to start paying attention to interrupts again

    UART_RX_Count = 0;                  // Set initial UART1 received interrupts count to 0
    UART_TX_Count = 0;                  // Set initial UART1 transmit interrupts count to 0
}

void __ISR(_UART_1_VECTOR, IPL5SRS) UART1_INT(void){
    if(INTGetFlag(INT_U1RX)){           // Check if UART1 RX interrupt was triggered
        LED1 = ~LED1;                   // Toggle LED1
        UART_RX_Count++;                // Add 1 to UART1 RX interrupt occurrence counter
//        UART_RX_OUTPUT = U1RXREG;       // Read UART1 RX buffer/register
        U1TXREG = U1RXREG;      // Transmit the received data back
//        U1STAbits.OERR = 0;             // Clear UART1 buffer overflow
        IFS0bits.U1RXIF = 0;            // Clear UART1 RX interrupt flag
    }else{
        if(INTGetFlag(INT_U1TX)){       // Check if UART1 TX interrupt was triggered
            UART_TX_Count++;            // Add 1 to UART1 TX interrupt occurrence counter
            IEC0bits.U1TXIE = 0;        // Disable UART1 TX ISR
            IFS0bits.U1TXIF = 0;        // Clear UART1 TX interrupt flag
        }
}
}

  // DelayMs creates a delay of given milliseconds using the Core Timer
  void DelayMs(WORD delay){
     unsigned int int_status;
     while( delay-- ){
         int_status = INTDisableInterrupts();
         OpenCoreTimer(GetSystemClock() / 200);
         INTRestoreInterrupts(int_status);
         mCTClearIntFlag();
         while( !mCTGetIntFlag() );
     }
     mCTClearIntFlag();
 }

int main(){
    UART1_Init();               // Call the initializations function of UART1
    LED1_TRIS = 0;              // Set the LED1 as an output
    UART1TX_TRIS = 0;           // Set UART1 TX pin as output
    UART1RX_TRIS = 1;           // Set UART1 RX pin as input
    LED1 = 0;                   // Turn off LED1

    while(1){
//        DelayMs(1000);
//        IEC0bits.U1TXIE = 1;            // Enable UART1 TX ISR
//       U1TXREG = 0x41;           // Send command to U1TXREG
    }
return 0;
}

2 ответа

Решение

Поскольку вы используете PIC32MX795F512H, вы можете использовать инструмент фреймворка MPLAB Harmony для создания своего проекта. Так что вам не нужно играть на битовом уровне и застревать в незначительной ошибке или наиболее вероятной ошибке опечатки. Удобно генерировать драйверы и все фреймворки правильно.

Спасибо и привет Рави

Использование Harmony фактически поможет вам избежать простых ошибок, подобных той, с которой вы столкнулись. Специально для часов у вас даже есть функции автоматического вычисления, которые значительно сокращают время вашей реализации.

Другие вопросы по тегам