マイコン、初心者です。表題のターゲットボードを使用し、AD9833(信号発生器)にて信号を出力してみたいと思いいざ、プログラムを書いて実行してみるとまったく動いている気配がありません。クロック設定などはtargetboard for RX65N のボードサプライパッケージ?をダウンロードし使用しています。何が足りないのか、いろいろ分からないなりに調べつつ試している最中ですが動く気配がなく困っております、、汗何か、とんでもない欠陥や見落としがあると思うのですが、、どなたか、教えてください。コードとクロック設定やデバック構成などのスクショを添付しました。/cfs-file/__key/communityserver-discussions-components-files/395/rxdeAD9938.txt
わわいです
そのボードに添付されているサンプルソフトは動くんでしょうか。
それが動かない、ということであれば、そのボードの不良ってことが疑われるでしょう。
そうでないなら、あなたが組んだプログラムというものが、不完全ということになろうかと思われます。
クロックの設定ですが、CPUを16MHzで動かす設定としているので、ちょっともったいないかと思います。
設定は一例ですが、PLLを使うと、HOCOベースで120MHz動作とする事が出来ます。
クロック設定を、スマートコンフィグレータで行っている場合は、
#include "r_smc_entry.h"
#include <math.h>
#include <stdint.h>
r_smc_entry.h をインクルードするのがお勧めです。(スマートコンフィグレータでモジュールを追加した際は、左記のファイルをインクルートしておけば、スマートコンフィグレータのAPI関数が普通に使えます。)
「動く気配がない」のレベルが判らないのですが、貼り付けられているファイルをコピペして、ビルド&デバッガツールにダウンロードしましたが、
resetprg.c内でブレークして、緑の矢印を押すと、
メイン関数に飛んできたので、ステップ実行や変数値をモニタする事でデバッグ可能かと思います。
(動作の期待値と、どのレベルで止まっているのかが判らないので、イマイチ何を言えば良いのか?です)
(1)コンパイル・ビルドエラーが出る
(2)デバッガ接続ができない
(3)期待した動作にならない
→私がコピペで実行する限りでは、(2)まではクリアしています。(3)は、手元にAD9833にアクセス出来る環境がないので、こちらでは動作を見られません。
ぱっとソースを見て言えることは、PFSレジスタの設定を行っていますが、PFS設定の前にプロテクトレジスタ解除
MPC.PWPR.BIT.B0WI = 0; MPC.PWPR.BIT.PFSWE = 1;
が必要です(どこかで行っていれば良いのですが。)
回答ありがとうございます。サンプルソフトは動きました。LEDを点滅させるものです。こちらいろいろ、プログラムを修正してみると、今度は70hzくらいの矩形波が出てきました。(出したいのは2khzの三角波)AD9833の仕様としてVccに電源を接続するだけ(SPIインタフェースでデータを設定しなくとも)で、「xx」MHz(xxはモジュールによって異なるみたいです)のサイン波が発生できます。ですが、出たのは矩形波です(苦笑)なんらかの信号は送れたのか、、、おっしゃる通りコードが不完全ということだと思いますので1から見直してみます。
早速のご返答ありがとうございますまず、クロック設定に関してアドバイスありがとうございます。近くにRXマイコンに関して伺える方がいないので非常に為になります!r_smc_entry.h インクルードしてみます。
私の方でも、デバックを起動まではなんとか行えているのですが、期待した動作にならないのです。2khzの三角波を期待しているのですが、デフォルトのサイン波がでます。(AD9833はVccとGndを繋ぐだけで、xxHzのサイン波がでます)また少しコードを修正してみて実行してみるとなぜか矩形波がでます(苦笑)SPI通信も初めて扱うので何か誤った設定をしているかもしれないです。AD9833に送るコマンドやAD9833の仕様(特に通信周りの理解に自信がない)を何か勘違いしているかもしれないので、そこを勉強、再確認してみます。PFS設定に関して、見落としていました、、、こちらも反映してみます。ご丁寧にありがとうございました。
AD9833のMCLKにクロックは供給されていますか?MCLKにクロック供給される回路構成のモジュール基板なら問題ないです。
ご回答ありがとうございます。はい、MCLKに水晶?から25Mhzクロック供給されるタイプのものです。こちらを使用しています。
tfさま進展がありました。ようやく、三角波、2khzを出力できました。前回と修正した点はtfさまにアドバイスいただいた以下を追加したのと、確実に送信完了したかを確認する文を追加しました。MPC.PWPR.BIT.B0WI = 0; MPC.PWPR.BIT.PFSWE = 1;MPC.PA5PFS.BYTE = 0x0D; // RSPCKA MPC.PA6PFS.BYTE = 0x0D; // MOSIA本当にありがとうございました。
//ビットレートは1Mbps/8 //SPI2 #include "r_smc_entry.h" /* 定数定義 */ #define FSYNC_LOW() (PORTC.PODR.BIT.B0 = 0) #define FSYNC_HIGH() (PORTC.PODR.BIT.B0 = 1) const float REF_FREQ = 25000000UL; // AD9833の基準クロック(25MHz) /* 波形タイプ */ typedef enum { SINE_WAVE = 0x2000, // 正弦波 TRIANGLE_WAVE = 0x2022, // 三角波 SQUARE_WAVE = 0x2028 // 矩形波 } AD9833_WaveType; /* プロトタイプ宣言 */ void init_SPI(void); void WriteRegister(uint16_t data); void AD9833reset(void); void AD9833setFrequency(uint32_t frequency, AD9833_WaveType waveform); void init_SPI(void) { /* モジュールストップ解除 */ SYSTEM.MSTPCRB.BIT.MSTPB17 = 0; /* ピン設定: RSPCKA、MOSIA */ MPC.PWPR.BIT.B0WI = 0; MPC.PWPR.BIT.PFSWE = 1; MPC.PA5PFS.BYTE = 0x0D; // RSPCKA MPC.PA6PFS.BYTE = 0x0D; // MOSIA PORTA.PMR.BIT.B5 = 1; PORTA.PMR.BIT.B6 = 1; /* RSPI停止 */ RSPI0.SPCR.BIT.SPE = 0; /* RSPI設定 */ RSPI0.SPPCR.BYTE = 0x00; RSPI0.SPCKD.BYTE = 0x00; RSPI0.SSLND.BYTE = 0x00; RSPI0.SPND.BYTE = 0x00; RSPI0.SPCR2.BYTE = 0x00; // 16ビット、MSBファースト、SPIモード2(CPOL=1, CPHA=0) RSPI0.SPCMD0.WORD = 0x0F02; /* RSPI開始 */ RSPI0.SPCR.BYTE = 0x48; // MSTR=1, SPE=1 } void WriteRegister(uint16_t data) { FSYNC_LOW(); // 送信レジスタに16ビット書き込み (WORDアクセス) RSPI0.SPDR.WORD.H = data; // 送信バッファエンプティフラグ (SPTEF) が1になるまで待機 // SPTEF=1は、送信バッファに次のデータを書き込める状態を示します。 // ただし、これだけでは転送が完全に完了した保証にはなりません。 while (!RSPI0.SPSR.BIT.SPTEF) { // 送信完了待ち } // より確実に転送完了を確認したい場合は、 // RSPIがアイドル状態になるのを待つ(IDLNF=0になるまで待機)ことも検討します。 while (RSPI0.SPSR.BIT.IDLNF) { // RSPIがアイドル状態になるまで待つ } FSYNC_HIGH(); } void AD9833reset(void) { WriteRegister(0x0100); R_BSP_SoftwareDelay(10, BSP_DELAY_MILLISECS); } void AD9833setFrequency(uint32_t frequency, AD9833_WaveType waveform) { if (frequency > (REF_FREQ / 2)) { return; // エラーチェック } uint32_t freqWord = (uint32_t)((frequency * (1ULL << 28)) / REF_FREQ); uint16_t MSB = (uint16_t)((freqWord & 0xFFFC000) >> 14); uint16_t LSB = (uint16_t)(freqWord & 0x3FFF); MSB |= 0x4000; LSB |= 0x4000; WriteRegister(0x2100); WriteRegister(LSB); WriteRegister(MSB); WriteRegister(0xC000); WriteRegister((uint16_t)waveform); } void main(void) { R_Systeminit(); init_SPI(); R_BSP_SoftwareDelay(50, BSP_DELAY_MILLISECS); AD9833reset(); R_BSP_SoftwareDelay(50, BSP_DELAY_MILLISECS); uint32_t frequency = 2000; AD9833setFrequency(frequency, TRIANGLE_WAVE); while (1) { // メインループ } }
わわいさまいろいろ、見直してみて修正をし、なんとか期待する2000hzの三角波を出力できました。やはり、おっしゃる通り思ったように動かないときは自分が悪いですね、、有難いご指摘ありがとうございました。 //ビットレートは1Mbps/8 //SPI2 #include "r_smc_entry.h" /* 定数定義 */ #define FSYNC_LOW() (PORTC.PODR.BIT.B0 = 0) #define FSYNC_HIGH() (PORTC.PODR.BIT.B0 = 1) const float REF_FREQ = 25000000UL; // AD9833の基準クロック(25MHz) /* 波形タイプ */ typedef enum { SINE_WAVE = 0x2000, // 正弦波 TRIANGLE_WAVE = 0x2022, // 三角波 SQUARE_WAVE = 0x2028 // 矩形波 } AD9833_WaveType; /* プロトタイプ宣言 */ void init_SPI(void); void WriteRegister(uint16_t data); void AD9833reset(void); void AD9833setFrequency(uint32_t frequency, AD9833_WaveType waveform); void init_SPI(void) { /* モジュールストップ解除 */ SYSTEM.MSTPCRB.BIT.MSTPB17 = 0; /* ピン設定: RSPCKA、MOSIA */ MPC.PWPR.BIT.B0WI = 0; MPC.PWPR.BIT.PFSWE = 1; MPC.PA5PFS.BYTE = 0x0D; // RSPCKA MPC.PA6PFS.BYTE = 0x0D; // MOSIA PORTA.PMR.BIT.B5 = 1; PORTA.PMR.BIT.B6 = 1; /* RSPI停止 */ RSPI0.SPCR.BIT.SPE = 0; /* RSPI設定 */ RSPI0.SPPCR.BYTE = 0x00; RSPI0.SPCKD.BYTE = 0x00; RSPI0.SSLND.BYTE = 0x00; RSPI0.SPND.BYTE = 0x00; RSPI0.SPCR2.BYTE = 0x00; // 16ビット、MSBファースト、SPIモード2(CPOL=1, CPHA=0) RSPI0.SPCMD0.WORD = 0x0F02; /* RSPI開始 */ RSPI0.SPCR.BYTE = 0x48; // MSTR=1, SPE=1 } void WriteRegister(uint16_t data) { FSYNC_LOW(); // 送信レジスタに16ビット書き込み (WORDアクセス) RSPI0.SPDR.WORD.H = data; // 送信バッファエンプティフラグ (SPTEF) が1になるまで待機 // SPTEF=1は、送信バッファに次のデータを書き込める状態を示します。 // ただし、これだけでは転送が完全に完了した保証にはなりません。 while (!RSPI0.SPSR.BIT.SPTEF) { // 送信完了待ち } // より確実に転送完了を確認したい場合は、 // RSPIがアイドル状態になるのを待つ(IDLNF=0になるまで待機)ことも検討します。 while (RSPI0.SPSR.BIT.IDLNF) { // RSPIがアイドル状態になるまで待つ } FSYNC_HIGH(); } void AD9833reset(void) { WriteRegister(0x0100); R_BSP_SoftwareDelay(10, BSP_DELAY_MILLISECS); } void AD9833setFrequency(uint32_t frequency, AD9833_WaveType waveform) { if (frequency > (REF_FREQ / 2)) { return; // エラーチェック } uint32_t freqWord = (uint32_t)((frequency * (1ULL << 28)) / REF_FREQ); uint16_t MSB = (uint16_t)((freqWord & 0xFFFC000) >> 14); uint16_t LSB = (uint16_t)(freqWord & 0x3FFF); MSB |= 0x4000; LSB |= 0x4000; WriteRegister(0x2100); WriteRegister(LSB); WriteRegister(MSB); WriteRegister(0xC000); WriteRegister((uint16_t)waveform); } void main(void) { R_Systeminit(); init_SPI(); R_BSP_SoftwareDelay(50, BSP_DELAY_MILLISECS); AD9833reset(); R_BSP_SoftwareDelay(50, BSP_DELAY_MILLISECS); uint32_t frequency = 2000; AD9833setFrequency(frequency, TRIANGLE_WAVE); while (1) { // メインループ } }
ビットレートを設定した気になっていましたが、出来てませんね。。。この場合、PCLKAを何分周かした値がデフォルトのSCLKとして供給されるそうです。
スマートコンフィギュータを使うなら生成コードを利用してはどうでしょうか?
SPIはRSPIですよね?FSYNCはRSPI対応のSSLA信号ピンですよね?簡単にSPCMDxレジスタを設定できるので安心かと思います。
複数のデバイスでアクセス周期が違うなどない場合は生成コードが便利だと思います。他の生成コードはわからないですが、割り込みサブルーチンで動作するRSPIについてはまともに動作します。
なお、私は周期の違うSPIデバイス(バースト転送ありとなしが混在)でも生成コードを利用していますが・・・クロック設定やポート設定、生成コードの初期化APIなどはmain呼び出し前に済ませてくれます。
この場合使うのはSPI動作モード(4線式)ですね。8ビットの倍数ならSCIを使った3線式+GPIO(FSYNC信号用)でも良いかもしれません。4線式の気をつける点はバッファのアクセス幅で指定したサイズをN個送信するという考え方です。このデバイスならバッファのアクセス幅は16にしてやるだけでいいですね。
コマンド設定は
フレーム数:コマンド数1、転送フレーム数1
でコマンド0は
ビット長16・・・とやっていきます。
割り込みはデバイスは応答を返さないので送信完了のみとし、割り込みハンドラが生成されるのでそこに状態管理の変数を操作するなどすれば送信完了も確認可能です。
コンポーネントタブの設定が済んだら対応するRSPIやSCIのピン割り当てです。端子タブに移り使うペリフェラルのピンを使用するチェックにして端子番号を設定します。実際のコードは生成コンポーネント名がConfig_HogeならR_Config_Hoge_Createが初期化、_Startがペリフェラルを動作状態にし、実際の通信は_SPI_Master_Send_Receiveを使います、MISOピンは使ってなくても送信専用のAPIが生成されないのでダミーの変数を受信バッファにセットして呼び出せばいいです。
設定した終了後に呼ばれるコールバック関数(生成コード)のコメントで指定されたエリアに同期するための処理を追加しましょう。