MPLAB X IDE 调试-UART(DSPIC33FJ32MC204芯片与PC进行通信)附上代码和注释

 

上图为芯片TTL电压转换为串口RS232电压,该DB9为母口,通过串口转USB线连接到电脑PC端上。

目的:使用dspic33fj32mc204与PC端进行通信,然后使用串口调试助手进行收发数据

程序如下(注意:下面程序与MIRCOCHIP公司的dspic33f系列数据手册的程序有些不同,是在它基础上的补充说明和改进bug):

#include "p33FJ32MC204.h"
#include "dsp.h"
#include <xc.h>
#include <PPS.H>
/*****************Config bit settings****************/
// FBS
#pragma config BWRP = WRPROTECT_OFF     // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH           // Boot Segment Program Flash Code Protection (No Boot program Flash segment)

// FGS
#pragma config GWRP = OFF               // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF                // General Segment Code Protection (User program memory is not code-protected)

// FOSCSEL
#pragma config FNOSC = FRC             //
#pragma config IESO = ON                // 使用内部FRC振荡源启动器件,然后自动切换为就绪的用户选择的振荡器源 Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)

// FOSC
#pragma config POSCMD = XT              //
#pragma config OSCIOFNC = OFF           // OSC2 Pin Function (OSC2 pin has clock out function)
#pragma config IOL1WAY = OFF            //
#pragma config FCKSM = CSECME           // 

// FWDT
#pragma config FWDTEN = OFF             //
// FPOR
#pragma config FPWRT = PWR128           // POR Timer Value (128ms)
#pragma config ALTI2C = OFF             // Alternate I2C  pins (I2C mapped to SDA1/SCL1 pins)
#pragma config LPOL = ON                // Motor Control PWM Low Side Polarity bit (PWM module low side output pins have active-high output polarity)
#pragma config HPOL = ON                // Motor Control PWM High Side Polarity bit (PWM module high side output pins have active-high output polarity)
#pragma config PWMPIN = ON              // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)

// FICD
#pragma config ICS = PGD3               // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG is Disabled)

#define FCY 40000000
#define BAUDRATE 9600
#define BRGVAL ((FCY/BAUDRATE)/16)-1
unsigned int i;


void __attribute__((__interrupt__,no_auto_psv)) _U1RXInterrupt( void );
void __attribute__((__interrupt__)) _U1TXInterrupt( void );
void __attribute__((__interrupt__,no_auto_psv)) _T1Interrupt(void);
char ReceivedChar;

int main(void)
{
        //Perform a clock switch to 40MIPS (80Mhz)外部晶振电路图上是7.3728MHZ(FIN)但是实际板子上是8MHZ
	PLLFBD = 38;			//M=PLLFBD+2       = 40
	CLKDIVbits.PLLPOST = 0;	//N2=2(PLLPOST+1)  = 2
	CLKDIVbits.PLLPRE = 0;	//N1=PLLPRE+2      = 2

        OSCTUN=0; // Tune FRC oscillator, if FRC is used
        RCONbits.SWDTEN=0; // Disable Watch Dog Timer

        //unlock OSCCON register
	__builtin_write_OSCCONH(0x03);//切换到带PLL的主振荡器模式   经过测试 应该切换成功了
	__builtin_write_OSCCONL(0x01);//时钟切换被使能,外设引脚未锁定,允许写入外设引脚选择寄存器,PLL处于失锁状态,禁止辅助振荡器,请求切换新的振荡器
    //wait for clock to stabilize
	while(OSCCONbits.COSC != 0b011);
	//wait for PLL to lock
	while(OSCCONbits.LOCK != 1) {};
    //clock switch finished

        TRISBbits.TRISB4 = 1;//RP4输入
        TRISCbits.TRISC5 = 0;//RP21输出

        TRISBbits.TRISB15 = 0;
        TRISBbits.TRISB14 = 0;
        //UART
        //UART外设引脚选择
        PPSUnLock;
        RPINR18bits.U1RXR = 4;//UART1接收
        _RP21R = 0b00011;//UART1发送
        PPSLock;

        //UART发送配置
        //UxMODE UARTx模式寄存器
        //_USIDL = 1;//器件进入空闲模式时,模块停止工作
        //_UEN = 0;// 使能并使用 UxTX 和 UxRX 引脚; UxCTS、 UxRTS 和 BCLKx 引脚由端口锁存器控制
        //_LPBACK = 0;//禁止环回模式
        _ABAUD = 0;//禁止自动波特率使能位
        //U1STAbits.UTXINV = 0;//UxTX的空闲状态为0
        //_URXINV = 1;//UxRX的空闲状态为0
        _BRGH = 0;//波特率选择为低速
        U1BRG = BRGVAL;//波特率设置为9600
        _PDSEL = 0;//8位数据,无奇偶校验位
        _STSEL = 0;//1个停止位
        //UxSTA UARTx状态和控制寄存器
        U1STAbits.UTXISEL0 = 0b0;//当一个字符被传输到发送移位寄存器时,意味着发送缓冲器至少有一个单元为空,产生中断
        U1STAbits.UTXISEL1 = 0b0;
        //U1STAbits.UTXINV = 0;//UxTX的空闲状态为0
        //U1STAbits.UTXBRK = 1;//发送间隔位,无论发送器状态如何,都将UxTX引脚驱动为低电平
        //IPC3bits.U1TXIP = 3;//接收器自然优先级比发送器高
        IEC0bits.U1TXIE = 1;
        _UARTEN = 1;//使能UART1 当模块第一次使能时,用户应用程序应在ISR中清零U1TXIF位
        _UTXEN = 1;//使能UART1发送器,由UARTx控制UxTX引脚,如果UTXISEL为00将UxTXIF位置1
    
        /* wait at least 104 usec (1/9600) before sending first char */
        for(i=0;i<4160;i++)
        {
            Nop();
        }
        U1TXREG = '1';

        //UART接收配置
//        IPC2bits.U1RXIP = 4;
        IEC0bits.U1RXIE = 1;
        IFS0bits.U1RXIF = 0;
        U1STAbits.URXISEL = 0;

        while(1)
        {
            /* check for receive errors */
            if(U1STAbits.FERR == 1)//检测到当前字符的帧错误
            {
                continue;
            }
            /* must clear the overrun error to keep uart receiving */
            if(U1STAbits.OERR == 1)//如果接收缓冲区已经溢出
            {
                U1STAbits.OERR = 0;//清零原来置1的OEER位将使接收缓冲区和RSR复位为空状态
                continue;
            }
            /* get the data */
            if(U1STAbits.URXDA == 1)
            {
                ReceivedChar = U1RXREG;
            }
        }

        while(1);
        return(0) ;

}



void __attribute__((__interrupt__,no_auto_psv)) _U1TXInterrupt(void)
{
    IFS0bits.U1TXIF = 0;
    for(i=0;i<4160;i++)
       {
            Nop();
        }
    U1TXREG = '1';
    //PORTBbits.RB14 = !PORTBbits.RB14;
}

void __attribute__((__interrupt__,no_auto_psv)) _U1RXInterrupt(void)
{
    IFS0bits.U1RXIF = 0;

   if (ReceivedChar == 'a')
   {PORTBbits.RB15 = !PORTBbits.RB15;}
}

程序说明:配置UART的收发程序,电路板芯片通过串口和PC进行通信,发送字符1到PC端,PC端也可发送字符a到芯片,如果接收到了正确的字符a,那么RB15对应的LED灯亮或灭。

下面是PC端接收和发送: