__delay_ms() の動きに違和感を感じたのでもう少し深掘りしてみることにした。
あと、 PLL(Phase Locked Loop)×16でbit出力のスキャンタイム計測など。
XC16リファレンスマニュアルによると、libpic30.hは遅延マクロコマンドのライブラリであり、includeする前にFCYに instruction clock frequency を定義してやらねばならないそうなので、当初それに従い7.37MHz÷2を代入していたが、それでは倍の時間になってしまう。
なので、7.37MHz÷4を入力することにした。XC8と同じく、Fosc÷4が命令実行の基底周波数なのだろうか?
1.まず、FOSFPR = FRCにて、__delay_ms(500);を入れてPORTB0をフリッカさせ、出力電圧の波形を見る。
概ね設計通りのパルス幅になっていることがわかる。
2.この状態から、FOSFPR = FRC_PLL16に変更。
PLLの安定を待つためwhile (OSCCONbits.LOCK != 1);を生かして計測する。
設定通り、概ねパルス幅が1/16になっていることがわかる。
ここで、FCYを29480000ULにしてやると、元の500ms幅のパルスに戻るので、PLLは正常に効いていると思う。
3.次に__delay_ms(500);をコメントアウトし、FOSFPR = FRCにてスキャンタイムを計測した。
スキャンタイムは約7μsecといったところだろうか。
4.最後、FOSFPR = FRC_PLL16に変更してスキャンタイムを計測する。
スキャンタイム425.5nsecなので、PLL×16が正常に効いているみたい。
なお、オシレータの補正関数であるOSCTUNは補正値の最小が1.5%とかのになるので大雑把すぎて実際にはあまり役に立たない印象。
newmainXC16.c
あと、 PLL(Phase Locked Loop)×16でbit出力のスキャンタイム計測など。
XC16リファレンスマニュアルによると、libpic30.hは遅延マクロコマンドのライブラリであり、includeする前にFCYに instruction clock frequency を定義してやらねばならないそうなので、当初それに従い7.37MHz÷2を代入していたが、それでは倍の時間になってしまう。
なので、7.37MHz÷4を入力することにした。XC8と同じく、Fosc÷4が命令実行の基底周波数なのだろうか?
1.まず、FOSFPR = FRCにて、__delay_ms(500);を入れてPORTB0をフリッカさせ、出力電圧の波形を見る。
概ね設計通りのパルス幅になっていることがわかる。
2.この状態から、FOSFPR = FRC_PLL16に変更。
PLLの安定を待つためwhile (OSCCONbits.LOCK != 1);を生かして計測する。
設定通り、概ねパルス幅が1/16になっていることがわかる。
ここで、FCYを29480000ULにしてやると、元の500ms幅のパルスに戻るので、PLLは正常に効いていると思う。
3.次に__delay_ms(500);をコメントアウトし、FOSFPR = FRCにてスキャンタイムを計測した。
スキャンタイムは約7μsecといったところだろうか。
4.最後、FOSFPR = FRC_PLL16に変更してスキャンタイムを計測する。
スキャンタイム425.5nsecなので、PLL×16が正常に効いているみたい。
なお、オシレータの補正関数であるOSCTUNは補正値の最小が1.5%とかのになるので大雑把すぎて実際にはあまり役に立たない印象。
Template_dsPIC30F3013_2.X\newmainXC16.c |
1 /* 2 * File: newmainXC16.c 3 * Author: http://kazuikazui.dreamlog.jp/ 4 * Device: dsPIC30F3013 5 * Compiler: XC16 Ver2.00 6 * IDE : MPLAB X IDE v6.05 7 * Created on 2023/05/20, 00:02 8 */ 9 10 // DSPIC30F3013 Configuration Bit Settings 11 12 // 'C' source line config statements 13 14 // FOSC 15 #pragma config FOSFPR = FRC // Oscillator (Internal Fast RC (No change to Primary Osc Mode bits)) 16 //#pragma config FOSFPR = FRC_PLL16 // Oscillator (FRC w/PLL 16x) 17 #pragma config FCKSMEN = CSW_FSCM_OFF // Clock Switching and Monitor (Sw Disabled, Mon Disabled) 18 19 // FWDT 20 #pragma config FWPSB = WDTPSB_16 // WDT Prescaler B (1:16) 21 #pragma config FWPSA = WDTPSA_512 // WDT Prescaler A (1:512) 22 #pragma config WDT = WDT_OFF // Watchdog Timer (Disabled) 23 24 // FBORPOR 25 #pragma config FPWRT = PWRT_64 // POR Timer Value (64ms) 26 #pragma config BODENV = BORV20 // Brown Out Voltage (Reserved) 27 #pragma config BOREN = PBOR_ON // PBOR Enable (Enabled) 28 #pragma config MCLRE = MCLR_EN // Master Clear Enable (Enabled) 29 30 // FGS 31 #pragma config GWRP = GWRP_OFF // General Code Segment Write Protect (Disabled) 32 #pragma config GCP = CODE_PROT_OFF // General Segment Code Protection (Disabled) 33 34 // FICD 35 #pragma config ICS = ICS_PGD // Comm Channel Select (Use PGC/EMUC and PGD/EMUD) 36 37 // #pragma config statements should precede project file includes. 38 // Use project enums instead of #define for ON and OFF. 39 40 #include <xc.h> 41 42 //****************** Include Library ******************* 43 //#define FCY 1843200UL // 7.3728MHz / 4 44 //#define FCY 29491200UL // 7.3728MHz*16 / 4 45 //#define FCY 1842500UL // 7.37MHz / 4 46 #define FCY 29480000UL // 7.37MHz*16 / 4 47 #include <libpic30.h> 48 49 //****************** I/O assignment ******************* 50 #define LED1 _LATB0 51 #define LED2 _LATB1 52 #define LED3 _LATB2 53 #define LED4 _LATB3 54 #define SW1 _LATB5 55 56 int main(void) { 57 OSCTUN = 0b00000000; 58 // while (OSCCONbits.LOCK != 1); // Wait for PLL to stabilize (LOCK) 59 60 TRISBbits.TRISB0 = 0; // TRISx* = 0 is output 61 TRISBbits.TRISB1 = 0; // TRISx* = 1 is input 62 TRISBbits.TRISB2 = 0; 63 TRISBbits.TRISB3 = 0; 64 TRISBbits.TRISB4 = 1; 65 TRISBbits.TRISB5 = 1; 66 TRISBbits.TRISB6 = 1; 67 TRISBbits.TRISB7 = 1; 68 TRISBbits.TRISB8 = 1; 69 TRISBbits.TRISB9 = 1; 70 TRISCbits.TRISC13 = 1; 71 TRISCbits.TRISC14 = 1; 72 TRISCbits.TRISC15 = 1; 73 74 ADPCFGbits.PCFG0 = 0; //PCFG* = 0; is analog 75 ADPCFGbits.PCFG1 = 0; //PCFG* = 1; is degital 76 ADPCFGbits.PCFG2 = 0; 77 ADPCFGbits.PCFG3 = 0; 78 ADPCFGbits.PCFG4 = 0; 79 ADPCFGbits.PCFG5 = 1; 80 ADPCFGbits.PCFG6 = 0; 81 ADPCFGbits.PCFG7 = 0; 82 ADPCFGbits.PCFG8 = 0; 83 ADPCFGbits.PCFG9 = 0; 84 85 while(1){ 86 LED1 = ~LED1; 87 // __delay_ms(500); 88 } 89 } 90