編集履歴一覧に戻る
akira.keiのアイコン画像

akira.kei が 2025年03月01日14時07分21秒 に編集

コメント無し

本文の変更

[<前の記事](https://elchika.com/article/d76c4d9b-212b-438f-b16a-3d80a72ad870/) : [次の記事>]() ## シリアルポートを使う

-

シリアルポートEUSARTを使い「Hello, world!」を延々と書き込み続ける。そして書き込みはprintf文で実施する。printfの出力先をシリアルポートにするには、putch関数を用意してあげればいいだけなので簡単だ。

+

シリアルポートEUSARTを使い「Hello, world!」を延々と叫び込み続けるブツを考えてみる。そしてその書き込みはprintf文で実施する。printfの出力先をシリアルポートにするには、putch関数を用意してあげればいいだけなので簡単だ。

``` void putch(char tx) { while(PIR1bits.TXIF==0) {} TX1REG=tx; } ``` ## pragma_config.h 今回もFoscは1MHzに固定する。シリアルポートを9600にする設定はちゃんとデータシートに示されているが、当然ながらFoscを変更するとボーレートジェネレータに設定する値も変わってしまうのでFoscは変更不可にすべきだ。USBシリアル変換基板から電源をとっているので電源監視機能もOFFにする。LEDを接続して点滅させるし、将来的にシリアル入力も試すのでCLKOUTはOFFにして端子を空けた。そしていつものようにLVPはOFFだ。 ``` // CONFIG1 #pragma config FEXTOSC = OFF #pragma config RSTOSC = HFINT1 #pragma config CLKOUTEN = OFF #pragma config CSWEN = OFF #pragma config FCMEN = OFF // CONFIG2 #pragma config MCLRE = ON #pragma config PWRTE = OFF #pragma config WDTE = OFF #pragma config LPBOREN = OFF #pragma config BOREN = OFF #pragma config BORV = LOW #pragma config PPS1WAY = ON #pragma config STVREN = OFF #pragma config DEBUG = OFF // CONFIG3 #pragma config WRT = OFF #pragma config LVP = OFF // CONFIG4 #pragma config CP = OFF #pragma config CPD = OFF ``` ## main関数 冒頭はいつも大体同じだが、「printf」を使うので「stdio」を、ディレイ関数を使うので「_XTAL_FREQ」を設定した。LEDを点滅させるのに「LATAbits.LATA5」と書くと分かり難いので、これを「LED」と定義してある。 ``` #include <xc.h> #include "pragma_config.h" #include <stdio.h> #define _XTAL_FREQ 1000000 #define LED LATAbits.LATA5 ``` main関数の冒頭もほぼいつもと同じだ。アナログを無効にして出力バッファを念の為OFFにしておく。変数「cnt」はループ中に使用するカウンタだ。 ``` void main(void) { unsigned char cnt=0; ANSELA=0; TRISA=0xff; ``` LEDはRA5に接続したのでその設定をする。「RA5PPS」は念の為0にしたがたぶん不要だ。どうせ点滅させるのでLED=1は不要なのだが、ちゃんとループしない場合はずっと点灯になるようにしておく。 ``` // TRISAbits.TRISA5=0; // LED RA5PPS=0; LED=1; ``` EUSARTは普通に出力だけに使う分には設定すべき点は多くない。非同期でFoscを1MHzの時にボーレートを9600にするにはデータシートによればSYNCをクリア、BRGHとBRG16をセット、SPBRGレジスタに25を入れればいい。 ![9600@1MHz](https://camo.elchika.com/75e3b9e24bfe3a8730eba5aa2d54b9e353e0f5d4/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f66313238356136302d396166312d343636392d393936622d306662393565653564363637/) その他は送信可能にしてモジュールを有効化しかしていない。あとはPPSを適切に設定する必要があるのを忘れずに。 ``` // BAUD1CON=0; BAUD1CONbits.BRG16=1; TX1STA=0; TX1STAbits.TXEN=1; // TX enabled TX1STAbits.BRGH=1; // Hi-speed SP1BRGL=25; // 25 (9600 at Fosc=1MHz) SP1BRGH=0; RC1STAbits.SPEN=1 ; // Serialport enabled RA2PPSbits.RA2PPS=0b10100; // EUSART out ``` ## ループ部 ループはprintf、ディレイ、LED点滅処理を繰り返すだけだが、ここにちょっとした罠があった。普段Windowsを使っていると「¥」とバックスラッシュは同じなので改行は「¥n」と入力するのだが、macの場合は「¥」とバックスラッシュは異なる文字(正しい)扱いのため、改行させたい場合は正しくバックスラッシュを入力する必要がある。 出力文字列の冒頭にカウンタ表示付けておかないと、画面がスクロールする時に変化が無くなってしまい、画面上の動きがなくなってしまう。 ``` // while(1) { printf("%02x: Hello, world!\n",cnt++); __delay_ms(250); LED=~LED; } ``` ## Hello, world! と叫び続ける WIndowsのTeraTermなどでデフォルト設定(改行はCRのみ)では「¥n」だけではきちんと改行しないのだが、macやLinuxなら普通に改行してくれる。これはこれで正しいな。むしろTeraTermがデフォルト改行設定をAutoにするだけでいいはず……… ![Hello...](https://camo.elchika.com/c5150a1938ea9eda2155fa1a8665de4ca2b617f7/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f31643931376564322d623039352d343134392d383934332d366239663335376161633139/)