PIC32MX795F512H UART 通信到 RS232

PIC32MX795F512H UART communication to RS232

我目前是第一次使用 PIC 微控制器。在代码中,我准确指定了我正在使用的 PIC、编译器等。也许这有帮助。

我正在尝试在 PIC32 上设置 UART 通信,并通过 RS232 将十六进制代码(例如 0x41)发送到我计算机上的终端。为了将信号从 PIC UART 转换为 RS232 电平,我使用的是 MAX232EPE。

目前我 运行 遇到这样的问题,例如当我从 PIC32 向终端发送 0x41 或向终端发送 0x41 时,接收到的数据不匹配。我认为这是由于我的波特率设置错误引起的,但我不确定。有人可以查看我的代码,看看是否有人可以看到问题吗?我忘了定义什么吗?我定义错了吗?我是不是算错了波特率?

P.S。我知道接收到的数据与发送的数据不匹配,因为我在 mplab 的调试模式下检查了 "watches",当我回显从终端发送到 PIC32 的数据返回到终端时,它不匹配要么。

延迟和中断代码可以忽略,它们按预期工作,所以我真的认为问题与 PIC/buad 速率的初始设置有关。

我希望这足够清楚,非常感谢任何帮助

谢谢,

见下方代码

/*
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;
}

由于您使用的是PIC32MX795F512H,您可以使用MPLAB Harmony 框架工具来创建您的项目。这样您就不必在位级别上玩并陷入小错误或最有可能的错字错误中。 方便地正确生成驱动程序和所有框架。

感谢和问候 拉维

使用 Harmony 实际上可以帮助您避免类似您遇到的简单错误。特别是对于时钟,您甚至可以使用自动计算功能显着减少您的实施时间。