//****************************************************************************** // si5351+PIC18F14K50 DDS-VFO の製作 // CYTEC 2018-03-23    製作:JE1AHW/内田恵介 // 開発ソフト: mikroC PRO Ver7.0 // --------------------------------------------------------------------------- // 2018-03-23 ソフト開発始める // 2018-03-24 si5351発振する。 // // // // //****************************************************************************** //■■■ 関数宣言 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ void main(); void PIC18F14k50_set(); void await(unsigned long ct); void wr_I2C(unsigned char x); void cmd_si5351(unsigned char reg_No, unsigned char x); void set_freq(unsigned long freq); void si5351_init(void); //■■■ ピンアサイン ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ #define SCL PORTC.B4 //I2C Clock RC4 #define SDA PORTC.B5 //I2C Data RC5 //■■■グロ−バル変数設定 ■■■■■■■■■■■■■■■■■■■ ■■■■■■ //■■■ PIC初期設定  PIC18F14K50 ■■■■■■■■■■■■■■■■■■■■ void PIC18F14k50_set() { OSCCON = 0b01110111; //クロック周波数設定 111=16MHz, 110=8MHz, 101=4MHz OSCCON2 = 0b00000111; // //--------------------------------------------------------------------------- IOCA = 0b00000011; //端子状態変化割り込み許可(PORTA、0−1) UCON = 0b00000000; //USB機能未使用 // RA0,RA1の状態変化割り込みを許可した後、USB機能を未使用とする。 // この設定で、RA0,RA1が、デジタル・ポ−ト(入力のみ)として使用できる。 //--------------------------------------------------------------------------- C1ON_bit = 0; // Disable comparators C2ON_bit = 0; // コンパレ−タ未使用 //--------------------------------------------------------------------------- TRISA = 0b00111011; //ポ−トA入出力設定 RA0,RA1,RA3 = Input TRISB = 0b00000000; //ポ−トB入出力設定 ALL = OutPut TRISC = 0b11000000; //ポ−トC入出力設定 RC6,RC7 = Input //--------------------------------------------------------------------------- ANSEL = 0b00000000; //RC3,RC2,RC1,RC0,RA4,-,-,- ; 0 = デジタル 有効 ANSELH = 0b00000001; // -,-,-,-,RB5,RB4,RC7,RC6 ; 1 = デジタル 無効 //--------------------------------------------------------------------------- ADCON0 = 0b00100001; //AN8(RC6,1000), A/D Unit ON ADCON1 = 0b00000000; //リファレンス電源選択(電源電圧使用) // .............. ADCON2.ADFM = 1; //デ−タ右詰め // .............. ADCON2.ACQT2 = 1; //アクイジョンタイム  ADCON2.ACQT1 = 0; //110=16TDA,100=8TDA,011=6TDA ADCON2.ACQT0 = 0; // ............... ADCON2.ADCS2 = 1; //A/D変換クロック  ADCON2.ADCS1 = 0; //001=Fosc/8, 101=Fosc/16, 010=Fosc/32, 110=Fosc/64 ADCON2.ADCS0 = 1; //---- 割り込みの設定 ------------------------------------------------------- RCON.IPEN = 0; // //---- Timer0の設定 --------------------------------------------------- T0CON.T08BIT = 1; T0CON.T0CS = 0; T0CON.PSA = 1; T0CON.T0CS = 0; INTCON.T0IF = 0; //オバ−フロ−フラグ・クリア− TMR0L = 0x80; //TIMER0インタ−バル周期設定 T0CON.TMR0ON = 1; INTCON.TMR0IE = 1; //Timer0オバ−フロ−割り込み設定。 } //■■■ Wate Timer ■■■■■■■■■■■■■■■■■■■■ void await(unsigned long ct) { while(ct>0) ct--; } //■■■ I2C Data 書き込み ■■■■■■■■■■■■■■■■■■■■ void wr_I2C(unsigned char x) { unsigned int k; for(k=0;k<8;k++){ if(x & 0x80) SDA = 1; else SDA = 0; await(20); SCL = 1; await(20); SCL = 0; await(20); SDA = 0; x <<= 1; } SCL = 1; await(20); SCL = 0; } //■■■ I2C cmd 書き込み ■■■■■■■■■■■■■■■■■■■■ void cmd_si5351(unsigned char reg_No, unsigned char x) { SDA = 0; // start condition await(20); SCL = 0; // await(20); wr_I2C(0xC0); wr_I2C(reg_No); wr_I2C(x); await(20); SCL = 1; // stop condition await(20); SDA = 1; // await(200); } //■■■ si5351 初期化 ■■■■■■■■■■■■■■■■■■■■ void si5351_init(void){ SDA=1; SCL=1; await(200); cmd_si5351(183,0b10010010); // CL=8pF cmd_si5351(16,0x80); // Disable CLK0 cmd_si5351(17,0x80); // Disable CLK1 // set_freq(7100100); // 10MHz cmd_si5351(177,0xA0); // Reset PLL_A cmd_si5351(16,0x4F); // Enable CLK0 (MS0=Integer Mode, Source=PLL_A) // cmd_si5351(17,0x4F); // Enable CLK1 (MS1=Integer Mode, Source=PLL_A) } //■■■ si5351 Dataセット ■■■■■■■■■■■■■■■■■■■■ void set_freq(unsigned long freq){ // freq [Hz] // // fvco= fxtal*(a+b/c) ( a:15 -- 90, b:0 -- 1048575, c:1 -- 1048575 ) // freq= fvco /(a+b/c) ( a:4, 6--1800, b:0 -- 1048575, c:1 -- 1048575 ) // // P1= 128*a + floor(128*b/c) - 512 // P2= 128*b - c*floor(128*b/c) // P3= c // // int k; unsigned long M; unsigned int R; unsigned long c; unsigned long a; unsigned long b; unsigned long dd; unsigned long P1; unsigned long P2; unsigned long P3; if(freq<1500) freq=1500; else if(freq>280000000) freq=280000000; if( freq> 150000000){M=4; R=0;} else if(freq>=63000000){M=6; R=0;} else if(freq>=27500000){M=14; R=0;} else if(freq>=13000000){M=30; R=0;} else if(freq>= 6500000){M=62; R=0;} else if(freq>= 3000000){M=126; R=0;} else if(freq>= 1500000){M=280; R=0;} else if(freq>= 700000){M=600; R=0;} else if(freq>= 330000){M=1280; R=0;} else if(freq>= 150000){M=1300; R=1;} else if(freq>= 67000){M=1500; R=2;} else if(freq>= 30300){M=1600; R=3;} else if(freq>= 14000){M=1800; R=4;} else if(freq>= 7000){M=1800; R=5;} else if(freq>= 3500){M=1800; R=6;} else{M=1800; R=7;} freq*=M; freq<<=R; c=0xFFFFF; a=freq/25000000; b=(long)((double)(freq-a*25000000)*(double)c/(double)25000000); dd=(128*b)/c; P1=128*a+dd-512; P2=128*b-c*dd; P3=c; //Set fvco of PLL_A cmd_si5351(26,(P3>>8)&0xFF); //MSNA_P3[15:8] cmd_si5351(27,P3&0xFF); //MSNA_P3[7:0] cmd_si5351(28,(P1>>16)&0x03); //MSNA_P1[17:16] cmd_si5351(29,(P1>>8)&0xFF); //MSNA_P1[15:8] cmd_si5351(30,P1&0xFF); //MSNA_P1[7:0] cmd_si5351(31,(P3>>12)&0xF0|(P2>>16)&0x0F);//MSNA_P3[19:16], MSNA_P2[19:16] cmd_si5351(32,(P2>>8)&0xFF); //MSNA_P2[15:8] cmd_si5351(33,P2&0xFF); //MSNA_P2[7:0] // Set MS0, MS1 // a=M, b=0, c=1 ---> P1=128*M-512, P2=0, P3=1 if(M==4){ P1=0; cmd_si5351(42,0); //MS0_P3[15:8] cmd_si5351(43,1); //MS0_P3[7:0] cmd_si5351(44,0b00001100); //0,R0_DIV[2:0],MS0_DIVBY4[1:0],MS0_P1[17:16] cmd_si5351(45,0); //MS0_P1[15:8] cmd_si5351(46,0); //MS0_P1[7:0] cmd_si5351(47,0); //MS0_P3[19:16], MS0_P2[19:16] cmd_si5351(48,0); //MS0_P2[15:8] cmd_si5351(49,0); //MS0_P2[7:0] cmd_si5351(50,0); //MS1_P3[15:8] cmd_si5351(51,1); //MS1_P3[7:0] cmd_si5351(52,0b00001100); //0,R1_DIV[2:0],MS1_DIVBY4[1:0],MS1_P1[17:16] cmd_si5351(53,0); //MS1_P1[15:8] cmd_si5351(54,0); //MS1_P1[7:0] cmd_si5351(55,0); //MS1_P3[19:16], MS0_P2[19:16] cmd_si5351(56,0); //MS1_P2[15:8] cmd_si5351(57,0); //MS1_P2[7:0] }else{ P1=128*M-512; cmd_si5351(42,0); //MS0_P3[15:8] cmd_si5351(43,1); //MS0_P3[7:0] cmd_si5351(44,(R<<4)&0x70|(P1>>16)&0x03);//0,R0_DIV[2:0],MS0_DIVBY4[1:0],MS0_P1[17:16] cmd_si5351(45,(P1>>8)&0xFF); //MS0_P1[15:8] cmd_si5351(46,P1&0xFF); //MS0_P1[7:0] cmd_si5351(47,0); //MS0_P3[19:16], MS0_P2[19:16] cmd_si5351(48,0); //MS0_P2[15:8] cmd_si5351(49,0); //MS0_P2[7:0] cmd_si5351(50,0); //MS1_P3[15:8] cmd_si5351(51,1); //MS1_P3[7:0] cmd_si5351(52,(R<<4)&0x70|(P1>>16)&0x03);//0,R1_DIV[2:0],MS1_DIVBY4[1:0],MS1_P1[17:16] cmd_si5351(53,(P1>>8)&0xFF); //MS1_P1[15:8] cmd_si5351(54,P1&0xFF); //MS1_P1[7:0] cmd_si5351(55,0); //MS1_P3[19:16], MS0_P2[19:16] cmd_si5351(56,0); //MS1_P2[15:8] cmd_si5351(57,0); //MS1_P2[7:0] } cmd_si5351(165,0); cmd_si5351(166,M); cmd_si5351(177,0xA0); // Reset PLL_A. Mが変化(特にM=4からM>=6に変化)するときは必須かも… } //■■■ メイン関数 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ void main() { PIC18F14k50_set() ; si5351_init(); set_freq(16100000); // スタ−ト周波数 while(1) { } }