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

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
Peripheral Pin Select (PPS)機能
2017-09-02

PIC16F18313の特記するべき特徴の一つはPeripheral Pin Select (PPS)機能を持っていることです。PPSにより内蔵するモジュールの入出力ピンを自由に再配置することができます。これは、ピン数の少ないPICでは大きな福音となります。

入力ピンの配置指定

右表のペリフェラル入力ピンを任意のI/Oピンに指定することができます。左辺にxxxxで、どの周辺デバイスかを表記したPPSレジスター、右辺に指定する“I/O”ピン番号を指定します。たとえば EUSART1 Rxピンを RA1ピンに指定するには、

RXPPS  =  0x01;
↑RXを示す   ↑RA1ピンを示す

とプログラムします。さらに該当ピンのANSELxのビットを「0」にリセット、TRISxのビットは「1」にセットして、該当する“I/O”ピンをデジタル入力にします。

周辺デバイス名称 レジスター名
External Interrupt INTPPS
Timer0 Ext Clock IN T0CKIPPS
Timer1 Ext Clock IN T1CKIPPS
Timer1 Gate IN T1GPPS
Input Capture 1 CCP1PPS
Input Capture 2 CCP2PPS
CWG 1 Data Input CWG1PPS
MDC Input 1 MDCIN1PPS
MDC Input 2 MDCIN2PPS
MDM Input MDMINPPS
周辺デバイス名称 レジスター名
SSP1 Clock IN SSP1CLKPPS
SSP1 Data IN SSP1DATPPS
SSP1 Slave Select IN SSP1SSPPS
EUSART1 Async Rx RXPPS
EUSART1 Async Tx TXPPS
CLC Data Input 0 CLCIN0PPS
CLC Data Input 1 CLCIN1PPS
CLC Data Input 2 CLCIN2PPS
CLC Data Input 3 CLCIN3PPS
 
I/O名称 表記
RA0 0x00
RA1 0x01
RA2 0x02
RA3 0x03
RA4 0x04
RA5 0x05

出力ピンの配置指定

右表のペリフェラル出力をRA3を除く任意のI/Oピンに指定することができます。左辺に RxyPPSと、“I/O”番号の後ろに"PPS"を追記したレジスター名称を指定し、右辺に周辺デバイスを表記番号で記載します。たとえば Timer 0 出力ピンを RA2ピンに指定するには

RA2PPS   =  28;
↑RC3ピンを示す  ↑Timer0を示す「28」

とプログラムします。さらに、ANSELxの該当ビットを「0」にセット、TRISxのビットは「0」にリセットして、該当ピンをデジタル出力にします。

周辺デバイス名称 記号 表記番号
Port LATxy output LAT 0 00000
PWM5 output PWM5 2 000010
PWM6 output PWM6 3 00011
CLC 1 Output CLC1OUT 4 00100
CLC 2 Output CLC2OUT 5 00101
CWG 1A Output CWG1A 8 01000
CWG 1B Output CWG1B 9 01001
CWG 1C Output CWG1C 10 01010
CWG 1D Output CWG1D 11 01011
CCP1 Comp or PWM Output CCP1 12 01100
CCP2 Comp or PWM Output CCP2 13 01101
周辺デバイス名称 記号 表記番号
EUSART1 Tx/Ck Output TX/CK 20 10100
EUSART1 Sync Tx DT 21 10101
Comparator 1 Output C1OUT 22 10110
Comparator 2 Output C2OUT 23 10111
MSSP 1 Clock Output SCK1/SCL1 24 11000
MSSP 1 Data Output SDO1/SDA1 25 11001
Timer 0 Output TMR0 28 11100
NCO 1 Output NCO1 29 11101
CLKR Output CLKR 30 11110
DSM Output DSM 31 11111

プログラム

Peripheral Pin Select (PPS)機能の例として、USARTのプログラムです。 UART TX Outputは、 RC4に、 UART RX Inputを RC5に設定しています。

<プログラム>

/*************************************
 * File: PPS sample
 * System ClockはConfigで内部1MHzに設定
 * UARTでデータを送受信する。
 * RC4をTX出力 RC5をRX入力とする
 * SW5を押すと開始メッセージ。
 * その後 SWを押すと「SW pressed」を送信
 * 「1」を受信すると、LED1を点灯
 * 「0」を受信すると、LEDを消灯
 * PIC16F18325
 * Created on Aug 22, 2017, 2:37 PM
 **************************************/

#include <xc.h>
#include <stdio.h>

#define _XTAL_FREQ 1000000              // delay_ms(x) のための定義
#define antiCnt    5;

#pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF

#define SW5  PORTAbits.RA5

// ================= printf関数を使用するための定義 =================
void putch(unsigned char ch) {
    while (!TXIF);                     //送信終了待ち
    TX1REG = ch;
}

// ******************* main *************************************
void main() {
    char SWcnt = 10;
    char RxData;

    TRISA  = 0b111111;                 // Port すべて入力
    TRISC  = 0b110000;                 // RC0-RC3出力 RC4,RC5入力
    ANSELA = 0;                        // すべてデジタル
    ANSELC = 0;                        // すべてデジタル
    WPUA   = 0b100000;                 // RA5 弱プルアップ ON

    RC4PPS = 20;                       // RC4をTX出力とする
    RXPPS = 0x15;                      // RC5をRX入力とする

//------------ Initialize UART ----------------------------------
    RC1STA   = 0b10010000;             // 非同期送受信 9600baud
    TX1STA   = 0b00100100;
    BAUD1CON = 0b00001000;
    SP1BRGH  = 0;
    SP1BRG   = 25;

    __delay_ms(100);                    // システム安定まで待つ
    while(SW5);                         // SWが押されるのを待つ
    printf("\r\nHello OK\r\n");         // 開始のメッセージ

    // ----------- 繰返し --------------------------------------------
    while(1){
        // ----- SW check -----------
        if(SWcnt){                         // 待機中でない
            if(SW5){                       // SWがOFF なら
                SWcnt--;                   //   SWcntをー1
                __delay_ms(1);             //   チャタリング防止
            }else{                         // SWが押されていれば
                SWcnt = antiCnt;           //   SWcntをリセット
            }
        }else{                             // 待機中なら
            if(SW5==0){                    //   SW ON なら
                printf("SW pressed\r\n");  //   メッセージ送信
                SWcnt = antiCnt;
            }
        }  // end if(SWcnt)
        // ----- Rx check -----------
        if(RCIF){                          // 受信したなら
           RxData = RC1REG;                // 受信データを取り込む
           switch(RxData){                 // データ内容で、On/Off
               case '0':                   // 0を受信
                   printf("0 LEDs all off\r\n");
                   LATC = 0;
                   break;
               case '1':                   // 1を受信
                   printf("1 LED1 on\r\n");
                   LATC = 1;
                   break;
               case '2':                   // 2を受信
                   printf("2 LED2 on\r\n");
                   LATC = 2;
                   break;
               case '3':                   // 3を受信
                   printf("3 LED3 on\r\n");
                   LATC = 4;
                   break;
               case '4':                   // 4を受信
                   printf("4 LED4 on\r\n");
                   LATC = 8;
                   break;
               default:
                   break;
           }
        }
    }
}