今回は、PIC16F18346とPC間でデータのやり取りをしてみたいと思います。
(もちろんシリアル通信 UART です)
やりたいこと
- シリアル通信でPC側にデータを送る
- シリアル通信でPIC側にデータを送る
上は簡単だと思います。(頑張ればソフトウェア実装でも行けます)
ただ、下のほうが大変そうです。(昔すごく苦労した気がします…)
(頑張ればどっちもソフトウェア実装でもできますよ。やりたくないですが…)
ということでこれらをトータルし、
- PC側から’A’を送信したら”Hello”
- PC側から’B’を送信したら” World!”
- PC側から’C’を送信したら改行(‘\r\n’)
というプログラムを作ってみたいと思います。
ちなみにこの記事は今後予定しているAD9833をPC上でコントロールするための事前演習みたいなものです。
余談
Windows11からPL2303TAが使用できなくなりました(表面上)
これのせいで、この記事を書くのが遅くなってしまったのですが、しょうがないですね。
後、いつも使っていたUART-RS232C変換基板のコネクタ部分が取れました。
え…(絶望)
こんな風に直しました。
また画像にはとっていませんが、電源回路もはんだ不良で壊れ、修理したためめちゃくちゃ時間がかかりました。(マイコンは動作するのにUART-RS232C変換基板が動作しない怪現象が発生)
回路図
今回は、送信・受信ともにこの回路図で行いました。
なお、この回路図はUART-USB変換アダプタや5V変換装置などを省略しています。
実験の様子
基板は過去に作ったやつです。参考程度にどうぞ。
ちなみに下の商品でも代用可能です。
動きました
今回は動作している様子をYouTubeにアップロードしてみました。
(様子といってもPCの画面を録画しただけですが)
備忘録
なぜだか分かりませんが、連続受信モードをONにしないと受信できません。
後、PIC16F18346はRXピンがPB5に割り当てされていますが、PPS機能を使用すれば別のピンに移すことができることも確認しました。(まあピン割り当て表の注記にかいてあるんですけどね)
プログラムソース
あまりきれいではないプログラムです。
参考程度にどうぞ。
/*
* 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;
//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':
UART_print("Hello");
break;
case 'b':
UART_print(" World!");
break;
case 'c':
UART_print("\r\n");
break;
}
PIR1bits.RCIF = 0;
}
}
void UART_print(char moji[50]) {
int i = 0;
while (moji[i] != '\0') {
TX1REG = moji[i];
while (!TX1STAbits.TRMT) {
};
i++;
}
}
おわり。