PIC18F47Q43 メカナムホイール車 M5AtomLite bluetooth通信

# 40ピンPICマイコン18F47Q43で、メカナムホイール車を動かしました。
<iframe width="560" height="315" src="https://www.youtube.com/embed/ANSZEqH8880?si=2I93CbFcBaLWfBwa" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

![IMG_4840.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/06e9a887-bf2e-9dca-3f17-9ae8eb43a28d.jpeg)



:::note info
**メカナム車本体**

**PIC18F47Q43+M5 ATOM Lite**

**・18F47Q43のPWM1,2,3モジュールと、CCP1,2モジュールを使って、4輪駆動のメカナムホイール車を操作します。**

**・メカナム車本体受信用でATOM Liteを使用(シリアル通信で受信データをPICマイコンに送信）**
:::

:::note info
**無線コントローラ部**
**・M5AtomLiteを使用しています。
    ・スーパーファミコンコントローラボタン押下送信**
:::

# メカナムホイール車の動作
![メカナムホイール動作１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/f2d222a8-cb1f-b884-071a-02c29c182983.jpeg)
![メカナムホイール動作２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/8ca85a36-8930-c1e9-8e4d-a09e77b67d45.jpeg)

# メカナムホイール車　ＤＣモータ部
![IMG_4837.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/6deb94b6-13d1-d46e-d626-8efc6ddaad0c.jpeg)

# メカナムホイール車　モータ電源部とＨブリッジ基板
HブリッジIC BD6211 を４つ使用して、DCモータを駆動しています。
LM371可変電源レギュレータでモータ電源電圧をコントロールしています。(2.5v～3v)
![IMG_4826.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/5f951d5a-3710-c140-f75b-07fd08ba54b5.jpeg)
![BD6211回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/9e1b6f5c-0bc0-fcbd-455c-4504e7e02b09.png)


# メカナムホイール車　マイコン部PIC18F47Q43
![IMG_4843.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/f6a875b6-27a9-98bb-e94b-6f3db8b493ac.jpeg)

![メカナム車配線図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/18e22ed4-07b4-64be-9ab6-8a0fffccea78.jpeg)

# メカナムホイール車　M5Atom Lite bluetooth無線通信部　受信(Q43とシリアル通信で接続)
![IMG_4844.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/e83d20b1-f22d-ddde-0d9b-a9de9f40ef36.jpeg)

ポート割り振り
![port表１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/0ce1fb51-4a56-35c3-c272-eabe8ca26c32.png)
![port表２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/8e744148-7f12-1dc9-da07-7cead920055a.png)



# 無線コントローラ　M5Atom Liteとスーパーファミコンコントローラ送信機
コントローラの押下データを、メカナム車搭載のATOM Liteに送信します。
![IMG_4841.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/81edd7df-3537-062e-c8f1-8a6bdd36ae52.jpeg)

![ATOM配線図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/4d934ca8-c7e4-5244-e5e3-093badab8ce4.jpeg)

# メカナム車側本体コード　PIC18F47Q43
:::note info
・PWM1,2,3,およびCCP1,2PWMモジュールのデューティーサイクルは15msで統一しています。
・スーファミコントローラ
    L:減速  R:加速 十字キーで移動  A：CW回転  B:CCW回転
・ATOMLiteとUARTで接続し、コントローラから送られてくるデータを受信します。
:::
```C:main
// PIC18F27Q43 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FEXTOSC = OFF    // External Oscillator Selection (Oscillator not enabled)
#pragma config RSTOSC = HFINTOSC_64MHZ// Reset Oscillator Selection (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)

// CONFIG2
#pragma config CLKOUTEN = OFF   // Clock out Enable bit (CLKOUT function is disabled)
#pragma config PR1WAY = OFF     // PRLOCKED One-Way Set Enable bit (PRLOCKED bit can be set and cleared repeatedly)
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)

// CONFIG3
#pragma config MCLRE = EXTMCLR  // MCLR Enable bit (If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin function is MCLR )
#pragma config PWRTS = PWRT_OFF // Power-up timer selection bits (PWRT is disabled)
#pragma config MVECEN = ON      // Multi-vector enable bit (Multi-vector enabled, Vector table used for interrupts)
#pragma config IVT1WAY = ON     // IVTLOCK bit One-way set enable bit (IVTLOCKED bit can be cleared and set only once)
#pragma config LPBOREN = OFF    // Low Power BOR Enable bit (Low-Power BOR disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)

// CONFIG4
#pragma config BORV = VBOR_1P9  // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR) set to 1.9V)
#pragma config ZCD = OFF        // ZCD Disable bit (ZCD module is disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = OFF     // PPSLOCK bit One-Way Set Enable bit (PPSLOCKED bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)

// CONFIG5
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF       // WDT operating mode (WDT Disabled; SWDTEN is ignored)

// CONFIG6
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)

// CONFIG7
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF       // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF      // Storage Area Flash enable bit (SAF disabled)
#pragma config DEBUG = OFF      // Background Debugger (Background Debugger disabled)

// CONFIG8
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block not Write protected)
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers not Write protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not Write protected)
#pragma config WRTSAF = OFF     // SAF Write protection bit (SAF not Write Protected)
#pragma config WRTAPP = OFF     // Application Block write protection bit (Application Block not write protected)

// CONFIG10
#pragma config CP = OFF         // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "Q_peripheral27Q43.h"
#include "Q_interrupt27Q43.h"
#include "Q_initialize.h"
#include "Q_I2C1.h"
#include "I2C_LCD.h"
#include "stringFormat.h"
#include  "MCP23017.h"
#include "I2C_LCD.h"
#include "I2C_LCD_BarMeter.h"
#include "RTC_DS3231.h"
#include "EEPROM_24LCxxx.h"
#include "Q_SPI2.h"
#include "MCP23Sxx.h"
#include "DFMRW.h"
#include "ds_ST7735S.h"
#include "ST7735_BarMeter.h"
#include "famicon.h"

void portInit(void);
void oscillatorInit(void);
void vicInit(void);
uint16_t strToInt16(uint8_t *ch, uint8_t _length);



void main(void)
{
    
    uint8_t length,i;
    int16_t val16;
    uint16_t buttonState;
    
    i=0;
    val16=0;
    //CPUハード初期化-----------------------
    portInit();
    oscillatorInit();
    vicInit();
    __delay_ms(100);
  /*  while(1)
    {
        LATCbits.LATC2=1;
        LATCbits.LATC5=1;
        __delay_ms(500);
        LATCbits.LATC2=0;
        LATCbits.LATC5=0;
        __delay_ms(500);
    }*/
    //周辺機能初期化--------------------------------
    timer0Init();//LED表示
    timer1Init();//表示
    //timer2Init();//ADC trigger
    timer3Init();//CCP capture
    timer4Init();//I2C　timeOut
    timer6Init();//CCP1 PWM
    //timer6Init();
    usartInit();
    //adcInit();//Timer2も同時に初期化
    pwm1Init();
    pwm2Init();
    pwm3Init();
    CCP1_PWM_Init();
    CCP2_PWM_Init();
    //iocInit();//RC0:input
    //I2C1_Init();//I2C初期化
    //LCD_Init(LcdDeviceAdd);//LCD初期化(PCD8574駆動)
    //Lcd_Mem_Char_Set(LcdDeviceAdd);//LCD CGRAMデータセット
    //LCD_Printf(LcdDeviceAdd,"18F27Q43",8,0x80);
    //LCD_Printf(LcdDeviceAdd,"PWM1 Slice1",11,0xC0);
    //famicon controller
    //famiconInit();
   
    
  
//#define debug
#ifdef debug
    INTCON0bits.IPEN=1;//プライオリティ無し
    INTCON0bits.GIE=1;//Enable all masked interrupts
    while(1)
    {
        printf("%d\n",val16++);
        __delay_ms(500);
         if(rxUsart.completed)
            {
                rxUsart.completed=false;
                printf("%s",rxUsart.buf);
                rxUsart.length=0;
                PIE4bits.U1RXIE=1;
            }
    };
#endif
    
    //ｸﾞﾛｰﾊﾞﾙ割り込み許可------------------------------------------
    IPR3bits.TMR2IP=1;
    INTCON0bits.IPEN=1;//プライオリティ無し
    INTCON0bits.GIE=1;//Enable all masked interrupts
    
    adcData.val[0]=0x0FFF;
    while(1)
    {
     
        //Timer0割込み処理-------------------------------------
        if(tm0.fg==true)
        {
            tm0.fg=false;
            PORTCbits.RC0=~PORTCbits.RC0;
            T0CON0bits.EN=1;
            PIE3bits.TMR0IE=1;
        }
        
        //Timer1割込み------------------------------------------
        if(tm1.fg==true)
        {
            tm1.fg=false;
            T1CONbits.ON=1;
            PIE3bits.TMR1IE=1;
        }
        
        //USART受信割り込み----------------------------------------
        if(rxUsart.completed)
        {
            rxUsart.completed=false;
            
            buttonState = (uint16_t)strtol(rxUsart.buf,NULL,16);
            
            if(buttonState==0xFFF0)
            {
                PWM1S1P1L=0;
                PWM1S1P2L=0;
                //FR 後ろ
                PWM2S1P1L=0;
                PWM2S1P2L=0;                    
               //RL　前
                PWM3S1P1L=0;
                PWM3S1P2L=0;
                //RR 前
                CCPR1=0;              
                CCPR2=0;    
            }
                          
            if((buttonState&0x0800)==0x0000)//UP
            {
                if((buttonState&0x0200)==0x0000)
                {//左上
                    //FL　停止
                    PWM1S1P1L=0;
                    PWM1S1P2L=0;
                    //FR  前
                    PWM2S1P1L=adcData.val[0]>>4;
                    PWM2S1P2L=0;
                    //RL　前
                    PWM3S1P1L=adcData.val[0]>>4;
                    PWM3S1P2L=0;
                    //RR  停止
                    CCPR1=0;              
                    CCPR2=0;   
                }
                else
                {
                    if((buttonState&0x0100)==0x0000)
                    {//右上
                        //FL　前
                        PWM1S1P1L=adcData.val[0]>>4;
                        PWM1S1P2L=0;
                        //FR  停止
                        PWM2S1P1L=0;
                        PWM2S1P2L=0;
                        //RL　停止
                        PWM3S1P1L=0;
                        PWM3S1P2L=0;
                        //RR 前
                        CCPR1=adcData.val[0]>>2;              
                        CCPR2=0;   
                    }else
                    {//前進
                        //FL　前
                        PWM1S1P1L=adcData.val[0]>>4;
                        PWM1S1P2L=0;
                        //FR  前
                        PWM2S1P1L=adcData.val[0]>>4;
                        PWM2S1P2L=0;
                        //RL　前
                        PWM3S1P1L=adcData.val[0]>>4;
                        PWM3S1P2L=0;
                        //RR 前
                        CCPR1=adcData.val[0]>>2;              
                        CCPR2=0;   
                    }
                }
            }
             
            if((buttonState&0x0400)==0x0000)//DOWN
            {
                if((buttonState&0x0200)==0x0000)
                {//左下
                    //FL 後ろ
                    PWM1S1P1L=0;
                    PWM1S1P2L=adcData.val[0]>>4;
                    //FR 停止
                    PWM2S1P1L=0;
                    PWM2S1P2L=0;
                    //RL 停止
                    PWM3S1P1L=0;
                    PWM3S1P2L=0;
                    //RR 後ろ
                    CCPR1=0;
                    CCPR2=adcData.val[0]>>2;
                }else
                {
                    if((buttonState&0x0100)==0x0000)
                    {//右下
                        //FL 停止
                        PWM1S1P1L=0;
                        PWM1S1P2L=0;
                        //FR 後ろ
                        PWM2S1P1L=0;
                        PWM2S1P2L=adcData.val[0]>>4;
                        //RL 後ろ
                        PWM3S1P1L=0;
                        PWM3S1P2L=adcData.val[0]>>4;
                        //RR 停止
                        CCPR1=0;
                        CCPR2=0;
                    }else
                    {//後進
                        //FL 後ろ
                        PWM1S1P1L=0;
                        PWM1S1P2L=adcData.val[0]>>4;
                        //FR 後ろ
                        PWM2S1P1L=0;
                        PWM2S1P2L=adcData.val[0]>>4;
                        //RL 後ろ
                        PWM3S1P1L=0;
                        PWM3S1P2L=adcData.val[0]>>4;
                        //RR 後ろ
                        CCPR1=0;
                        CCPR2=adcData.val[0]>>2;
                    }                    
                }               
            }
             
            if(((buttonState&0x0800)!=0x0000) && ((buttonState&0x0400)!=0x0000)) 
            {
                if((buttonState&0x0200)==0x0000)//LEFT
                {//左すべり
                    //FL　後
                    PWM1S1P1L=0;
                    PWM1S1P2L=adcData.val[0]>>4;
                    //FR  前
                    PWM2S1P1L=adcData.val[0]>>4; 
                    PWM2S1P2L=0;                   
                    //RL 前
                    PWM3S1P1L=adcData.val[0]>>4;
                    PWM3S1P2L=0;
                    //RR 後
                    CCPR1=0;
                    CCPR2=adcData.val[0]>>2;
                }
             
                if((buttonState&0x0100)==0x0000)//RIGHT
                {//右すべり
                    //FL 前
                    PWM1S1P1L=adcData.val[0]>>4;
                    PWM1S1P2L=0;
                    //FR 後ろ
                    PWM2S1P1L=0;
                    PWM2S1P2L=adcData.val[0]>>4;                    
                    //RL 後ろ
                    PWM3S1P1L=0;
                    PWM3S1P2L=adcData.val[0]>>4;
                    //RR 前
                    CCPR1=adcData.val[0]>>2;              
                    CCPR2=0;    
                }
                
                if((buttonState&0x8000)==0x0000)
                {//CW
                    //FL 前
                    PWM1S1P1L=adcData.val[0]>>4;
                    PWM1S1P2L=0;
                    //FR 後ろ
                    PWM2S1P1L=0;
                    PWM2S1P2L=adcData.val[0]>>4;                    
                    //RL 前
                    PWM3S1P1L=adcData.val[0]>>4;
                    PWM3S1P2L=0;
                    //RR 後ろ
                    CCPR1=0;             
                    CCPR2=adcData.val[0]>>2;     
                }
                
                if((buttonState&0x0080)==0x0000)
                {//CCW
                    //FL 後
                    PWM1S1P1L=0;
                    PWM1S1P2L=adcData.val[0]>>4;
                    //FR 前
                    PWM2S1P1L=adcData.val[0]>>4;  
                    PWM2S1P2L=0;
                    //RL 後
                    PWM3S1P1L=0;
                    PWM3S1P2L=adcData.val[0]>>4;
                    //RR 前
                    CCPR1=adcData.val[0]>>2;             
                    CCPR2=0;
                }
                
                
            }    
            
            if((buttonState&0x0020)==0x0000)
            {//減速
                adcData.val[0]-=100;
                if(adcData.val[0]<110)
                    adcData.val[0]=10;
            }

            if((buttonState&0x0010)==0x0000)
            {//加速
                adcData.val[0]+=100;
                if(adcData.val[0]>0x0FFF)
                    adcData.val[0]=0x0FFF;
            }
            
            
             PWM1CONbits.LD=1;
             PWM2CONbits.LD=1;
             PWM3CONbits.LD=1;
             while(PWM1CONbits.LD);  
             while(PWM2CONbits.LD);
             while(PWM3CONbits.LD);
             PIE1bits.ADIE=1;
             //ADCON0bits.ON=1;
             PIE3bits.TMR2IE=1;
             T2CONbits.TMR2ON=1;
             //Usart復帰
             rxUsart.length=0;
             PIE4bits.U1RXIE=1;
        }
       
    }
    return;
}

void oscillatorInit(void)
{
    //オシレータ設定----------------
    OSCCON3bits.CSWHOLD=1;//Hold
    OSCCON1bits.NDIV=1;//64Mhz/2=32Mhz;
    while(!OSCCON3bits.NOSCR);
    while(!PIR0bits.CSWIF);//ready state
    PIR0bits.CSWIF=0;
    OSCCON3bits.CSWHOLD=0;
    while(!OSCCON3bits.ORDY);
}

void portInit(void)
{
    //ポート設定----------------------    
    PORTA=0x00;
    LATA=0x00;
    ANSELA=0x00;
    TRISA=0x00;
    
    PORTB=0x00;
    LATB=0x00;
    ANSELB=0x00;
    TRISB=0x00;
    
    PORTC=0x00;
    LATC=0x00;
    ANSELC=0x00;
    TRISC=0x00;
   
    PORTD=0x00;
    LATD=0x00;
    ANSELD=0x00;
    TRISD=0x00;
    
    
    PORTE=0x00;
    LATE=0x00;
    ANSELE=0x00;
    TRISE=0x00;
   
     //PPS---------------------
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;
    
    //I2C1-------------------------
    //RC4 for SDA
    RC4PPS=0x38;
    I2C1SDAPPS=0x14;
    //RC3 for SCL
    RC3PPS = 0x37;
    I2C1SCLPPS=0x13;
    
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;
    
    ODCONCbits.ODCC3=1;
    ODCONCbits.ODCC4=1;
    
    RC3I2Cbits.TH=1;
    RC4I2Cbits.TH=1;
    
}

void vicInit(void)
{
 //割り込みテーブルaddress設定----------------------------------
    INTCON0bits.GIE=0;//Enable all masked interrupts
    IVTLOCK=0x55;
    IVTLOCK=0xAA;
    IVTLOCKbits.IVTLOCKED=0;
    IVTBASE = 0x000008;
    IVTLOCK=0x55;
    IVTLOCK=0xAA;
    IVTLOCKbits.IVTLOCKED=1;
}

uint16_t strToInt16(uint8_t *ch, uint8_t _length)
{
    uint8_t i;
    uint16_t ret;
    ret = strtol(ch,NULL,16);
}
```


```C:Q_Peripheral.c

#include "Q_peripheral27Q43.h"

//*****************************************************//
//USART初期化
//*****************************************************//
_rxUsart rxUsart;
void usartInit(void)
{
    //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    U1RXPPS=0b010111;//RC7:rx
    RC6PPS=0x20;//RC6:tx
    TRISC|=0x80;
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    
    
    //1.ボーレート設定115200
    U1BRG=SET_SPBRG_DATA1;
    //2.モード　非同期
    U1CON0bits.MODE=0b0000; //Asynchronous 8-bit USART mode
    //4.Serial port enabled
    U1CON1bits.ON=1;
    //5.Transmit is enabled.
    U1CON0bits.TXEN=1;
    U1CON0bits.RXEN=1;
    
    //7.interrupt
    PIR4bits.U1RXIF=0;
    PIE4bits.U1RXIE=1; 
    
}

void putch(uint8_t _txData)
{
    if(U1ERRIRbits.TXMTIF==High)//ｼﾌﾄﾚｼﾞｽﾀ空?
    {
        do{
            U1TXB=_txData;
            while(U1ERRIRbits.TXMTIF==Low);
        }while(U1FIFObits.TXBF);//TXﾊﾞｯﾌｧ空になるまで送信。
    }else{
        //error operation
    }
}

uint8_t getch(void)
{
    while(PIR4bits.U1RXIF==Low);//受信完了
    return U1RXB;
}

uint8_t usartTxData[20];
void myUsartPrint(uint8_t *txBuf, uint8_t _length)
{
    do{
        putch(*txBuf++);
    }while(--_length);
}
//*****************************************************//
//Timer0初期化
//*****************************************************//
_tm tm0;
void timer0Init(void)
{
//Timer0初期化--------------------------------------------------
    T0CON1bits.CS=0b010;//クロックソースFosc/4
    T0CON1bits.CKPS=0b0011;//プリスケ1:8
    T0CON0bits.MD16=1;//16bitsタイマー
    T0CON0bits.OUTPS=0b0000;//ﾎﾟｽﾄｽｹｰﾗ1:1
    TMR0H=0xD8;//10ms Fosc=32Mhz
    TMR0L=0xF0;//10ms 
    T0CON0bits.EN=1;
    PIE3bits.TMR0IE=1;
    PIR3bits.TMR0IF=0;
}


/*---------------------------------------------------
 Timer1
 ---------------------------------------------------*/
_tm tm1;
void timer1Init(void)
{
    T1CLK=1;//Fosc/4
    T1CONbits.CKPS=0b11; //1:8
    T1CONbits.RD16=1;//16bits.Timer
    T1CLK=0b00001;//Fosc/4
    TMR1H=0xD8;//Fosc=32 10ms
    TMR1L=0xF0;
    T1CONbits.ON=1;
    PIR3bits.TMR1IF=0;
    PIE3bits.TMR1IE=1;
}


/*---------------------------------------------------
 Timer3
 ---------------------------------------------------*/
_tm tm3;
void timer3Init(void)
{
    T3CONbits.CKPS=0b11; //1:8
    T3CONbits.RD16=1;//16bits.Timer
    T3CLK=0b00001;//Fosc/4
    TMR3H=0x00;
    TMR3L=0x00;
    T3CONbits.ON=1;
    PIR5bits.TMR3IF=0;
    PIE5bits.TMR3IE=1;
}
/*---------------------------------------------------
 Timer2
 ---------------------------------------------------*/
_tm tm2;
void timer2Init(void)
{
    TMR2=0x00;
    T2CONbits.T2CKPS=0b100;//prescle1:16
    T2CONbits.OUTPS=0b0001;//postScaler 1:2
    T2HLTbits.PSYNC=1;//synchoronized to Fosc/4
    T2CLKCONbits.CS=0b00001;//Fosc/4
    //PR2=0x1F;//Fosc=32Mhz 1ms 16,16
    PR2=0x19;//32Mhz 0.1ms 16,2
    tm2.cnt=0;
    tm2.fg=false;        
    PIR3bits.TMR2IF=0;
    PIE3bits.TMR2IE=1;
    T2CONbits.TMR2ON=1;
}

/*---------------------------------------------------
 Timer4
 ---------------------------------------------------*/
_tm tm4;
void timer4Init(void)
{
    TMR4=0x00;
    T4CONbits.OUTPS=0b1111;//postScaler 1:16
    T4CONbits.T4CKPS=0b111;//prescle1:128
    T4HLTbits.PSYNC=1;//synchoronized to Fosc/4
    T4CLKCONbits.CS=0b00001;//Fosc/4
    //PR4=0x1F;//Fosc=32Mhz 1ms
    PR4=0x27;//Fosc=32Mhz 10ms
    tm4.cnt=0;
    tm4.fg=false;        
    PIR11bits.TMR4IF=0;
    PIE11bits.TMR4IE=0;
    T4CONbits.TMR4ON=0;
}

/*---------------------------------------------------
 Timer6
 ---------------------------------------------------*/
_tm tm6;
void timer6Init(void)
{
    TMR6=0x00;
    T6CONbits.T6CKPS=0b101;//prescle1:32
    T6CONbits.OUTPS=0b1111;//postScaler 1:16
    T6HLTbits.PSYNC=1;//synchoronized to Fosc/4
    T6CLKCONbits.CS=0b00001;//Fosc/4
    //PR6=0xEA;//Fosc=32Mhz 5ms  pre1:128,post1:16
    //PR6=0x27;//Fosc=32Mhz 10ms pre1:128,post1:16
    T6PR=0xEA; //Fosc=32Mhz 15ms pre1: 32,post1:16
    
    tm6.cnt=0;
    tm6.fg=false;        
    PIR15bits.TMR6IF=0;
    PIE15bits.TMR6IE=0;
    T6CONbits.TMR6ON=1;
}


//*****************************************************//
//ioc初期化
//*****************************************************//
 _ioc ioc;
void iocInit(void)
{
    IOCCNbits.IOCCN0=1;//RC0
    TRISC|=0x01;//RC0
    PIE0bits.IOCIE=1;
    PIR0bits.IOCIF=0;
}

//******************************************************//
// * ADC初期化
// *****************************************************//
_adc adcData;
#define ADC_AverageMode
#ifdef ADC_BasicMode
void adcInit(void)
{
    ADCON0bits.FM=1;//Right justified
    ADCON0bits.CS=0;//Fosc
    ADREFbits.NREF=0;//connected Vss
    ADREFbits.PREF=0b00;//connected Vdd
    ADACTbits.ACT=0b00100;//TMR2 postscaled.
    ADPCH=2;//RA2 ANA2
    adcData.ch[0]=2;
    //port設定
    TRISA|=0x04;//RA2:input 
    ANSELA|=0x04;//RA2:ANA4; 
    //割込み許可
    PIR1bits.ADIF=0;
    PIE1bits.ADIE=1;
    ADCON0bits.ON=1;
    //Trigger Timer begins
    timer2Init();
}
#endif 
#ifdef ADC_AverageMode
void adcInit(void)
{
    ADCON0bits.FM=1;//Right justified
    ADCON0bits.CS=0;//Fosc
    ADCLK=15;
    //Avarage MODE sample=16
    ADCON2bits.MD=0b010;//Average Mode
    ADCON2bits.CRS=3;//divied by 2^4=16;
    ADRPT=8;
    
    ADREFbits.NREF=0;//connected Vss
    ADREFbits.PREF=0b00;//connected Vdd
    ADACTbits.ACT=0b00100;//TMR2 postscaled.
    
    
    //acquisition time Tacq=7us
    ADACQ = 224;            //Tosc=1/32Mhz = 1/32 us =0.03125us
    
    ADPCH=0;
    adcData.ch[0]=0;
    //port設定
    TRISA|=0x03;
    ANSELA|=0x03;
    //割込み許可
    PIR1bits.ADIF=0;
    PIE1bits.ADIE=1;
    ADCON0bits.ON=1;
    //Trigger Timer begins
    timer2Init();
}
#endif

//******************************************************//
// * CCP1 PWM初期化
// *****************************************************//
void CCP1_PWM_Init(void)
{
    
    CCP1CONbits.CCP1MODE=0b1100;//PWMmode
    CCP1CONbits.CCP1FMT=0b0;
    CCPR1=0x00;
    CCPTMRS0bits.C1TSEL=0b11;//Timer6
    //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    RB0PPS=0x15;//CCP1 output
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    
    CCP1CONbits.CCP1EN=1;
}

//******************************************************//
// * CCP2 PWM初期化
// *****************************************************//
void CCP2_PWM_Init(void)
{
    
    CCP2CONbits.CCP2MODE=0b1100;//PWMmode
    CCP2CONbits.CCP2FMT=0b0;
    CCPR2=0x00;
    CCPTMRS0bits.C2TSEL=0b11;//Timer6
    //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    RB1PPS=0x16;//CCP2 output
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    
    CCP2CONbits.CCP2EN=1;
}

//******************************************************//
// * CCP1 キャプチャー初期化
// *****************************************************//
volatile _CCP1 CCP1;
void CCP1_CaptureInit(void)
{
    CCP1CONbits.MODE=0b0101;//every rising edge
    CCPTMRS0bits.C1TSEL=0b10;//Timer3
    CCP1CAP=0x00;//Pin selected by CCP1PPS
    
    //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    CCP1PPS=0b010010;//RC2
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    TRISC|=0x04;//RC2 input
    //interrupt
    PIR3bits.CCP1IF=0;
    PIE3bits.CCP1IE=1;
    CCP1CONbits.CCP1EN=1;
}


//******************************************************//
// * PWM1 初期化
// *****************************************************//
void pwm1Init(void)
{
    PWM1CLK=0x05;//MFINTOSC 500khz
    PWM1PR=0x00EA;//15ms
    //PWM1PR=0x7EF;//100ms
    
    //PWM1PR=0x02FFF;
    PWM1CPRE=0x20;//prescaler
    PWM1S1P1H=0x00;
    PWM1S1P1L=0x00;
    PWM1S1CFG=0x00;
    
    //Clear PWM1_16BIT period interrupt flag
    PIR4bits.PWM1PIF = 0;
    //Clear PWM1_16BIT interrupt flag
    PIR4bits.PWM1IF = 0;  
    //Clear PWM1_16BIT slice 1, output 1 interrupt flag
    PWM1GIRbits.S1P1IF = 0;
    //Clear PWM1_16BIT slice 1, output 2 interrupt flag
    PWM1GIRbits.S1P2IF = 0;
    //PWM1_16BIT interrupt enable bit
    PIE4bits.PWM1IE = 0;
    //PWM1_16BIT period interrupt enable bit
    PIE4bits.PWM1PIE = 0;
   
    //PPS
     //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    RB2PPS=0x18;
    RB3PPS=0x19;
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    PWM1CONbits.EN=1;
}

//******************************************************//
// * PWM2 初期化
// *****************************************************//
void pwm2Init(void)
{
    PWM2CLK=0x05;//MFINTOSC 500khz
    PWM2PR=0x00EA;//15ms
    //PWM2PR=0x7EF;//100ms
    //PWM2PR=0x02FFF;
    PWM2CPRE=0x20;//prescaler
    PWM2S1P1H=0x00;
    PWM2S1P1L=0x00;
    PWM2S1CFG=0x00;
    
    //Clear PWM1_16BIT period interrupt flag
    PIR5bits.PWM2PIF = 0;
    //Clear PWM1_16BIT interrupt flag
    PIR5bits.PWM2IF =0;
    //Clear PWM1_16BIT slice 1, output 1 interrupt flag
    PWM2GIRbits.S1P1IF=0;
    //Clear PWM1_16BIT slice 1, output 2 interrupt flag
    PWM2GIRbits.S1P2IF =0;
    //PWM1_16BIT interrupt enable bit
    PIE5bits.PWM2IE=0;
    //PWM1_16BIT period interrupt enable bit
    PIE5bits.PWM2PIE=0;
   
    //PPS
     //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    RB4PPS=0x1A;
    RB5PPS=0x1B;
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    PWM2CONbits.EN=1;
}

//******************************************************//
// * PWM3 初期化
// *****************************************************//
void pwm3Init(void)
{
    PWM3CLK=0x05;//MFINTOSC 500khz
    PWM3PR=0x00EA;//15ms
    //PWM3PR=0x7EF;//100ms
    //PWM3PR=0x02FFF;
    PWM3CPRE=0x20;//prescaler
    PWM3S1P1H=0x00;
    PWM3S1P1L=0x00;
    PWM3S1CFG=0x00;
    
    //Clear PWM1_16BIT period interrupt flag
    PIR7bits.PWM3PIF = 0;
    //Clear PWM1_16BIT interrupt flag
    PIR7bits.PWM3IF =0;
    //Clear PWM1_16BIT slice 1, output 1 interrupt flag
    PWM3GIRbits.S1P1IF=0;
    //Clear PWM1_16BIT slice 1, output 2 interrupt flag
    PWM3GIRbits.S1P2IF =0;
    //PWM1_16BIT interrupt enable bit
    PIE7bits.PWM3IE=0;
    //PWM1_16BIT period interrupt enable bit
    PIE7bits.PWM3PIE=0;
   
    //PPS
     //6.PPS
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 0;//Unlock.
    //RC5PPS=0x1C;
    //RC2PPS=0x1D;
    RD0PPS=0x1C;
    RD1PPS=0x1D;
    PPSLOCK = 0x55; 
    PPSLOCK = 0xAA;
    PPSLOCKbits.PPSLOCKED = 1;//lock.
    PWM3CONbits.EN=1;
}

```

```C:interrupt.c
#include "Q_interrupt27Q43.h"

//****************割り込み関数***********************//
// USART1割込み
//**************************************************//
void __interrupt(irq(IRQ_U1RX)) USART1RX_ISR(void)
{
    uint8_t ch;
    PIR4bits.U1RXIF=0;
    ch=getch();
    rxUsart.buf[rxUsart.length++]=ch;
    if(rxUsart.length>RXUSART_BUFFER_SIZE)
    {
        rxUsart.length=0;
    }
    if(ch==0x0a)
    {
        rxUsart.buf[rxUsart.length-2]=0x00;
        PIE4bits.U1RXIE=0;
        rxUsart.completed=1;
    }
}

//****************割り込み関数***********************//
// Timer0割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR0)) Timer0_ISR(void)
{
    PIR3bits.TMR0IF=0;
    tm0.cnt++;
    TMR0L=0xF0;//10ms
    if(tm0.cnt==50)
    {
        tm0.cnt=0;
        tm0.fg=true;
        T0CON0bits.EN=0;
        PIE3bits.TMR0IE=0;
    }
    
}
//****************割り込み関数***********************//
// Timer1割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR1)) Timer1_ISR(void)
{
    PIR3bits.TMR1IF=0;
    tm1.cnt++;
    TMR1L=0xF0;
    if(tm1.cnt==1)
    {
        tm1.cnt=0;
        tm1.fg=true;
        T1CONbits.ON=0;
        PIE3bits.TMR1IE=0;
    }
}


//****************割り込み関数***********************//
// Timer2割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR2)) Timer2_ISR(void)
{
    PIR3bits.TMR2IF=0;
    PIE3bits.TMR2IE=0;
}

//****************割り込み関数***********************//
// Timer3割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR3)) Timer3_ISR(void)
{
    PIR5bits.TMR3IF=0;
    CCP1.cnt[1]++;     

    if(CCP1.cnt[1]>10)
    {   
        CCP1.cnt[0]=0x00;
        CCP1.cnt[1]=0x00;
        CCP1.index=0;
        CCP1.val[0]=0x0000;
        CCP1.val[1]=0x0000;
        CCP1.flag=true;  
        CCP1.Tupflag=true;
    }
}


//****************割り込み関数***********************//
// Timer4割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR4)) Timer4_ISR(void)
{
    PIR11bits.TMR4IF=0;
    PORTBbits.RB2=~PORTBbits.RB2;
   // PIE11bits.TMR4IE=1;
   // T4CONbits.TMR4ON=1;
}
//****************割り込み関数***********************//
// Timer6割込み
//**************************************************//
void __interrupt(irq(IRQ_TMR6)) Timer6_ISR(void)
{
    PIR15bits.TMR6IF=0;
    PORTBbits.RB2=~PORTBbits.RB2;
   // PIE11bits.TMR4IE=1;
   // T4CONbits.TMR4ON=1;
}
//****************割り込み関数***********************//
// IOC割込み
//**************************************************//
void __interrupt(irq(IRQ_IOC)) IOC_ISR(void)
{
    uint8_t val;
    
    PIR0bits.IOCIF=0;
    val=IOCCF;
    if(IOCCNbits.IOCCN0==1 && val==0x01)
    {
        ioc.fg=true; 
        PIE0bits.IOCIE=0;
    }
    //zero clear--------------
    val=0xFF;
    val=val^IOCCF;
    IOCCF&=val;
}

//****************割り込み関数***********************//
// ADC割込み
//**************************************************//
void __interrupt(irq(IRQ_AD)) ADC_ISR(void)
{
    PIR1bits.ADIF=0;
   
    //adcData.val[0]=(uint16_t)((ADRESH << 8) + ADRESL);

    if(ADCNT==ADRPT)
    {
        if(ADPCH==0)
        {
            adcData.val[0]=ADFLTR;
            
            ADPCH=1;
        }else
        {
            if(ADPCH==1)
            {
                adcData.val[1]=ADFLTR;
                ADFLTR=0x0000;
                ADPCH=0;
                PIE3bits.TMR2IE=0;
                T2CONbits.TMR2ON=0;
                PIE1bits.ADIE=0;
                //ADCON0bits.ON=0;
                adcData.completed=true;
            }
        }
    }                 
}

//****************割り込み関数***********************//
// CCP1キャプチャー割込み
//**************************************************//
void __interrupt(irq(IRQ_CCP1)) CCP1_ISR(void)
{
    PIR3bits.CCP1IF=0;
    CCP1.val[CCP1.index]=((uint16_t)CCPR1H)<<8;
    CCP1.val[CCP1.index++]|=CCPR1L;
    if(CCP1.index==2)
    {
        CCP1.flag=true;
        CCP1.index=0;
        CCP1CONbits.CCP1EN=0;
        PIE3bits.CCP1IE=0;
       
        T3CONbits.ON=0;
        PIE5bits.TMR3IE=0;
        TMR3H=0x00;
        TMR3L=0x00;
        
      
    }
}

```