PIC18F14K50の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
シリアル信号表示器

18F14K50のEUSARTを使い非同期のシリアル信号を受信しLCD表示する回路を作成しました。
マイコンからの情報を少ない配線数で表示でき、マイコン側のソフトウエアも単純なプログラムで処理できる表示ユニットになりました。ASCII文字以外は、画面表示に最低限必要と思われる制御コードを受け付けます。非同期受信は、パリティーなし、9600bpsのロジックレベル信号の入力とします。

制御コード 動作
0x00 何もしない
0x01 クリア 全表示をクリアし、カーソルを上段先頭にする
0x02 カーソルを上段先頭にする
0x03 カーソルを下段先頭にする
0x8X カーソルを上段 X番目(0-F)にする
0x9X カーソルを下段 X番目(0-F)にする
0x20-0x7F ASCII文字(英数字)を表示
0xA0-0xFF ASCII文字(カタカナ、特殊文字)を表示

このシリアル信号表示器は、スライドスイッチで、LCD表示器に与えるバイアス電圧を切り替え、5v電源にも3.3v電源にも対応できる回路構成となっています。 電源電圧が3.3vのときは、PICのPWMモジュールで100KHzの方形はを発生させ、整流した負電圧をLCDの表示バイアスに使います。

<回路図>

マウスを写真に重ねるとLCDの下に隠れているPICを見ることができます。

プログラム

プロジェクトファイル SerialLCD.zip

<プログラム>
main.c

//*************************************************
//  PIC18F14K50 LCD Program
//   PWM で負電圧を発生させLCDバイアスに使用するため
//   5vと3.3vの電源電圧で動作する
//   Laungage     :  MPLAB xc8
//*************************************************
//     1)Define I/O PORT
//         PORTC(5)    :  PWM Out 負電圧発生用
//         PORTC(3-0)  :  LED_(DB7-4) ←Lowwer 4 Bits接続
//         PORTB(4)    :  LCD_(EN)
//         PORTB(6)    :  LED_(RS)
//     2)OSC
//         4MHz
//**************************************************

#include <p18f14k50.h>
#include <usart.h>
#include <timers.h>
#include "L_LCD.h"
#include <pwm.h>
//
//---------------- configration
#pragma config CPUDIV=NOCLKDIV, USBDIV = OFF
#pragma config FOSC = IRCCLKOUT      //内部クロック
#pragma config PLLEN = ON, PCLKEN = OFF, FCMEN = OFF, IESO = OFF
#pragma config PWRTEN = OFF,BOREN = OFF,BORV = 19
#pragma config WDTEN = OFF,WDTPS = 1
#pragma config MCLRE = OFF,HFOFST = OFF,STVREN = OFF
#pragma config LVP = OFF,BBSIZ = OFF,XINST = OFF
#pragma config CP0 = OFF,CP1 = OFF,CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTRB = OFF
//
//------------ Program
void main(void){
    char msgStart[] ="LCD Test";
    unsigned char i;
    OSCCON = 0b01010010;     //  内部クロック4Mhz
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    TRISA = 0b11101111;      //PortA すべて入力
    TRISB = 0b10101111;      //PortB 6,4出力
    TRISC = 0b11010000;      //PortC 0-3,5出力
    ANSEL  = 0b00000000;     //すべて Degital PORT
    ANSELH = 0b00000000;
// --------------- CCPの 設定 --------------------
// ライブラリで各レジスタは以下のように設定される
//     CCP1CON = 0b00001100;  CCPR1L = 5;
//     PSTRCON = 0b00000001;
//     T2CON   = 0b00000100;  PR2    = 9;
// ---------------------------------------------
    OpenPWM1(9);             // PWM 100KHz
    SetDCPWM1(20);           // Duty 50%
    SetOutputPWM1(
            SINGLE_OUT,
            PWM_MODE_1);
    PSTRCON = 0b00000001;    // PWM出力がP1A ピン
    PIE1bits.CCP1IE = 0;     // 割り込みを使用しない。
    OpenTimer2(              // Timer2
        TIMER_INT_OFF &      //  インタラプトOFF
        T2_PS_1_1 &          //  プリスケラ   1/1
        T2_POST_1_1 );       //  ポストスケラ 1/1
//------------ Initialize LCD --------------------
    LCD_int();
//------------ Initialize UART -------------------
// ライブラリでレジスタは以下のように設定される
//    RCSTA   = 0b10010000;   TXSTA = 0b00100100;
//    BAUDCON = 0b00001000;
//    SPBRGH  = 0;            SPBRG = 103;
// ---------------------------------------------
    baudUSART (
        BAUD_IDLE_RX_PIN_STATE_HIGH &
        BAUD_IDLE_TX_PIN_STATE_HIGH &
        BAUD_16_BIT_RATE &
        BAUD_WAKEUP_OFF &
        BAUD_AUTO_OFF);
    OpenUSART(
        USART_TX_INT_OFF &
        USART_RX_INT_OFF &
        USART_ASYNCH_MODE &
        USART_EIGHT_BIT &
        USART_CONT_RX &
        USART_BRGH_HIGH,
        103);                         //9600 bps
//***************************************************/
    while(1){
    while (!DataRdyUSART());
        i=ReadUSART();                // データ受信
        switch(i){
            case 0x00:                // 何もしない
                break;
            case 0x01:                // Clearコマンド出力
                LCD_cmd(0x01);
                break;
            case 0x02:                // 1行目先頭に移動
                LCD_posyx(0,0);
                break;
            case 0x03:                // 2行目先頭に移動
                LCD_posyx(1,0);
                break;
            default:                  // 80-9Fはカーソル移動
                if((i>=0x80)&&(i<=0x9F)){
                    LCD_posyx((i&0x10)>>4,i&0x0F);
                }else if(i>=0x20){    // 0x20以上は文字の表示
                    LCD_dat(i);
                }
                break;
        }
    }
}