電子工作を行う上で、ある程度の計測器が必要になります。
今回は信号発生器を作りました。ファンクションジェネレーターです。 【はじめに】 テスターは買うしかないです。電圧可変の安定化電源は簡単に作れますな。 オシロはヤフオクとかで安い中古の物を入手できます。 回路図CADとかを動かすパソコンもwinxp出たての頃の中古品が数千円で買えます。 さて、オシロを入手したら、信号発生器があれば便利です。世の中には色々な方式の信号発生器がありますが、良くある方式じゃなくて面白い構成にチャレンジしてみました。頭の体操も兼ねた訳です。 【構成】 どういう方式を選択したかの考察は省きますが、下図の様な構成で作りました。 PIC16F84Aを信号発生器にしますが、DDSじゃなくてクロック周波数をLTC1799で可変するという禁じ手の方法です。表示はPIC16F648Aでやってみました。 ちょっと間違って図ではLT1799ですが正しくはLTC1799です。 使用したPICの品種は手持ちの物を消費する為に選択しました。最適じゃないです。 波形選択の所の4bitカウンタですが、使っているうちに面倒になったのでロータリー式のディップスイッチに変更したままです。 4bitパラレルにした理由は16F84Aの動作がLTC1799の周波数に依存しシリアル入力が不可だからです。 16F648Aの方も面倒なので同じ設定で動かせるパラレル入力にしました。 LTC1799とかほとんどの部品は秋月で入手できます。 電源はノイズが出ない様にデカップリングとか定電圧回路をしっかり作ります。 【動作】 16F84AはポートBの波形をループで出力するだけです。 通常は「波形反映」でリセットされ、最初に読んだ「波形選択」のビットに応じて 正弦波とかノコギリ波を出力します。 ただしパルス波形を選択した時は「波形選択」のビットでパルス幅が可変可能。 表示の方も「波形/デューティ」をLOにしてパルス幅を画面に出します。 16F648Aは周波数カウンタと、波形名称の画面表示、パルス幅の表示です。 【回路図】 縮小され見にくいですが、このブログは画像のクリックで原寸表示する様です。 【16F648A側のソース】 ちょっと長いですがそこは勘弁して下さい。 このブログはタブが消える様で、しょうがなく全角スペースに置き換えています。 あとこのブログでは<lcd_lib_port_a0-a3.c>を半角の<>にすると非表示? CCSのコンパイラを使ってます。 LCDドライバは有名な後閑さんのやつが元で、ポート変更して使ってます。 以下はソースです。 // //周波数カウンタ // #include <16f648a.h> #fuses HS,NOWDT,NOPROTECT,PUT,NOLVP,NOMCLR #use delay(clock=10000000) #define mode 0 #define input_x input_A //3つともポートAにしてください。 #define output_x output_A #define set_tris_x set_tris_A #define stb PIN_B4 #define rs PIN_B5 #include <lcd_lib_port_a0-a3.c> //A0〜A3ポート用のLCDドライバ #byte bport=6 long f_count=0; int i=0,j,k=19; float freq; #int_timer0 //内部クロックのカウント void int_count() { k--; if(k==0) { f_count=get_timer1(); j=i; set_timer1(0); i=0; k=19; } } #int_timer1 //外部入力パルスのカウント void ext_count() { i++; } void main() { byte n; // ポートBをバイトごと読む set_tris_b(0x4f); //入力端子設定 set_tris_a(0x10); lcd_init(); //LCD初期化 lcd_clear(); //LCD全消去 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); set_timer0(0); setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); set_timer1(0); enable_interrupts(int_timer0); enable_interrupts(int_timer1); enable_interrupts(GLOBAL); while (1) { freq=(f_count+j*65536)*2.0077354; //周波数計算 //10MHz÷4÷256÷256÷19=2.0077354 lcd_cmd(0xC0); //2行目の先頭へ printf(lcd_data,"%9.1fHz ",freq); delay_ms(200); n=(~bport & 0x0f); // nに代入。ポートBの反転とビットマスク lcd_cmd(0x02); //1行目の先頭へ if(input(pin_A4)) //ポートA4がHIなら波形名の表示 { if(n==1) printf(lcd_data,"sinwave 6step "); if(n==2) printf(lcd_data,"sinwave 18step "); if(n==3) printf(lcd_data,"sinwave 33step "); if(n==4) printf(lcd_data,"sinwave 66step "); if(n==5) printf(lcd_data,"sinwave 132step "); if(n==6) printf(lcd_data,"sawwave 4step "); if(n==7) printf(lcd_data,"sawwave 8step "); if(n==8) printf(lcd_data,"sawwave 16step "); if(n==9) printf(lcd_data,"sawwave 32step "); if(n==10) printf(lcd_data,"sawwave 64step "); if(n==11) printf(lcd_data,"sawwave 128step "); if(n==12) printf(lcd_data,"sawwave 256step "); if(n==13) printf(lcd_data," pulse _|_|_"); if(n==14) printf(lcd_data," pulse -|-|-"); if(n==15) printf(lcd_data," burst -4-4-"); if(n==0) printf(lcd_data,"random noise "); } else //ポートA4がLOならパルス幅の表示 { printf(lcd_data,"%u ",n); // パルス幅設定を上書き表示 // } } } 【16F84A側のソース】 テーブルを作ってループさせるだけです。 ポイントは乱数発生の所です。けっこう苦労しました。 // 16f84A波形発生器 // #include <16f84a.h> #fuses HS,NOWDT,NOPROTECT // HSとする。RCだと25MHz以上で不安定 #use delay(clock=20000000) #byte bport=6 #byte aport=5 void main() { byte j; //ポートAをバイトごと読む int i=0,m; set_tris_A(0x0f); // ポートA0〜3は入力。ポートA4は出力 set_tris_B(0x00); // ポートBは全出力 j=(~aport & 0x0f); // jに代入。ポートAの反転とビットマスク output_high(pin_A4); if(j==2) // j が1ならsine1までスキップ goto sine2 ; if(j==3) goto sine3 ; if(j==4) goto sine4 ; if(j==5) goto sine5 ; if(j==6) { i=64; //階段の高さ(インクリメントの数値) goto sawwave ; } if(j==7) { i=32; //数値がでかいと255まで上がるのが早い goto sawwave ; } if(j==8) { i=16; //数値が小さいと255までちょっとずつ上がる goto sawwave ; } if(j==9) { i=8; goto sawwave ; } if(j==10) { i=4; goto sawwave ; } if(j==11) { i=2; goto sawwave ; } if(j==12) { i=1; goto sawwave ; } if(j==13) { output_low(pin_A4); goto pulse1 ; } if(j==14) { output_low(pin_A4); goto pulse2 ; } if(j==15) { output_low(pin_A4); goto burst ; } if(j==0) goto noisewave ; // sine1 : ; while(1) //テーブルをループしているだけ { bport=64 ; bport=191 ; bport=255 ; bport=191 ; bport=64 ; bport=0 ; } sine2 : ; while(1) { bport=8 ; bport=30 ; bport=64 ; bport=105; bport=150 ; bport=191 ; bport=225 ; bport=247 ; bport=255 ; bport=247 ; bport=225 ; bport=191 ; bport=150 ; bport=105 ; bport=64 ; bport=30 ; bport=8 ; bport=0 ; } sine3 : ; while(1) { bport=5 ; bport=14 ; bport=27 ; bport=44 ; bport=64 ; bport=86 ; bport=109 ; bport=134 ; bport=158 ; bport=180 ; bport=201 ; bport=220 ; bport=235 ; bport=246 ; bport=253 ; bport=255 ; bport=253 ; bport=246 ; bport=235 ; bport=220 ; bport=201 ; bport=180 ; bport=158 ; bport=134 ; bport=109 ; bport=86 ; bport=64 ; bport=44 ; bport=27 ; bport=14 ; bport=5 ; bport=0 ; } sine4 : ; while(1) { bport=1 ; bport=2 ; bport=5 ; bport=9 ; bport=14 ; bport=20 ; bport=27 ; bport=35 ; bport=44 ; bport=54 ; bport=64 ; bport=75 ; bport=86 ; bport=97 ; bport=109 ; bport=121 ; bport=134 ; bport=146 ; bport=158 ; bport=169 ; bport=180 ; bport=191 ; bport=201 ; bport=211 ; bport=220 ; bport=228 ; bport=235 ; bport=241 ; bport=246 ; bport=250 ; bport=253 ; bport=254 ; bport=255 ; bport=254 ; bport=253 ; bport=250 ; bport=246 ; bport=241 ; bport=235 ; bport=228 ; bport=220 ; bport=211 ; bport=201 ; bport=191 ; bport=180 ; bport=169 ; bport=158 ; bport=146 ; bport=134 ; bport=121 ; bport=109 ; bport=97 ; bport=86 ; bport=75 ; bport=64 ; bport=54 ; bport=44 ; bport=35 ; bport=27 ; bport=20 ; bport=14 ; bport=9 ; bport=5 ; bport=2 ; bport=1 ; bport=0 ; } sine5 : ; while(1) { bport=0 ; bport=0 ; bport=1 ; bport=1 ; bport=1 ; bport=2 ; bport=4 ; bport=5 ; bport=7 ; bport=9 ; bport=12 ; bport=14 ; bport=17 ; bport=20 ; bport=24 ; bport=27 ; bport=31 ; bport=35 ; bport=40 ; bport=44 ; bport=49 ; bport=54 ; bport=59 ; bport=64 ; bport=69 ; bport=75 ; bport=80 ; bport=86 ; bport=92 ; bport=97 ; bport=103 ; bport=109 ; bport=115 ; bport=121 ; bport=128 ; bport=134 ; bport=140 ; bport=146 ; bport=152 ; bport=158 ; bport=163 ; bport=169 ; bport=175 ; bport=180 ; bport=186 ; bport=191 ; bport=196 ; bport=201 ; bport=206 ; bport=211 ; bport=215 ; bport=220 ; bport=224 ; bport=228 ; bport=231 ; bport=235 ; bport=238 ; bport=241 ; bport=243 ; bport=246 ; bport=248 ; bport=250 ; bport=251 ; bport=253 ; bport=254 ; bport=254 ; bport=254 ; bport=255 ; bport=255 ; bport=255 ; bport=254 ; bport=254 ; bport=254 ; bport=253 ; bport=251 ; bport=250 ; bport=248 ; bport=246 ; bport=243 ; bport=241 ; bport=238 ; bport=235 ; bport=231 ; bport=228 ; bport=224 ; bport=220 ; bport=215 ; bport=211 ; bport=206 ; bport=201 ; bport=196 ; bport=191 ; bport=186 ; bport=180 ; bport=175 ; bport=169 ; bport=163 ; bport=158 ; bport=152 ; bport=146 ; bport=140 ; bport=134 ; bport=128 ; bport=121 ; bport=115 ; bport=109 ; bport=103 ; bport=97 ; bport=92 ; bport=86 ; bport=80 ; bport=75 ; bport=69 ; bport=64 ; bport=59 ; bport=54 ; bport=49 ; bport=44 ; bport=40 ; bport=35 ; bport=31 ; bport=27 ; bport=24 ; bport=20 ; bport=17 ; bport=14 ; bport=12 ; bport=9 ; bport=7 ; bport=5 ; bport=4 ; bport=2 ; bport=1 ; bport=1 ; bport=1 ; bport=0 ; } sawwave : ; while(1) { bport=bport+i; } pulse1 : ; while(1) { bport=255; bport=0; j=(~aport & 0x0f); m=j+1; //バイトjによってパルス幅設定する while(m>1) { m--; delay_us(1); } } pulse2 : ; while(1) { bport=255; bport=1; bport=127; j=(~aport & 0x0f); m=j+1; while(m>1) { m--; delay_us(1); } } burst : ; while(1) //トーンバーストのテーブル { bport=134 ; bport=158 ; bport=180 ; bport=201 ; bport=220 ; bport=235 ; bport=246 ; bport=253 ; bport=255 ; bport=253 ; bport=246 ; bport=235 ; bport=220 ; bport=201 ; bport=180 ; bport=158 ; bport=134 ; bport=109 ; bport=86 ; bport=64 ; bport=44 ; bport=27 ; bport=14 ; bport=5 ; bport=1 ; bport=5 ; bport=14 ; bport=27 ; bport=44 ; bport=64 ; bport=86 ; bport=109 ; bport=134 ; bport=158 ; bport=180 ; bport=201 ; bport=220 ; bport=235 ; bport=246 ; bport=253 ; bport=255 ; bport=253 ; bport=246 ; bport=235 ; bport=220 ; bport=201 ; bport=180 ; bport=158 ; bport=134 ; bport=109 ; bport=86 ; bport=64 ; bport=44 ; bport=27 ; bport=14 ; bport=5 ; bport=1 ; bport=5 ; bport=14 ; bport=27 ; bport=44 ; bport=64 ; bport=86 ; bport=109 ; bport=134 ; bport=158 ; bport=180 ; bport=201 ; bport=220 ; bport=235 ; bport=246 ; bport=253 ; bport=255 ; bport=253 ; bport=246 ; bport=235 ; bport=220 ; bport=201 ; bport=180 ; bport=158 ; bport=134 ; bport=109 ; bport=86 ; bport=64 ; bport=44 ; bport=27 ; bport=14 ; bport=5 ; bport=1 ; bport=5 ; bport=14 ; bport=27 ; bport=44 ; bport=64 ; bport=86 ; bport=109 ; bport=134 ; bport=158 ; bport=180 ; bport=201 ; bport=220 ; bport=235 ; bport=246 ; bport=253 ; bport=255 ; bport=253 ; bport=246 ; bport=235 ; bport=220 ; bport=201 ; bport=180 ; bport=158 ; bport=134 ; bport=109 ; bport=86 ; bport=64 ; bport=44 ; bport=27 ; bport=14 ; bport=5 ; bport=1 ; bport=5 ; bport=14 ; bport=27 ; bport=44 ; bport=64 ; bport=86 ; bport=109 ; bport=127 ; j=(~aport & 0x0f); m=(j+1)*2; while(m>1) { m--; delay_us(20); } } noisewave : ; while(1) { bport=3*bport+121; // 擬似乱数1 swap(bport); // 上下ビット入れ替えで乱雑度アップ i=3*i+111; // 擬似乱数2 swap(i); bport=bport^i; // 2つの擬似乱数のxorを行い乱雑度アップ } } 【注意事項】 真似て作らないで下さい。当方は何の保証も致しません。 【予告】 次回は実際に作ったものを検証してみます。 以上です。 。
by ca3080
| 2013-01-24 18:02
| 電子工作(一般)
|
カテゴリ
全体 オーディオ&電子工作 ┗電子工作(一般) 修理等 節約生活 節約レシピ ┣和食系 ┣洋食関連 ┣中華食堂的 ┣異国風味 ┣ひそかに食べる系 ┗のみもの 野菜作り 与太話 ┗さよならの向う側 業務連絡 AdSense進捗 緊急連絡用コメント欄 タグ
DAC(39)
アナログレコード機器(36) ヘッドフォンアンプ(31) アホアホ計測機器(25) ミニアンプ(19) ヘッドホン改造(16) ノイズ対策(13) 抵抗の音、ATT(10) スイッチング電源(8) APB-3(7) 音質改善ネタ(7) ソーラー、LED、電池(6) コンデンサの音と使い方(6) 考察[mp3,wav,DSD…(6) トランジスタの音質(4) 当方の現状
YouTubeチャンネルは閉鎖しますた
↓当方運営の古銭サイト ㋺ 謎の珍品古銭 ㋺ 他のSNS等は不使用です Google AdSenseもうダメぽ。アドセンス閉鎖😭 現在までライセンス供与 および他の方や団体との 提携など一切ありません 知人友人や師弟も無し 今まで物品販売も無し 当ブログの各ページにつ いて引用元urlを明示し 正しく引用される場合は 問題ありません 無許可の商用利用は禁止 無許可の頒布利用も禁止 許可を与えた事例は無し パクる人とは関わり合いたくありません 最近高音質化ネタを投稿しない理由は俺のせいじゃないのよね ネタは沢山あるけどパックラーが跋扈する状況で新規ネタの公開はちょっと無理 誠実なご利用をお願いします 皆さん! 知ったかパクり先生に 騙されんなよ!(爆) 記事ランキング
最新の記事
以前の記事
|
ファン申請 |
||