PIC16F18346の特記するべき特徴の一つは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 1 | CLCIN1PPS |
CLC Data Input 2 | CLCIN2PPS |
CLC Data Input 3 | CLCIN3PPS |
CLC Data Input 4 | CLCIN4PPS |
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 |
RC6 | 0x16 | ||
RB4 | 0x0C | RC7 | 0x17 |
RB5 | 0x0D | ||
RB6 | 0x0E | ||
RB7 | 0x0F |
右表のペリフェラル出力をRA3を除く任意のI/Oピンに指定することができます。左辺に RxyPPSと、“I/O”番号の後ろに"PPS"を追記したレジスター名称を指定し、右辺に周辺デバイスを表記番号で記載します。たとえば Timer 0 出力ピンを RC3ピンに指定するには
RC3PPS = 28;
↑RC3ピンを示す ↑Timer0を示す「28」
とプログラムします。さらに、ANSELxの該当ビットを「0」にセット、TRISxのビットは「0」にリセットして、該当ピンをデジタル出力にします。
周辺デバイス名称 | 記号 | 表記番号 |
---|---|---|
Port LATxy output | LAT | 0 |
PWM5 output | PWM5 | 2 |
PWM6 output | PWM6 | 3 |
CLC 1 Output | CLC1OUT | 4 |
CLC 2 Output | CLC2OUT | 5 |
CLC 3 Output | CLC3OUT | 6 |
CLC 4 Output | CLC4OUT | 7 |
CWG 1A Output | CWG1A | 8 |
CWG 1B Output | CWG1B | 9 |
CWG 1C Output | CWG1C | 10 |
CWG 1D Output | CWG1D | 11 |
CCP1 Comp or PWM Output | CCP1 | 12 |
CCP2 Comp or PWM Output | CCP2 | 13 |
CCP3 Comp or PWM Output | CCP3 | 14 |
CCP4 Comp or PWM Output | CCP4 | 15 |
周辺デバイス名称 | 記号 | 表記番号 |
---|---|---|
CWG 2A Output | CWG2A | 16 |
CWG 2B Output | CWG2B | 17 |
CWG 2C Output | CWG2C | 18 |
CWG 2D Output | CWG2D | 19 |
EUSART1 Tx/Ck Output | TX/CK | 20 |
EUSART1 Sync Tx | DT | 21 |
Comparator 1 Output | C1OUT | 22 |
Comparator 2 Output | C2OUT | 23 |
MSSP 1 Clock Output | SCK1/SCL1 | 24 |
MSSP 1 Data Output | SDO1/SDA1 | 25 |
MSSP 2 Clock Output | SCK2/SCL2 | 26 |
MSSP 2 Data Output | SDO2/SDA2 | 27 |
Timer 0 Output | TMR0 | 28 |
NCO 1 Output | NCO1 | 29 |
CLKR Output | CLKR | 30 |
DSM Output | DSM | 31 |
PPSLOCKレジスタのPPSLOCKEDビットをセットすると、PPSの選択がロックされ、すべての入出力選択をロックし、不注意による変更を防止しています。このビットをセットおよびクリアするには、特別なシーケンスが必要となり、さらなる不用意防止になっています。例12-1に、PPSLOCKEDビットのセットとクリアの例を示します。
PPS LOCK / UNLOCKシーケンス
#include "stdbool.h" bool state = (unsigned char)GIE; GIE = 0; // インタラプト禁止 PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCKbits.PPSLOCKED = 0x00; // unlock PPS CLCIN0PPS = 0x14; // PPSの設定を実施 RA5PPS = 0x04; // PPSの設定を実施 PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCKbits.PPSLOCKED = 0x01; // lock PPS GIE = state; // インタラプトを元に復旧
コンフィグレーションビット PPS1WAY をセットすることにより、PPSを永続的にロック可能です。このビットがセットされている場合、PPSLOCKEDビットは、デバイスのリセット後に一度だけクリアしセットすることができます。デバイスリセットでPPSLOCKEDビットがクリアされるため、初期化中にPPS入出力を選択できるようになります。すべての選択が行われた後でPPSLOCKEDビットがセットされると、ビットはセットされたままになり、次のデバイスリセットイベントが完了するまでクリアできません。
PPSの入力と出力の選択は、スリープの影響を受けません。
デバイスのパワーオンリセット(POR)は、すべてのPPS入力と出力の選択をデフォルト値にクリアします。他のすべてのリセットでは、選択内容は変更されません。デフォルトの入力選択は、ピン割り当て表2と表3に示されています。
Peripheral Pin Select (PPS)機能の例として、CLCのプログラムです。 CLC Input 0 をPPSでRC4に、CLC1 OutputをppsでRA5に設定しています。
<プログラム>
/********************************************* * File: CLC sample * System ClockはConfigで内部1MHzに設定 * CLCのAND-ORで、PushSW入力を反転しLEDに接続する * CLC入出力はPPSでピン指定する * PIC16F18346 * Created on may 22, 2020 **********************************************/ #include <xc.h> #pragma config FEXTOSC = OFF,RSTOSC = HFINT1 // HFINTOSC (1MHz) #pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF #pragma config MCLRE = ON,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 = ON,CP = OFF,CPD = OFF void main(void){ TRISA5 = 0; // LED RA5 出力設定 ANSC4 = 0; // SW RC4 デジタル設定 // PPS 初期化 ************************************** // pin RC4 (PushSW) を CLCIN0 入力に指定 // pin RA5 (LED D4) を CLC1OUT 出力に指定 // ************************************************* CLCIN0PPS = 0x14; // RC4 -> CLCIN0 RA5PPS = 0x04; // CLC1OUT -> RA5 // CLC1 初期化 ************************************** // AND-OR を使用 // 入力は、CLCIN0PPS でPushSWを指定 // CLC1出力を反転したものをLEDに接続 // ************************************************* CLC1POL = 0x82; // モジュール、Gate2出力反転 他はそのまま CLC1SEL0 = 0x00; // 信号源1 CLCIN0PPS CLC1SEL1 = 0x00; // 信号源2 CLCIN0PPS CLC1SEL2 = 0x00; // 信号源3 CLCIN0PPS CLC1SEL3 = 0x00; // 信号源4 CLCIN0PPS CLC1GLS0 = 0x02; // Gate1 Data1T ON 他はOFF CLC1GLS1 = 0x00; // Gate2 全入力OFF CLC1GLS2 = 0x00; // Gate3 全入力OFF CLC1GLS3 = 0x00; // Gate4 全入力OFF CLC1CON = 0x80; // LC1 ON 割込OFF AND-OR while (1) {} }