开发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,在调试单片机的代码时,善用数字示波器和逻辑分析仪,有奇效。
``