PIC16F1619の特記するべき特徴の一つは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”ピンをデジタル入力にします。また、複数の周辺機器が同じピンを同時に入力指定し動作することができます。
周辺機器名 | レジスター名 | デフォルトピン |
---|---|---|
Interrupt on change | INTPPS | RA2 |
Timer 0 clock | T0CKIPPS | RA2 |
Timer 1 clock | T1CKIPPS | RA5 |
Timer 1 gate | T1GPPS | RA4 |
Timer 2 clock | T2CKIPPS | RA5 |
Timer 3 clock | T3CKIPPS | RC5 |
Timer 3 gate | T3GPPS | RC4 |
Timer 4 clock | T4CKIPPS | RC1 |
Timer 5 clock | T5CKIPPS | RC0 |
Timer 5 gate | T5GPPS | RC3 |
Timer 6 clock | T6CKIPPS | RA3 |
CCP1 | CCP1PPS | RC5 |
CCP2 | CCP2PPS | RC3 |
CWG1 | CWG1INPPS | RA2 |
SPI/I2C clock | SSPCLKPPS | RB6 |
SPI/I2C data | SSPDATPPS | RB4 |
周辺機器名 | レジスター名 | デフォルトピン |
---|---|---|
SPI slave | SSPSSPPS | RC6 |
EUSART RX | RXPPS | RB5 |
EUSART CK | CKPPS | RB7 |
All CLCs | CLCIN0PPS | RC3 |
All CLCs | CLCIN1PPS | RC4 |
All CLCs | CLCIN2PPS | RC1 |
All CLCs | CLCIN3PPS | RA5 |
SMT1 WIN Input | SMTWIN1PPS | RA5 |
SMT1 SIG Input | SMTSIG1PPS | RA4 |
SMT2 WIN Input | SMTWIN2PPS | RA3 |
SMT2 SIG Input | SMTSIG2PPS | RC1 |
AT1 Clock Input | AT1INPPS | RC5 |
AT1 CC1 Input | AT1CC1PPS | RC3 |
AT1 CC2 Input | AT1CC2PPS | RC4 |
AT1 CC3 Input | AT1CC3PPS | RC5 |
I/O名称 | 表記 | I/O名称 | 表記 | I/O名称 | 表記 |
---|---|---|---|---|---|
RA0 | 0x00 | RC0 | 0x10 | ||
RA1 | 0x01 | RC1 | 0x11 | ||
RA2 | 0x02 | RC2 | 0x12 | ||
RA3 | 0x03 | RC3 | 0x13 | ||
RA4 | 0x04 | RB4 | 0x0C | RC4 | 0x14 |
RA5 | 0x05 | RB5 | 0x0D | RC5 | 0x15 |
RB6 | 0x0E | RC6 | 0x16 | ||
RB7 | 0x0F | RC7 | 0x17 |
右表のペリフェラル出力をRA3を除く任意のI/Oピンに指定することができます。左辺に RxyPPSと、“I/O”番号の後ろに"PPS"を追記したレジスター名称を指定し、右辺に周辺デバイスを表記番号で記載します。たとえば PWM3出力ピンを RC3ピンに指定するには
RC3PPS = 0x0E;
↑RC3ピンを示す ↑PWM3を示す「0x0E」
とプログラムします。さらに、ANSELxの該当ビットを「0」にセット、TRISxのビットは「0」にリセットして、該当ピンをデジタル出力にします。
周辺デバイス名称 | 表記番号 |
---|---|
LATxy | 0x00 |
sync_C1OUT | 0x01 |
sync_C2OUT | 0x02 |
ZCD1_out | 0x03 |
LC1_out | 0x04 |
周辺デバイス名称 | 表記番号 |
---|---|
LC2_out | 0x05 |
LC3_out | 0x06 |
LC4_out | 0x07 |
CWG1OUTA(1) | 0x08 |
CWG1OUTB(1) | 0x09 |
周辺デバイス名称 | 表記番号 |
---|---|
CWG1OUTC(1) | 0x0A |
CWG1OUTD(1) | 0x0B |
CCP1_out | 0x0C |
CCP2_out | 0x0D |
PWM3_out | 0x0E |
周辺デバイス名称 | 表記番号 |
---|---|
PWM4_out | 0x0F |
SCK/SCL(1) | 0x10 |
SDO/SDA(1) | 0x11 |
TX/CK | 0x12 |
DT | 0x13 |
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入力と出力の選択をデフォルト値にクリアします。他のすべてのリセットでは、選択内容は変更されません。デフォルトの入力選択は、ピン割り当て表に示されています。
*注意*
I2Cのデフォルトの入力ピンはI2CおよびSMBusと互換性があり、この互換性を持つのはこのピンだけです。
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) {} }