如何使能PIC32MX的UART中断?

问题描述 投票:0回答:1

我试图为 PIC32MX320F128H 创建一个 UART 驱动程序,当我注意到每当 UART IRQ 发生时,系统都会崩溃。

调试器告诉我程序在这些行(119 - 21)处停止?每次都是 ctr0.s。

\_reset:
jal \_startup

        nop

这是董事会设置

// BOARD Setup
\#pragma config POSCMOD      = XT        // Set oscillator to XT, crystal mode.
\#pragma config FPBDIV       = DIV_2     // Set peripheral clock to run at half sys clock
\#pragma config FWDTEN       = OFF       // Disable watchdog timer
\#pragma config CP           = OFF       // Disable Code protect, ensures all memory is available
\#pragma config FPLLMUL         = MUL_20    // PLL Multiplier
\#pragma config FPLLODIV     = DIV_1     // System PLL Output Clock Divide

\#define SYSTEM_CLOCK 80000000L
\#define  PB_CLOCK SYSTEM_CLOCK/2

\#define TRUE 1
\#define FALSE 0

// UART DEFINES
\#define UART_IBITS 0x1C000000   // ERR, RX, TX interrupt bits
\#define ERR_IBITS 0x4000000
\#define RX_IBITS   0x8000000
\#define TX_IBITS 0x10000000

\#define STA_OERR_BIT 2          // U1STA bit assosciated with OERR

\#define TEST_CHAR 0x41          // char to send and test stuff, A in ascii

\#define U1_PRIORITY 0b110       // don't know what this should be

\#define U1_SUBPRIORITY 0b01     // don't know what this should be either

这是 UART 设置

void Uart_Init(unsigned long baudRate) {
AD1PCFG = 0xffff;               // Set PORTs to digital mode

// Disable interrupts to avoid crazy malloc errors while initing CBuffs
__builtin_disable_interrupts();

// Initialize CBuffers
RXBuff = InitCBuff();
TXBuff = InitCBuff();

// Enable interrupts after cbuffs are initialized
__builtin_enable_interrupts();

// Disable stdout to UART2
setbuf(stdout, NULL);

// Clear control registers
U1MODECLR = 1;
U1STACLR = 1;

// Clear RX, TX registers
U1RXREG = 0;
U1TXREG = 0;

// Set Baudrate, U1BRG should be 20 or 21. In this case it is 21.
U1MODEbits.BRGH = 0;    // enable high baudrate mode
U1BRG = (PB_CLOCK / (16 * baudRate)) - 1;

// Turn on the UART
// Note, that by default the UART is configured for 8 data bits, 1 stop bit, and no parity.
U1MODEbits.ON = 1;    // 8 bit 1 stop bit

// Enable RX and TX pins
U1STAbits.URXEN = 1;
U1STAbits.UTXEN = 1;

// Enable interrupts RX and ERR interrupts. TX will enable when TXBuff has chars
IEC0bits.U1RXIE = 1;
IEC0bits.U1EIE = 1;
IEC0bits.U1TXIE = 0;

// Set Interrupt priority and subpriority
IPC6bits.U1IP = U1_PRIORITY;
IPC6bits.U1IS = U1_SUBPRIORITY;

// Set interrupt modes
U1STAbits.URXISEL = 0b00;   // flag when char received
U1STAbits.UTXISEL = 0b10;   // flag when buffer is empty


}

最后,这是 ISR 定义

void __ISR(_UART1_VECTOR, IPL4AUTO) IntUart1Handler(void) {

我还尝试使用一种已弃用的方法来启用中断,但我什至不知道如何让 plib 库工作,所以这并没有走得太远。

// Depreceated method.
void __attribute__ ((nomips16)) INTEnableSystemMultiVectoredInt(void)
{
    unsigned int val;

    // set the CP0 cause IV bit high
    asm volatile("mfc0   %0,$13" : "=r"(val));
    val |= 0x00800000;
    asm volatile("mtc0   %0,$13" : "+r"(val));
    
    INTCONSET = _INTCON_MVEC_MASK;

    // set the CP0 status IE bit high to turn on interrupts
    INTEnableInterrupts();
}

我真的束手无策,直到 MPLAB 论坛的 Rich TBCO 为我指明了正确的方向。

c embedded interrupt pic pic32
1个回答
0
投票

我没有正确启用中断。以下是我按照本指南启用 UART 中断的方法。

实际上只有七个步骤。步骤 3 到 7 应在您的程序中按顺序完成。

  1. 包括 xc.h 和 sys/attribs.h
  2. 创建 ISR。确保此处的优先级参数与中断配置中指定的优先级匹配。
  3. 关闭外围设备。
  4. 配置中断,按以下顺序:设置优先级,设置子优先级,清除标志,然后启用中断
  5. 启用多向量中断。
  6. 启用全局中断
  7. 启用外设

以下是我按照以下步骤配置 UART 的方法。

    #include <xc.h>
    #include <sys/attribs.h>
    void Uart_Init(unsigned long baudRate) {
    // Set Ports to digital mode, configure later to only do UART pins.
    AD1PCFG = 0xffff;

    // Initialize CBuffers
    RXBuff = InitCBuff();
    TXBuff = InitCBuff();

    // Clear control registers
    U1MODECLR = 0xFF;
    U1STACLR = 0xFF;

    // Clear RX, TX registers
    U1RXREG = 0;
    U1TXREG = 0;

    // Set Baudrate, U1BRG should be 20 or 21. In this case it is 21.
    U1MODEbits.BRGH = 0; // enable high baudrate mode
    U1BRG = (PB_CLOCK / (16 * baudRate)) ;

    // Turn off the UART
    U1MODEbits.ON = 0;

    // Enable RX and TX pins
    U1STAbits.URXEN = 1;
    U1STAbits.UTXEN = 1;

    // Set interrupt modes
    U1STAbits.URXISEL = 0b00; // flag when char received
    U1STAbits.UTXISEL = 0b10; // flag when buffer is empty

    // Set Interrupt priority and sub-priority
    IPC6bits.U1IP = 4;
    IPC6bits.U1IS = 1;

    // Clear flags
    IFS0bits.U1EIF = 0;
    IFS0bits.U1RXIF = 0;
    IFS0bits.U1TXIF = 0;

    // Enable interrupts RX and ERR interrupts. TX not necessary for this simple program
    IEC0bits.U1RXIE = 1;
    IEC0bits.U1EIE = 1;
    IEC0bits.U1TXIE = 0;
    
    // Enable multi-vector interrupts
    INTCONSET = _INTCON_MVEC_MASK;
    
    // Enable Global Interrupts
    __builtin_enable_interrupts();
    
    // Enable UART
    // Note, that by default the UART is configured for 8 data bits, 1 stop bit, and no parity.
    U1MODEbits.ON = 1;
}
© www.soinside.com 2019 - 2024. All rights reserved.