土曜日, 10月 19, 2019

PIC24FV16KM202 MPLAB+MCC simulatorでシリアルテスト

目標仕様
  • タイマーを回し,一定時間間隔でUARTに文字を送信(状況ログ出しを想定)
  • UARTで文字を受け取り,その旨をUARTで送信(PCから設定更新を想定)
とりあえずMCCで設定を始める。System Moduleから難しい。



いつもお世話になる picfun のページにバッチリ解説されてた。内蔵発振器はFRCを選ぶ。8MHzで,Postscalerは要するに分周ですね。1:1で,8MHzにする。

低電力発振器 LPRC おもしろそうだが,これはきっとスリープ等で使うのだろう。31kHzなので,標準では使わない。
などなど。

続くタイマー割り込みで,処理を記述するとコンパイルエラーが出て,少し悩む...
結果,タイマー処理で使う変数を,きちんと初期化しないと,変数として認めてくれないようだ。うーむ。C言語の基本がわかってない -> 自分

調べる過程で,公式のサンプルを見つけた。
https://microchipdeveloper.com/projects:16bit-interrupts

PIC16Fでプログラムを書いたときは,tmr1.cに割り込み処理を書いていた。
上記サンプルでは,main.cに記述している。こちらの方がいい!
ということで,UARTも含めて,できた。


#include "mcc_generated_files/system.h"
#include "mcc_generated_files/mcc.h" // <- 追加せよとのこと

#include <stdio.h>
 

unsigned long int GLOBAL_TIME = 0; // <- 初期化必要だった
unsigned long int NEXT_TIME = 0;
char RECEIVED_CHAR = ' ';

void My_TMR1_ISR(void) // <- 自分のタイマー処理                   
  {
    GLOBAL_TIME++;
    if (GLOBAL_TIME>NEXT_TIME) {
        NEXT_TIME=GLOBAL_TIME+10; // means 1 sec
        printf("Time is %lo.¥n",GLOBAL_TIME);
    }
   }

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    TMR1_SetInterruptHandler(My_TMR1_ISR); 
    NEXT_TIME=GLOBAL_TIME+10;
    // TMR1_Start();
    while (1) {
        if (UART1_IsRxReady()) {
            RECEIVED_CHAR=UART1_Read();
            printf("%c was received at %lo.¥n",RECEIVED_CHAR,GLOBAL_TIME);
        }
    }

    return 1;
}


UARTだが,PIC16Fで試した時と様子が違っていた。割り込みが,送信,受信,エラー,一括でON/OFFしかできないのだ。送信の割り込みってどうやるんだよ... どうも割り込みONだとうまく動かない。ONにして,interrupt.c で個別にOFFにしても,どうもうまく動かない。ということで,受信も,main関数内で書いてみた。uart1.cに置かれている関数をコール。うまく動いた。

Simulationは以下の通り。
  • Project設定で,書き込み先をSimulatorにセット
  • さらにSimulator設定で,Uart1 IO Options で Window をON
  • Window - Simulator - Stimulus で,PICに送信する文字を設定。
  • シミュレーション開始,Stimulus [Fire] でPICに送信。


できた!
 
(昼過ぎ 追記)
GLOBAL_TIMEで10(1秒)ずつ送信するように書いたつもりだが,出力している文字列がおかしい。以下のように書き直した。

void My_TMR1_ISR(void)                     
  {
    GLOBAL_TIME++;
    if (GLOBAL_TIME>NEXT_TIME) {
        printf("Interrupted at %lu.¥n",NEXT_TIME);
        NEXT_TIME=NEXT_TIME+10; // means 1 sec
    }
   }

printf分の書式の誤り。ああ,はずかしい。もっとC言語そのものを知らなくては...

0 件のコメント: