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

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

PIC16F18325の特記するべき特徴の一つは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
Timer3 Ext Clock IN T3CKIPPS
Timer3 Gate IN T3GPPS
Timer5 Ext Clock IN T5CKIPPS
Timer5 Gate IN T5GPPS
Input Capture 1 CCP1PPS
Input Capture 2 CCP2PPS
Input Capture 3 CCP3PPS
IN Capture 4 CCP4PPS
CWG 1 Data Input CWG1PPS
CWG 2 Data Input CWG2PPS
MDC Input 1 MDCIN1PPS
周辺デバイス名称 レジスター名
MDC Input 2 MDCIN2PPS
MDM Input MDMINPPS
SSP1 Clock IN SSP1CLKPPS
SSP1 Data IN SSP1DATPPS
SSP1 Slave Select IN SSP1SSPPS
SSP2 Clock IN SSP2CLKPPS
SSP2 Data IN SSP2DATPPS
SSP2 Slave Select IN SSP2SSPPS
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名称 表記 I/O名称 表記
RA0 0x00 RC0 0x10
RA1 0x01 RC1 0x11
RA2 0x02 RC2 0x12
RA3 0x03 RC3 0x13
RA4 0x04 RC4 0x14
RA5 0x05 RC5 0x15

出力ピンの配置指定

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

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

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

周辺デバイス名称 記号 表記番号
Port LATxy output LAT 0 00000
PWM5 output PWM5 2 00010
PWM6 output PWM6 3 00011
CLC 1 Output CLC1OUT 4 00100
CLC 2 Output CLC2OUT 5 00101
CLC 3 Output CLC3OUT 6 00110
CLC 4 Output CLC4OUT 7 00111
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
CCP3 Comp or PWM Output CCP3 14 01110
CCP4 Comp or PWM Output CCP4 15 01111
周辺デバイス名称 記号 表記番号
CWG 2A Output CWG2A 16 10000
CWG 2B Output CWG2B 17 10001
CWG 2C Output CWG2C 18 10010
CWG 2D Output CWG2D 19 10011
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
MSSP 2 Clock Output SCK2/SCL2 26 11010
MSSP 2 Data Output SDO2/SDA2 27 11011
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;
           }
        }
    }
}