////////////////////////////////////////////////////////// // 市販DDSユニットを使った周波数スイープメータ // 機能 //  任意の周波数の正弦波出力(10Hzから10MHz) //  PICのUSARTによるパソコンからのリモコン //  ロータリースイッチによる周波数マニュアル設定 //  2チャンネルのログアンプによるdB計測 //  自動と手動のスイッチ切り替え //  出力周波数と計測dB値の液晶表示 ////////////////////////////////////////////////////////// #include <16f876.h> #device ADC=10 //10ビットモード指定 #include #use delay (CLOCK=10000000) //クロック10MHz #use fixed_io(C_OUTPUTS=PIN_C0,PIN_C1,PIN_C2,PIN_C6) #use fast_io(B) // コンフィギュレーションの設定 #FUSES HS,NOWDT,NOPROTECT,PUT,BROWNOUT // USARTの使用宣言 #use rs232(BAUD=9600,XMIT=PIN_C6, RCV=PIN_C7) // 液晶表示ライブラリのインクルード #include // 定数宣言 #define ddsSck PIN_C2 //周波数設定用のクロック #define ddsStb PIN_C0 //周波数データラッチ用トリガ #define ddsData PIN_C1 //周波数データ出力ピン #define Sw0 PIN_C4 //ロータリースイッチ左右判定 #define Sw1 PIN_C5 //ロータリースイッチトリガ #define ModeSW PIN_C3 //自動/手動切り替え #define ddsCmd 0x0067 //DDSへのコマンド static char buffer[10]; //RS232用バッファ static long freq_up,freq_low; //出力周波数範囲 static int Latch; //ロータリースイッチ用フラグ ////////  関数プロトタイプ定義 void Mesure(void); //dB計測関数 void setFreq(long F_up, long F_low); //周波数設定値演算関数 shift_out(long freq,int cnt); //DDS設定出力関数 long ad_input(int chanl); //A/D Sub Function void Mupdown(void); //手動周波数アップダウン関数 ///////// メイン関数 ///////// main() { int pcCmd; //受信コマンド格納変数 set_tris_c(0xB0); //PORT C設定 output_high(ddsStb); //DDS strobe set_tris_b(0); //PORT B 全出力モード set_tris_a(0xFF); //PORT C 全入力モード ////// A/Dコンバータの初期化 setup_adc(ADC_CLOCK_DIV_32); //Fosc32 full speed setup_adc_ports(ANALOG_RA3_REF); //RA3がRef+  RA0,1がA/D ////// 液晶表示器の初期化 スタートメッセージ表示 lcd_init(); //initialize LCD printf(lcd_data,"Start Log Meter!"); lcd_cmd(0xC0); //No2 Line if(input(ModeSW)) printf(lcd_data,"Manual Mode"); //Manual Mode else printf(lcd_data,"Remote Mode"); //Auto Mode delay_ms(1000); //1秒間だけ表示 lcd_clear(); //表示クリア //// 初期値セット Latch = 0; freq_low = 10; //周波数最低値10Hz freq_up = 0; ////// メイン処理部 while(1) { if (input(ModeSW)) { //手動か自動か? ////// 手動の場合の処理 if (input(Sw1)) { //ロータリースイッチテスト delay_ms(2); //2msecディレイ if (input(Sw1)){ //再確認 Mupdown(); //周波数アップダウン出力 Mesure(); //dB計測表示 } } else Latch = 0; // ラッチ解除 } else { //// 自動の場合の処理 gets(buffer); //データ受信 pcCmd = atoi(buffer); //コマンド数値に変換 switch(pcCmd) //各処理に分岐 { case 0: printf(lcd_data,"Initialize"); //初期化表示 break; case 1:{ gets(buffer); //周波数値上位 freq_up = atol(buffer); //整数に変換 gets(buffer); //周波数値下位 freq_low = atol(buffer); //整数に変換 setFreq(freq_up, freq_low); //周波数設定出力 break; } case 2: Mesure(); //dB計測、表示、転送 break; default: printf(lcd_data,"Cmd Error?"); //コマンドエラー表示 break; } } } } ///////////// サブ関数ライブラリ //////////// 手動周波数アップダウン関数 void Mupdown(void) { float frequency, Diff; //周波数、差分変数 if (Latch == 0) { //ラッチ解除待ち Latch = 1; //ラッチセット //// 現在周波数値から増分を決める frequency=65536 *(float)(freq_up) + (float)(freq_low); if (frequency < 100) Diff = 1; //増分 1Hz else { if (frequency < 1000) Diff = 10; //増分 10Hz else { if (frequency < 10000) Diff = 100; //増分 100Hz else { if (frequency < 100000) Diff = 1000; //増分 1kHz else { if (frequency < 1000000) Diff = 10000; //増分 10kHz else { if (frequency < 20000000) Diff = 100000; //増分 100kHz } } } } } ///// 周波数増減演算 if (input(Sw0)){ //左右回転方向テスト frequency =frequency - Diff; //左周り 減算 if (frequency < 10) frequency = 10; //最低値 10Hz } else { frequency=frequency + Diff; //右回り 加算 if(frequency > 16000000) frequency = 16000000; //最高値 16MHz } ///// 周波数設定 freq_up = (long)(frequency/65536); //上位 freq_low = (long)(frequency-65536*(float)freq_up); //下位 setFreq(freq_up, freq_low); //周波数設定 } } ////////// dB計測関数 void Mesure(void) { long adConv0,adConv1; //A/D読み込み値 float logData0,logData1; //dB値 adConv0 = ad_input(0); //チャネル0読み込み logData0 = adConv0; logData0 = (95*logData0) / 1024 - 68; //dBに変換(IC特性値) adConv1 = ad_input(1); //チャネル1読み込み logData1 = adConv1; logData1 = (95*logData1) / 1024 - 68; //dB値に変換 printf("%2.4f,%2.4f\r\n",logData0,logData1); //PCにdB値転送 lcd_cmd(0xC0); //液晶2行目指定 printf(lcd_data," %2.2f %2.2f ",logData0,logData1); //液晶にdB値表示 } //////// A/D変換読み込み関数 long ad_input(int chanl) { long adData; //10ビットモード set_adc_channel(chanl); //チャンネル指定 delay_us(50); //充電待ち adData = read_adc(); //データ入力 return(adData); //データ返し } ////////// 周波数設定出力関数 void setFreq(long F_up, long F_low) { float frequency; //周波数値 lcd_cmd(0x02); //液晶1行目指定 frequency=65536 *(float)(F_up) + (float)(F_low) + 1; printf (lcd_data,"f=%8.0f ",frequency); //設定データ表示 ////// DDSへシリアル出力 shift_out(ddsCmd,7); //DDSコマンド出力 shift_out(F_low,16); //下位16ビット分出力 shift_out(F_up,10); //上位10ビット分出力 output_low(ddsStb); //ラッチストローブ output_high(ddsStb); } //////// DDSへシリアル出力制御関数 shift_out(long freq,int cnt) //データとビット数 { int i; long temp; temp = freq; //周波数値退避 for (i=0; i> 1; output_high(ddsSck); //Shift Clockの出力 output_low(ddsSck); } }