- タイマーを回し,一定時間間隔でUARTに文字を送信(状況ログ出しを想定)
- UARTで文字を受け取り,その旨をUARTで送信(PCから設定更新を想定)
いつもお世話になる 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 件のコメント:
コメントを投稿