【原创】32位单片机PIC32MX270F256B设置UART的两种方法【寄存器方法和库函数方法(基于plib.h)】

开发IDE:MPLAB X 5.25
下载/DEBUG工具:MPLAB ICD 3/PICKIT 3
MCU:PIC32MX270F256B
编译器:XC32 V2.30
晶振:外部晶振4M,system pll 倍频到48M作为sys clock
首先是库函数方法配置UART1

#include "UART.h"
void UART1_Init() 
{
    //关联引脚
    U1MODEbits.STSEL = 0; //1 STOP BIT
    U1MODEbits.PDSEL = 0; //00 = 8 位数据,无奇偶校验
    U1MODEbits.BRGH = 0; //0 = 标准速度模式—— 使能16 倍波特率时钟  1 = 高速模式—— 使能4 倍波特率时钟
    U1MODEbits.ABAUD=0; //禁止波特率测量
    U1MODEbits.UEN=0b00;//00 = 使能并使用UxTX 和UxRX 引脚; UxCTS 和UxRTS/UxBCLK 引脚由PORTx 寄存器中的相应位控制
    U1STAbits.UTXEN = 1; //UTXEN:发送使能位
    U1BRG = 38; //9600
    //pbclk=sysclk/8=48/8=6M
    //UxBRG=PBCLK/(16 ×波特率)-1
  // NTCON1bits.NSTDIS = 0; //   NSTDIS: 中断嵌套禁止位  
    IEC1bits.U1RXIE=1;//UART1 接收器中断允许位 ,见pic32mx1xx2xx——44xlp page66
    IPC8bits.U1IP = 0b010; //记于2019年11月18日,优先级只能设为2,一开始设为111.最高优先级,进不去中断,很奇怪,设置为2就能近中断,血的教训
    //IPC8:中断优先级控制寄存器8,U1RXIP<2:0>:UART1 接收器中断优先级位 111 = 中断优先级为7 (最高优先级中断)
    IPC8bits.U1IS = 0b00; //IPC8:中断次级优先级控制寄存器 
    U1STAbits.URXISEL = 0; //当接收到一个字符时,中断标志位置1 ;且UxRSR 的内容被传输给接收缓冲器。接收缓冲器有一个或多个字符。 
    U1STAbits.OERR = 0; //CLEAR   接收缓冲器   
    //IFS1bits.U1RXIF=0;//复位接收中断标志位
    U1STAbits.URXEN = 1; //接收使能位
    U1MODEbits.ON = 1; //1 = 使能UARTx 模块。UARTx 引脚由UARTx 根据UEN<1:0> 和UTXEN 控制位的定义控制
    U1MODEbits.UARTEN=1;
   
}

或者用库函数初始化UART1,此方法和上面方法等效

void UART1_Init_By_Lib()
{
     //UART1模块初始化:配置为串口通信、8位数据、1位停止、无校验、仅用TX和RX引脚...等
    UARTConfigure(UART_MODULE_ID, UART_ENABLE_PINS_TX_RX_ONLY);
    UARTSetFifoMode(UART_MODULE_ID, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl(UART_MODULE_ID, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
    UARTSetDataRate(UART_MODULE_ID, GetPeripheralClock(), DESIRED_BAUDRATE);
    UARTEnable(UART_MODULE_ID, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

    //UART1中断配置
    INTEnable(INT_SOURCE_UART_RX(UART_MODULE_ID), INT_ENABLED);
    INTSetVectorPriority(INT_VECTOR_UART(UART_MODULE_ID), INT_PRIORITY_LEVEL_2);
    INTSetVectorSubPriority(INT_VECTOR_UART(UART_MODULE_ID), INT_SUB_PRIORITY_LEVEL_0);
 
}

接下来是发送一个char和一段字符串的函数

void UART1_SendData(char dat) 
{
    while (U1STAbits.TRMT!=1) 
    {
        ; //wait!!!if MCU is sending data
    }
    U1TXREG = dat;
}

void UART1_SendBuf(char *buff, uint num) {
    unsigned int i = 0;
    while (i < num) {
        UART1_SendData(buff[i]); //Send the current char
        i++;
    }
}

UART1的接收中断,以下中断函数放在main.c,否则报error

void __ISR(_UART_1_VECTOR, IPL2AUTO) IntUart1Handler(void) 
{
    //如果是接收中断
    if (INTGetFlag(INT_SOURCE_UART_RX(UART_MODULE_ID))) {
        int i;
        BYTE t;
        t = UARTGetDataByte(UART_MODULE_ID);
        
        // PORTClearBits(IOPORT_B, BIT_5);
        
        UART1_SendData(t); //回传数据
        
        // Clear the RX interrupt Flag
        INTClearFlag(INT_SOURCE_UART_RX(UART_MODULE_ID));
        //PORTSetBits(IOPORT_B, BIT_5);
       
    }
    // We don't care about TX interrupt
    if (INTGetFlag(INT_SOURCE_UART_TX(UART_MODULE_ID))) 
    {
        INTClearFlag(INT_SOURCE_UART_TX(UART_MODULE_ID));
    }
}

最后附上我的UART.h

#ifndef UART_H
#define    UART_H
#include "global.h"
void UART1_Init();
void UART1_Init_By_Lib();
void UART1_SendData(char dat) ;
void UART1_SendBuf(char *buff,uint num);
//void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt();
#endif    /* UART_H */

经验总结:pic32网上参考代码并不多,代码调不出来时,可以多认真看datasheet,在调试单片机的代码时,善用数字示波器和逻辑分析仪,有奇效。

``

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

添加新评论

  关于博主

  近期评论

  •  额: 优秀帅气的小伙子,加油

  分类目录

离别时的伤感,时候却很难说出口,哪怕是短暂的分离!—— by 小宇

人生应该树立目标,否则你的精力会白白浪费。

山涧的泉水经过一路曲折,才唱出一支美妙的歌。

如若不是为了一个人,谁肯枯守一座城。城市和爱情,总是有着这样那样的关系。我们会因为一个人,去到那座城,因为那是一座爱的城;我们也会因为一个人,离开一座城,那是一座绝望的伤城。

常求有利别人,不求有利自己。