si5351aを使用した7MHz-QRP-CWトランシーバーの製作

[公開:any]

[電子工作/アマチュア無線]
[電子工作/PIC]
[PIC,PIC18F14K22,si5351a,TA7358P]

origin 2016-12-31


  • 大晦日から始めました。完成までしばらくかかります。(2016-12-31)
  • 単純な回路なので受信回路と送信回路を一気に作りました。(2017-01-10)
  • キークリック音の改善に苦労しています。(2017-01-22)
  • 完ぺきとは言えませんが、キークリック音を改善しました。(2017-02-10)

 1年ほど前から、ネット上のあちこちのサイトで話題になっていたシリコンラボのI2CクロックジェネレーターのSi5351aを遅ればせながら入手しました。出力できる周波数は2.5KHz〜200MHzと広範囲で、なおかつ、DDSチップよりも安い(秋月電子で購入すればチップ単品で150円。DIP化されたモジュールで500円)と話題になるには十分なスペックです。これをVFOとして7MHzのCWトランシーバーでも作るかとブレッドボードでテストしました。Si5351aに関してはJR1PWZさんのサイトでかなり詳しくレポートされています。その中で周波数変更に伴うスプラッターで受信音にプチプチ音の影響が心配との指摘があります。TA7358を使用した受信回路でテストしたところロータリーエンコーダーを回すと確かにプチプチ音が入ります。受信音が静かな状況ではかなり明瞭です。一応、比較のため、DDSのAD9833を使用したものでもテストしましたが、当然ながらDDSではまったく問題ありません。


 プチプチ音は気になりますが、値段につられてSi5351aモジュールをまとめ買いしたので、このまま進めます。CW用に狭帯域のフィルターを使用すると受信音が静かになってプチプチ音が気になるので、クリスタルフィルターは、水晶発振子3個のブロードなものとしてみました。こうすればにぎやかな7MHzの受信音に紛れてプチプチ音が気にならなくなります。(解決法の方向性が間違っていますが・・・)
 送信回路は、周波数変換なしでSi5351aのから直接7MHzを出力させて増幅する構成でテストしました。Si5351aは、3ch出力できるので受信用局発としての17MHz(IFは10.245MHz)と送信用の7MHzを同時発振の状態としたのですが、当然のことながら受信に送信用の7MHzがかぶってしまいまともに受信できません。このため、送信用の7MHzをやめて、BFOの10.245MHzを同時に発信させた状態でテストしたのですが、ブレッドボードの環境では細かなスプリアスが出て受信への影響がありました。このため、BFOは水晶発振として、送信時(フルブレークインなのでキーダウン時)に受信用局発を止めて送信用の局発を出力する方式でいくことにします。


 Si5351aモジュールによるVFOは部品点数が少なく簡単に作成できます。受信用局発と送信用局発でそれぞれに対応したローパスフィルターを実装するため2chを使用しました。(同時発振は行いません)
 Si5351aの制御はハードウェアでI2Cを実装しているPIC18F14K22を使用しました。Si5351aの制御方法が非常に複雑でデータシートだけではお手上げでした。Computer Radio RF Techさんのサイトで詳しい解説があるのでこれを参考にしてようやく理解できました。ソースコードもGitHUBにあるものを加工して対応させました。(AVRのソースコードはGNUライセンスで公開されたものが多いのでAVRを使用すればよかった・・・)


 受信用局発のスペクトラムです。アッテネーターが20dB入れてあります。左は60MHzまでの高調波、右はスパン5MHzでみたスプリアスです。LPFを手持ちのアキシャルリードタイプのインダクタを使用して適当に作ったので高調波が落とし切れていませんが、このレベルでは受信には全く影響がありません。近接でやや大きめのスプリアスがありますが、これも受信には影響は少ないと見ました。


 送信用局発のスペクトラムです。左は30MHzまでの高調波、右はスパン5MHzです。発振周波数が低くなるためか受信用よりもさらにスプリアスが少なくなります。なお、Si5351aの出力インピーダンスは50Ωとなっており、出力レベルも+10dBm程度と大きな電力が得られます(これはソフトウェアで調整できます)。今回は送信出力を1W程度(30dBm程度)とするので、送信回路は2段の増幅で余裕です。


 APB-3で狭帯域スペクトラムを確認しました。左は受信用局発、右は送信用局発でスパン100kHzです。



2017-01-10

 全体の回路図です。キーダウンをPICで読み取ってSi5351aの出力チャンネル(同時に発振のON/OFFも)を切り替えることで送受信を切り替えます。フルブレークインのテスト環境を作り、送受信の切り替えをシミュレートしながら送信用局発の出力を市販無線機でモニターしてみましたが違和感はありませんでした。

回路図を変更しました。サイドトーンはPICのPWMにより生成することにしました。(2017-01-08)

回路図を変更しました。キー入力と送受切り替えをPICを介して行うようにしました。(2017-02-10)



 受信回路を作成しました。いつもとおりランド方式です。5儚僂隆霹弔縫屮蹈奪ごとに実装しています。こうすると回路に問題がある場合はブロック単位で切り分けて対応できるので失敗が少なくなります。アンテナをつないで実際に受信してみました。まず、周波数変更に伴うプチプチ音を確認しました。ロータリーエンコーダーを勢いよく回すとプチプチと聞こえます。聞こえますがあまり気になりません(これは個人の感覚なのであまり参考にならないでしょう)。クリスタルフィルターは、3素子で構成しましたがコンテストなど混みあった環境以外では問題は少ないと思います。3素子としたことで感度の低下が少なく非常に高感度の受信機となりました。AGCが無いので強い局が出てくると爆音となってスピーカー音が歪みます。


 アンテナをつないで空き周波数をモニターしているときに周波数変更したときのプチプチ音の波形です。ロータリーエンコーダーを素早く連続して回してみました。スピーカー出力を見ているので振幅は参考になりませんが、ご覧の通りパルス状のノイズが出ています。この程度ならAFでフィルタリングも可能と思われます(←対応予定はありませんが・・・)。なお、意図的に連続してロータリーエンコーダーを回すとノイズが気になりますが、通常の利用では意識するほどのものではないと思っています。
 

 送信回路も作成しました。Si5351aの出力が+10dBm(10mW)近くあるので、2SK241の前置増幅と2SC2078の終段増幅の2段で余裕で+30dBm(1W)以上になります。5儚僂隆霹1枚に送信回路すべてが実装できます。出力は終段トランジスタのベース抵抗を33Ωから75Ω程度で調整すると200mW弱から1W程度まで変更できます。今回は+30dBm(約1W)としました。


 エレキーをつないでフルブレークインの動作を確認してみました。FT-817で受信してみると受信音にちょっと違和感があります。受信音の先端にノイズがのったような感覚です。送信出力をオシロスコープで確認してみました。”CQ”を打った時の送信波形です。信号の先端でヒゲのようなパルス性のノイズが見られます。この影響でしょうか?。(右の画像は短点を拡大してみました。)



2017-01-22

 参考までにFT-817のキーイング波形を見てみました。立下りは相違は見られませんが、立ち上がりは滑らかです。立ち上がりを拡大してみるとフルパワーになるまで4ms程度かかっています。キークリック音を和らげるために意図的に遅延させていると思われます。


 ソフトウェアで対応できれば良いのですが、今の仕様ではむつかしそうです。送信部の電源の立ち上がりも穏やかにしてみたのですが、フルブレークインの動作に違和感が出ます。キーダウンをPICが読み取ってからsi5351aの出力を切り替えて7MHzの信号出力を行うのですが、この信号出力と送信部電源の立ち上がりが同時に行われており、これが原因となっていると思われます。とりあえずsi5351aの出力に抵抗とコンデンサでスナバ回路みたいなものを追加して入力を穏やかにしてみました。
 立ち上がり部分に見えていたヒゲのようなものはかなり改善されました。FT-817で受信してみるとかなり改善されています。ただ、キークリック音が気になります。7MHzを受信していると同じようなキークリック音が聞こえる局もいますので、この程度なら使えないことはないと思います。



2017-02-10

 やはり、キークリック音が気になります。回路を変更してフルブレークインの動作を見直しました。エレキーなどのキー入力をPICへ直接入力し、送信部への電源供給をPICでコントロールできるようにしました。また、si5351aの周波数変更と送信部への電源供給のタイミングを最適化するようにソフトウェアを書き直しました。また、終段のコンデンサ容量を調整してフルパワーまでの遅延を入れました。これによりキークリック音がかなり改善できました。 


 後は、ケースに入れるだけです。

 PICでのソースコードの問い合わせが何件かありましたので掲載します。MPLAB3.10とXC1.40で作成しました。ソースは、メインプログラムのmain.c、液晶制御のlcd.cとlcd.h、si5351a制御のsi5351a.cとsi5351a.hと別れています。si5351aの出力は2chのみを使用するようにしてあります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
 * 7MHz-QRP-CW tranceiver
 * File:   main.c
 * Author: www.henteko.org
 *
 * Created on 2016/12/25, 19:42
 */

#include <xc.h>
#include <stdio.h>

#include "lcd.h"
#include "si5351a.h"

#pragma config FOSC = IRC
#pragma config WDTEN = OFF
#pragma config FCMEN = OFF
#pragma config PWRTEN = ON
#pragma config BOREN = ON
#pragma config BORV = 30
#pragma config LVP = OFF
#pragma config MCLRE = OFF
#pragma config HFOFST = ON
#pragma config PLLEN = OFF

#define DEBUG    0

#define _XTAL_FREQ  16000000

#define MAX_FREQ    99000000    // max frequency
#define MIN_FREQ    1000000        // min frequency
#define DEF_FREQ    17273800    // default frequency
#define FIX_FREQ    10243800    // IF frequency

unsigned long freq;                    // VFO frequency
unsigned long step;                    // frequency up down step
unsigned char renc_now, renc_old;    // value of rotary encoder
unsigned char mode;                    // 0:normal 1:RIT mode
unsigned char cflag;                // frequency change flag
unsigned char diff;                    // frequency up down flag

void delay_ms(unsigned int t) {
    for(; t > 0; t--)    // 16MHz clock
        __delay_ms(1);    // 1ms: 0.001 / ((1 / (16000000 / 4)) * 1000) = 12
}

void interrupt isr(void) {
    if(INTCONbits.RABIF) {
        if(PORTBbits.RB5 == 1) {
            if(PORTBbits.RB7 == 0)
                renc_now = 0;
            else
                renc_now = 1;
        } else {
            if(PORTBbits.RB7 == 1)
                renc_now = 2;
            else
                renc_now = 3;
        }
        if((renc_now + 3 + 1) % 3 == renc_old)
            diff = 0;
        if((renc_now + 3 - 1) % 3 == renc_old)
            diff = 1;
        renc_old = renc_now;

        INTCONbits.RABIF = 0;
    }
    cflag = 1;
}

void long2comma(unsigned long data, unsigned char keta) {
    int i;
    char buf[10];

    sprintf(buf, "%7ld", data);
    for(i = 0; i < keta; i++) {
        lcd_putch(buf[i]);
        if(i == 0 || i == 3)
               lcd_putch('.');
    }
}

void lcd_update() {
    char buf[10];
    
    if(mode == 0) {
        lcd_gotopos(0, 0);
        long2comma(freq - FIX_FREQ, 6);
        sprintf(buf, "RIT OFF ", step);
        lcd_gotopos(0, 1);
        lcd_puts(buf);
    } else {
        lcd_gotopos(0, 0);
        long2comma(freq - FIX_FREQ, 6);
        sprintf(buf, "RIT ON  ", step);
        lcd_gotopos(0, 1);
        lcd_puts(buf);
    }
}


void main(void) {
    unsigned char sw0_state;
    unsigned int tim;
    unsigned char sendflag;
    unsigned long ftmp;

    OSCCON = 0b11110111;    // 16MHz internal clock

    TRISA = 0b00110000;        // RA4,5 sw input
    TRISB = 0b11110000;        // RB5,7 rotary encoder
    TRISC = 0b00000000;        // LCD control
    ADCON0bits.ADON = 0;    // ad converter off
    ANSEL = 0;
    ANSELH = 0;

    INTCONbits.RABIE = 1;    // PortA,B pin change interrupt enable
    INTCON2bits.RABPU = 0;    // PortA,B pull-up enable
    INTCON2bits.RABIP = 0;    // PortA,B interruput priority low
    WPUB = 0b10100000;        // RB5,7 pull-up
    WPUA = 0b00110000;        // RA3,5 pull-up
    IOCBbits.IOCB5 = 1;        // RB5 pin change interrupt enable
    IOCBbits.IOCB7 = 1;        // RB7 pin change interrupt enable

    // sidetone
    CCP1CONbits.CCP1M = 0b1100;
    T2CONbits.T2CKPS1 = 1;    // timer2 prescaler 1/16
    PIE1bits.TMR2IE = 0;
    TMR2 = 0;    
    PR2 = 250;            // about 1kHz
    CCPR1L = PR2 / 2;    // duty 50%
    T2CONbits.TMR2ON = 0;
    
    sw0_state = 0;
    mode = 0;
    step = 50;
    diff = 0;
    tim = 0;
    cflag = 0;
    sendflag = 0;
    freq = DEF_FREQ;
    
    PORTAbits.RA2 = 0;

    lcd_init();
    lcd_update();
    delay_ms(500);

    i2c_init();
    si5351_init();
       si5351_setfreq(0, freq);
    
    INTCONbits.GIE = 1;        // general interrupt enable

    while(1) {

        // RIT 
        if(PORTAbits.RA5 == 0) {
            sw0_state = 1;
            delay_ms(20);
            tim++;
        }
        if(sw0_state && PORTAbits.RA5 == 1) {
            sw0_state = 0;
            tim = 0;
            if(step == 50) {
                ftmp = freq;
                step = 10;
                mode = 1;
                lcd_update();
            } else {
                freq = ftmp;
                step = 50;
                mode = 0;
                lcd_update();
            }
        }
        
        // change transmit and recive 
        if(PORTAbits.RA4 == 0) {
            if(sendflag == 0) {
                if(mode == 1) {
                    si5351_setfreq(1, ftmp - FIX_FREQ);
                } else {
                    si5351_setfreq(1, freq - FIX_FREQ);
                }
                delay_ms(1);
                T2CONbits.TMR2ON = 1;    // sidetone on
                PORTAbits.RA2 = 1;
                sendflag = 1;
            }
        } else {
            if(sendflag) {
                T2CONbits.TMR2ON = 0;    // sidetone off
                PORTAbits.RA2 = 0;
                si5351_setfreq(0, freq);
                sendflag = 0;
            }
        }

        if(tim > 100) {
            sw0_state = 0;
            tim = 0;
        }

        // frequency changed
        if(cflag) {
            if(diff) {
                if((freq + step) <= MAX_FREQ)
                    freq += step;
            } else {
                if((freq - step) >= MIN_FREQ)
                    freq -= step;
            }
            si5351_setfreq(0, freq);
              lcd_update();
            cflag = 0;
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * File:   lcd.c
 * Author: www.henteko.org
 *
 * Created on 2015/07/20, 11:10
 */


#include "lcd.h"

#define    LCD_STROBE    ((LCD_E = 1), (LCD_E = 0))

unsigned char columns, lines;

void lcd_write(unsigned char c)
{
    if(c & 0x80) LCD_D7=1; else LCD_D7=0;
    if(c & 0x40) LCD_D6=1; else LCD_D6=0;
    if(c & 0x20) LCD_D5=1; else LCD_D5=0;
    if(c & 0x10) LCD_D4=1; else LCD_D4=0;
    LCD_STROBE;
    if(c & 0x08) LCD_D7=1; else LCD_D7=0;
    if(c & 0x04) LCD_D6=1; else LCD_D6=0;
    if(c & 0x02) LCD_D5=1; else LCD_D5=0;
    if(c & 0x01) LCD_D4=1; else LCD_D4=0;
    LCD_STROBE;
    __delay_us(40);
}

void lcd_puts(unsigned char *s)
{
    LCD_RS = 1;
    while(*s) {
        lcd_write(*s++);
    }
}

void lcd_putch(unsigned char c)
{
    LCD_RS = 1;
    lcd_write(c);
/*
        LCD_RS = 1;
    lcd_write(c);
    columns++;
    if(columns == LCD_COL) {
        lines++;
                if(lines == 2) {
            lines = 0;
            lcd_gotopos(0, 0);
        } else {
            lcd_gotopos(0, 1);
        }
    }
*/
}

void lcd_init(void)
{
    __delay_ms(15);
    LCD_RS = 0;
    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_STROBE;
    __delay_ms(5);
    LCD_STROBE;
    __delay_us(100);
    LCD_STROBE;
    __delay_ms(5);
    LCD_D4 = 0;            // 4bit mode
    LCD_STROBE;
    __delay_us(40);
    lcd_write(0x2c);    // 4 bit mode,
    lcd_write(0x08);    // display off
    lcd_clear();
    lcd_write(0x0c);    // display on, blink curson off
    lcd_write(0x06);    // entry mode

    columns = lines = 0;
}

void lcd_gotopos(unsigned char col, unsigned char lin)
{
    LCD_RS = 0;
    if(lin == 0) {
        lcd_write(0x80 + col);
    } else if(lin == 1) {
        lcd_write(0xc0 + col);
    }
    lines = lin;
    __delay_us(40);
}

void lcd_clear(void)
{
    LCD_RS = 0;
    lcd_write(0x1);
    __delay_ms(2);

    columns = lines = 0;
}

void lcd_cursor(unsigned char c)
{
    LCD_RS = 0;
    lcd_write(0x0e);
    __delay_us(40);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* 
 * File:   lcd.h
 * Author: www.henteko.org
 *
 * Created on 2015/07/20, 11:17
 */

#include <xc.h>


#ifndef _XTAL_FREQ
#define _XTAL_FREQ 16000000
#endif

#define LCD_D4 PORTCbits.RC7
#define LCD_D5 PORTCbits.RC6
#define LCD_D6 PORTCbits.RC3
#define LCD_D7 PORTCbits.RC4
#define LCD_RS PORTCbits.RC1
#define LCD_E  PORTCbits.RC0

#define LCD_COL 8
#define LCD_LIN 2

void lcd_init(void);
void lcd_gotopos(unsigned char col, unsigned char lin);
void lcd_clear(void);
void lcd_write(unsigned char c);
void lcd_putch(unsigned char c);
void lcd_puts(unsigned char *s);
void lcd_cursor(unsigned char c);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * File:   si5351a.c
 * Author: www.henteko.org
 *
 * Created on 2016/12/26, 14:19
 */

#include <xc.h>
#include <stdio.h>
#include <plib/i2c.h>
#include "si5351a.h"

void i2c_init()
{
    OpenI2C(MASTER, SLEW_ON);    // i2c master mode, clock 400khz
    SSPADD = 9;                    // _XTAL_FREQ / (SSPADD + 1) * 4 = 400khz
}

void si5351_write(unsigned char reg, unsigned char data)
{
    StartI2C();
    WriteI2C(SI5351_I2C_ADDR);
    WriteI2C(reg);
    WriteI2C(data);
    StopI2C();
}

void si5351_init(void)
{
    si5351_write(SI5351_XTAL_LOAD, 0x80);   // 8pF
}

void si5351_setpll(unsigned char pll, unsigned char mult, unsigned long num, unsigned long denom)
{
    unsigned long P1;
    unsigned long P2;
    unsigned long P3;

    P1 = 128 * mult + (128 * (double)num / denom) - 512;
    P2 = 128 * num - denom * (unsigned long)(128 * (double)num / denom);
    P3 = denom;
    
    si5351_write(pll,     (P3 & 0x0000FF00) >> 8);
    si5351_write(pll + 1, (P3 & 0x000000FF));
    si5351_write(pll + 2, (P1 & 0x00030000) >> 16);
    si5351_write(pll + 3, (P1 & 0x0000FF00) >> 8);
    si5351_write(pll + 4, (P1 & 0x000000FF));
    si5351_write(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
    si5351_write(pll + 6, (P2 & 0x0000FF00) >> 8);
    si5351_write(pll + 7, (P2 & 0x000000FF));
}

void si5351_setms(unsigned char synth, unsigned long div)
{
    unsigned long P1;
    unsigned long P2;
    unsigned long P3;

    P1 = 128 * div - 512;
    P2 = 0;
    P3 = 1;

    si5351_write(synth,     (P3 & 0x0000FF00) >> 8);
    si5351_write(synth + 1, (P3 & 0x000000FF));
    si5351_write(synth + 2, ((P1 & 0x00030000) >> 16));
    si5351_write(synth + 3, (P1 & 0x0000FF00) >> 8);
    si5351_write(synth + 4, (P1 & 0x000000FF));
    si5351_write(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
    si5351_write(synth + 6, (P2 & 0x0000FF00) >> 8);
    si5351_write(synth + 7, (P2 & 0x000000FF));
}

void si5351_setfreq(unsigned char channel, unsigned long freq)
{
    unsigned long div;        // synth divider value
    unsigned long pllfreq;    // target PLL frequency
    unsigned char mult;        // multisynth a
    unsigned long num;        // multisynth b
    unsigned long denom;    // multisynth c
    unsigned long lltmp;    // temporary value

    div = SI5351_PLL_FREQ / freq;     
    div = div>>1<<1;                // synth divider value is even integer
    pllfreq = div * freq;            
    denom = 0xfffff;                // 20bit denominator max value 
    mult = pllfreq / SI5351_XTAL_FREQ;    
    lltmp = pllfreq % SI5351_XTAL_FREQ;
    num  = lltmp * ((double)denom / SI5351_XTAL_FREQ);
  
    si5351_write(SI5351_OUTPUT_CTRL, 0xff);
    // si5351_write(SI5351_CLK0_CTRL, 0x80);
    // si5351_write(SI5351_CLK1_CTRL, 0x80);
    
    if(channel == 0) {
        si5351_setpll(SI5351_PLL_A, mult, num, denom);
        si5351_setms(SI5351_MS_0, div);
        si5351_write(SI5351_PLL_RESET, 0xac);    
        si5351_write(SI5351_CLK0_CTRL, 0x4f);
    } else {
         si5351_setpll(SI5351_PLL_B, mult, num, denom);
        si5351_setms(SI5351_MS_1, div);
        si5351_write(SI5351_PLL_RESET, 0xac);    
        si5351_write(SI5351_CLK1_CTRL, 0x6f);
    }
    si5351_write(SI5351_OUTPUT_CTRL, 0x00);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * File:   si5351a.h
 * Author: www.henteko.org
 *
 * Created on 2016/12/25, 20:12
 */

#define SI5351_I2C_ADDR     0xc0

#define SI5351_XTAL_FREQ    25000000
#define SI5351_PLL_FREQ     900000000

#define SI5351_OUTPUT_CTRL  3
#define SI5351_CLK0_CTRL    16
#define SI5351_CLK1_CTRL    17
#define SI5351_CLK2_CTRL    18
#define SI5351_PLL_A        26
#define SI5351_PLL_B        34
#define SI5351_MS_0         42
#define SI5351_MS_1         50
#define SI5351_MS_2         58
#define SI5351_PLL_RESET    177
#define SI5351_XTAL_LOAD    183

void i2c_init();
void si5351_init();
void si5351_setfreq(unsigned char channel, unsigned long freq);

▲ページ Top へ...