AD9833を使ってDDSを作ってみたいと思うシリーズ1。
今回は、ソフトとPICの通信までやろうと思います。
詳しい通信内容などは面倒なので次回にしようと思います。
やりたいこと
- DDSを作る
DDSを作るといっても、通信目的には使用しないのでまあ大体正弦波ならいいかなっていう、ゆるーい気持ちで作ります。
また、少し前まではボタンとLCDを使って周波数を表示したり…。と考えていましたが、だんだん面倒になってきたので、PCによる制御にしようと思います。
PCで制御すれば回路規模が小さくなるのでGood!
そのための事前演習となります。
今回はPICと通信し、自作したソフト側に用意したボタンを押すと、LEDが光ったり消えたりするみたいなプログラムを作ります。
(正確にはPCから’a’が送信されると点灯し、’b’が送信されると消灯。のような動作です)
ソフト制作
今回は、シリアルポートを使います。
頑張れば.NET 7でも出来ますが、自分で設定しないといけなくなるので、今回は.NET Framework 4.8を使用します。
(詳しいことはよくわかりませんが、.NETFramework4.8だとOSのライフサイクルポリシーに従うらしいのでまだまだサポート対象です)
通信速度は 9600bps
ハンドシェイクやパリティ設定はOFFにしました。
(送受信に失敗した場合の対処はソフトウェア側で行います)
昔、シリアルポートを使った自作ソフトを作った気がするのですが、もう忘れました。
ということで、まずは簡単な実験からやります。
回路
前回とほぼ変わっていない
回路にUART-RS232C変換回路やブレッドボード用電源などは省略してあります。
詳しい記事は下をご覧ください。
自作しなくても、下に貼り付けた商品でも代用可能です。
実験 PC側でPICのポート操作
こんな感じでLEDとUART-RS232C変換基板を設け、接続しておきます。
(左側に刺さっている基板は関係ありません)
こんな感じで適当にソフトを作り、
こんなプログラムを書き込みます。(それぞれボタンに割り当てています)
ちなみに実用化させるとすれば、ポートが開いているかなど最低限のチェックはした方がいいと思います。
今回は、テストなのでこれでいきます。
PIC側のプログラムは下に乗っけておきます。
動作
あっけなく動作しました。
(まあ、前回苦労しただけあって当たり前ですが)
今回、写真を撮り忘れました。すみません。
ちなみにSerialport.Writeから送信される文字データはそのままのようです。
てっきり最後にNULL文字とか改行が付与されるのかと思っていました。(考えすぎか)
余談(記事とは関係ないです)
ほかの袋麺のほうがおいしいのに、なぜかチキンラーメンが無性に食べたくなりました。
…。一口目はすごくおいしい。
でも3口目くらいからもういいや。ってなりました。
なんか不思議な袋麺ですよね。(個人的な感想です)
こんなに買っても消費できないです…。150食分って…。
PICのプログラムソース(参考)
結構雑な作りなので、参考程度にどうぞ。
/*
* File: newmain.c
* Project: PIC16F18346-UART_TEST
*/
// CONFIG1
#pragma config FEXTOSC = OFF // 外部オシレータ無効
#pragma config RSTOSC = HFINT32 // 起動直後32MHz有効
#pragma config CLKOUTEN = OFF // クロック信号出力無効
#pragma config CSWEN = ON // クロックスイッチ有効
#pragma config FCMEN = ON // フェイルセーフクロック有効
// CONFIG2
#pragma config MCLRE = OFF // MCLRピン無効
#pragma config PWRTE = OFF // パワーアップタイマ無効
#pragma config WDTE = OFF // WDT無効
#pragma config LPBOREN = OFF // ローパワーBOR無効
#pragma config BOREN = ON // BOR有効
#pragma config BORV = LOW // BORロー電圧
#pragma config PPS1WAY = OFF // PPSLOCK1度のみ無効
#pragma config STVREN = ON // スタック・アンダーオーバーフローリセット有効
#pragma config DEBUG = OFF // デバッグ無効
// CONFIG3
#pragma config WRT = OFF // メモリ書き込み保護無効
#pragma config LVP = OFF // 低電圧書き込みモード無効
// CONFIG4
#pragma config CP = OFF // CPメモリ読み出し保護無効
#pragma config CPD = OFF // CPDメモリ読み出し保護無効
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 32000000
/*
* RC1:UART TX
* RC2:UART RX
*/
void UART_print(char moji[50]);
//グローバル宣言
unsigned char UART_flag = 0;
int main(int argc, char** argv) {
OSCCON1 = 0x00; //32MHz
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00; //デジタル入出力
TRISCbits.TRISC1 = 0;
TRISCbits.TRISC2 = 1;
TRISCbits.TRISC3 = 0;
//PPS設定
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCKED = 0;
RC1PPS = 0x14; //RC1 -> UART TX
RXPPS = 0x12; //UART RX -> RC2
//UART設定
TX1STA = 0x20; //UARTモード BRGH = 0;
RC1STA = 0x90; //シリアルモード有効 8bitモード
BAUD1CON = 0x00;
SP1BRG = 51; //9600bps速度
PIE1bits.RCIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
UART_print("PIC16F18346 UART Test Program\r\n");
UART_print("\r\n");
while (1) {
}
return (EXIT_SUCCESS);
}
void __interrupt() isr() {
if (PIR1bits.RCIF) {
if(RC1STAbits.OERR || RC1STAbits.FERR){
//エラー検知
RC1STA = 0x90;
return;
}
switch (RC1REG) {
case 'a':
LATCbits.LATC3 = 1;
break;
case 'b':
LATCbits.LATC3 = 0;
break;
}
PIR1bits.RCIF = 0;
}
}
void UART_print(char moji[50]) {
int i = 0;
while (moji[i] != '\0') {
TX1REG = moji[i];
while (!TX1STAbits.TRMT) {
};
i++;
}
}
おわり。