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; } } } }