dsPIC30F4013でLチカとUART通信をする

5 min read読了の目安(約4700字

dsPIC30F4013でLチカとUART通信が出来たのでメモ。
なかなかサンプルコードが落ちていなかったので、とても苦労しました。
内部クロックで動きます。
1HzでLEDの点滅とUART送信を行っています。

配線

dsPIC30F4013 周辺機器(LEDやFT232など)
Vdd 3V3(FT232)
Vss GND(FT232
pin25(U1TX) RXD(FT232)
pin26(U1RX) TXD(FT232)
pin27 アノード(LED)

コード

// FOSC
#pragma config FOSFPR = FRC_PLL4             // Oscillator (Internal Fast RC (No change to Primary Osc Mode bits))
#pragma config FCKSMEN = CSW_FSCM_OFF   // Clock Switching and Monitor (Sw Disabled, Mon Disabled)

// FWDT
#pragma config FWPSB = WDTPSB_16        // WDT Prescaler B (1:16)
#pragma config FWPSA = WDTPSA_512       // WDT Prescaler A (1:512)
#pragma config WDT = WDT_OFF            // Watchdog Timer (Disabled)

// FBORPOR
#pragma config FPWRT = PWRT_64          // POR Timer Value (64ms)
#pragma config BODENV = BORV27          // Brown Out Voltage (2.7V)
#pragma config BOREN = PBOR_ON          // PBOR Enable (Enabled)
#pragma config MCLRE = MCLR_DIS          // Master Clear Enable (Enabled)

// FGS
#pragma config GWRP = GWRP_OFF          // General Code Segment Write Protect (Disabled)
#pragma config GCP = CODE_PROT_OFF      // General Segment Code Protection (Disabled)

// FICD
#pragma config ICS = ICS_PGD            // Comm Channel Select (Use PGC/EMUC and PGD/EMUD)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

unsigned int counter = 0;   // Initialize counter

int main() {
    /* OSCCON oscillator setting register */
    OSCCONbits.CF = 0;  // Not detected clock failure
    OSCCONbits.COSC = 0b111;    // PLL oscillator which was defined FOSFPR
    OSCCONbits.LOCK = 1;    // PLL is in lock
    OSCCONbits.LPOSCEN = 0; // Secondary oscillator is disabled
    OSCCONbits.NOSC = 0b111;    // New PLL oscillator which was defined
    OSCCONbits.OSWEN =  0;  // Switch is completed
    OSCCONbits.POST = 0;    // Postscaler does not alter clock
    
    /* IO Setting */
    TRISA = 0;  // Digital out
    TRISB = 0;  // Digital out
    TRISC = 0;  // Digital out
    TRISD = 0;  // Digital out
    TRISF = 0;  // Digital out
    TRISFbits.TRISF2 = 1;   // RX pin setting
    TRISFbits.TRISF3 = 0;   // TX pin setting
    TRISBbits.TRISB0 = 1;   // Analog in
    TRISBbits.TRISB1 = 1;   // Analog in
    TRISBbits.TRISB2 = 1;   // Analog in
    TRISBbits.TRISB3 = 1;   // Analog in
    TRISBbits.TRISB4 = 1;   // Analog in
    TRISBbits.TRISB5 = 1;   // Analog in
    TRISBbits.TRISB8 = 1;   // Analog in
    TRISBbits.TRISB9 = 1;   // Analog in
    TRISBbits.TRISB10 = 1;  // Analog in
    TRISBbits.TRISB11 = 1;  // Analog in
    TRISBbits.TRISB12 = 1;  // Analog in
    
   /*Timer Setting Register(ADC Sampling Time Management)*/
    T1CONbits.TON = 0; //Timer OFF. タイマーOFF.
    T1CONbits.TCS = 0; //Use internal Clock. 内部クロックを使用.
    T1CONbits.TGATE = 0; //Gate time accumulate is off.ゲートタイム累積無効. 
    T1CONbits.TSIDL = 0; //Continue on IDLE mode. アイドルモードでタイマ継続.
    T1CONbits.TSYNC = 0; //NONE. 無視(TCS = 0のとき)
    T1CONbits.TCKPS = 0b11; //prescaler 256
    
    /*Interrupt Setting*/
    PR1 = 28; //700Hz
    IPC0bits.T1IP = 5; //Interrupt priority is 5. 優先順位5, 高いほうが優先順位が高い.
    IEC0bits.T1IE = 1; //Timer 1 interrupt is enable. タイマ1割り込みON.
    IFS0bits.T1IF = 0; //Timer 1 Interrupt flag is off. タイマ1割り込みフラグ0。
    T1CONbits.TON = 1; //Timer ON
    
    /* UART Setting */ 
    U1MODEbits.UARTEN = 1; //UART disabled
    U1MODEbits.USIDL = 0; //Run UART on IDLE mode
    U1MODEbits.ALTIO = 0; //Alternate pin is enabled
    U1MODEbits.WAKE = 0; //Wakeup is disabled
    U1MODEbits.LPBACK = 0; //Loopback mode is disabled
    U1MODEbits.ABAUD = 1; //U1RX to Capture
    U1MODEbits.PDSEL = 0; //No parity 8-bit
    U1MODEbits.STSEL = 0; //1STOP bit
    U1STAbits.UTXISEL = 1; //When buffer is empty
    U1STAbits.UTXBRK = 0; //Transfer break is normal mode
    U1STAbits.URXISEL = 0b00; //When accepting any character, interrupt is occured
    U1STAbits.ADDEN = 0; //Address detector is disabled
    U1STAbits.OERR = 0; //Not Overrun (First write only)
    
    U1BRG = 49;
    U1MODEbits.UARTEN = 1; //UART disabled
    U1STAbits.UTXEN = 1; //UART TX is enabled.
    
    PORTFbits.RF5 = 1;   // Invert bit
    while(1);
}

int flagLED = 0;
int counterLED  = 0;
void __attribute__((interrupt, shadow, auto_psv)) _T1Interrupt(void) {
    IFS0bits.T1IF = 0;  // Flag is low
    counterLED++;
    if(counterLED >= 1000) {
        printf("S\n");
        if (flagLED == 0) flagLED = 1;
        else flagLED = 0;
        PORTFbits.RF5 = flagLED;
        counterLED = 0;
    }
}

動作の様子

https://youtu.be/agoB07lBCxE
https://youtu.be/mFhUKO3ZInY