PIC32MX370F512F 64pin (１) 事始め

# PIC32MX370F512F事始め


Lチカさせるまでの内容です。PIC16F、PIC18FでTimer,USART,I2C,SPIなどのモジュールを動かした要領で、PIC32MXも動かせると思います。唯一、違うのが、CPUコアがMIPSコアになっているところだけです。実際には、delayマクロをdelay関数として自作するときにCPUコア内部のレジスタにアクセスします。違いは、ここだけで、ペリフェラル機能は、従来のPICマイコンとの違いは、それほどないと感じました。

:::note
# 今回の内容概略
<font color="deeppink">**XC8コンパイラで使用できた__delay_msマクロが、XC32コンパイラにはありません。**</font>

**意図的な遅延を発生させるため、CPUコア内のレジスタを使用します。** ここが、XC8と大きく違うところです。

基本的に、MIPS CPUコアに関する操作は、このディレイと割込みの許可だけで済むはずです。

ペリフェラルの操作に関しては、dsPIC,PIC24Fと大差なく制御できると思います。

※dsPIC、PIC24Fのレジスタ名、ビット名を改変して、I2CやSPIを動かせはずですが、なんせ、2年前なのでかなり忘れてしまいました。
:::

# 回路、基板製作
<img width="300" alt="IMG_5013.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/edb9e544-f389-64bd-b3e2-d0a87e629b82.jpeg">

<img width="300" alt="IMG_5014.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/c0b02f0f-9122-be5b-2c45-98aaffa542d3.jpeg">


<img width="500" alt="IMG_5069.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/6fa23de9-4322-8434-45e1-3d92a3e69c44.jpeg">
AWG30で配線。


<img width="300" alt="データシート回路１.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/ed6bed3d-c151-5f34-a5b3-8c668975a97f.png">




<img width="300" alt="データシート回路２.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/adbfc761-8560-caff-4c35-dd8c84b18989.png">


:::note
回路は、データシートの推奨回路どうり組めば、問題ないです。基本構成は、リセット回路と、電源ライン、書き込み線の配線ですから、この辺は、従来のPICマイコンと同じ回路になっています。
データシートの推奨回路は、MCLRにRとR1、Cを接続していますが、R1とC(0.1uf)をつけませんでした。つけたほうが無難ですが、付けなくても、動作しています。プルアップの”R”は必要です。

ピン数は６４ピンと多いですが、基本回路の電源とリセット回路、書き込み回路は、従来のピックマイコンと同じです。Vcap端子に１０uFを接続するのが少し違うところです。
:::

電源ピンを蛍光ペンで抜き出してみました。
![IMG_5017.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/7f160e37-28dd-14f3-6c21-93bf9190dae2.jpeg)

基本回路は、16F、18Fとさほど変わりません。56番ピンのVcapに10uFのコンデンサをつなげます。

![PIC32MX64pin配.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/7e8cad5e-3409-a2e6-eac3-0b6e84bf7cce.png)

:::note warn
VCCは3.3vで駆動しています。
:::

:::note
IOは、PORTAがありません。PORTB,C,D,E,F,Gという変則的な構成になっています。17番ピンと18番ピンをプログラム書き込み線として使用しています。
書き込み、デバッグ線は複数あるので、特定の一組を、コンフィグレーションビットで指定します。
:::

:::note
32bits PICマイコンですが、中身は、MIPSというCPUコアで動いています。ここが、従来のdsPIC,24F,18F,16Fと違うところです。CPUコアは、別会社が開発して、ペリフェラル機能、たとえば、Timer,PWM,AD変換をMicrochip社が開発しています。
:::

:::note
16F、18Fでは、delayマクロを使用してms,us単位で、遅延を発生させることが簡単にできました。

XC32コンパイラでは、**delayマクロがありません。** **MIPS32コア内にあるCP0レジスタ群の中にある、プロセッサのサイクルカウントレジスタ（CPUクロック2カウントでｲﾝｸﾘﾒﾝﾄ）** の経過時間をポーリングして、delay関数を作成します。


# SYSTEM CONTROL COPROCESSOR (CP0)

delay_ms, delay_us関数を自作するため、<font color="deepPink">CP0のレジスタ操作</font>が必要になってきます。

データシート　セクション 2. M4K® コア搭載デバイス用 CPUDS61113E_JP - p.2-21
レジスタ番号９Countのプロセッササイクル数をポーリングします。

![cp0詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/8d7990b0-3d5e-e579-113a-cccc4cbb1823.png)


データシート PIC32MX330/350/370/430/450/470　DS60001185F　page 37

![coprocesser0レジスタ一覧表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/7e472e52-582d-75ee-b8c0-0324d43ad8fd.png)

データシート XC32 Compiler for PIC32M　DS50002799B-page 105
![cp0レジスタ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/9ed702ed-3159-67c6-f3ae-49d50b6111a1.png)

データシート XC32 Compiler for PIC32M DS50002799B-page 108
![cp0マクロ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3693934/5ddb1176-3eef-c800-3dea-c25b6ff984af.png)

:::

# delayマクロを代替するための、delay関数を作る。

:::note
MIP32CPUコアレジスタであるCoProcesserのサイクルカウンタレジスタを読み出すマクロ
_CP0_GET_COUNT()
_CP0_SET_COUNT(value)
の2つを使います。

関数名は、PIC16F,18F,24F,dsPICのコードを流用したいので、__delay_ms、__delay_usとしておきました。
:::

オシレータは８０Mhzに設定しています。コンフィグレーションビットで指定しています。

```C:main.c

// PIC32MX370F512H Configuration Bit Settings

// 'C' source line config statements

// DEVCFG3
#pragma config USERID = 0xFFFF          // Enter Hexadecimal value (Enter Hexadecimal value)
#pragma config FSRSSEL = PRIORITY_7     // Shadow Register Set Priority Select (SRS Priority 7)
#pragma config PMDL1WAY = OFF           // Peripheral Module Disable Configuration (Allow multiple reconfigurations)
#pragma config IOL1WAY = OFF            // Peripheral Pin Select Configuration (Allow multiple reconfigurations)

// DEVCFG2
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20         // PLL Multiplier (20x Multiplier)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)

// DEVCFG1
#pragma config FNOSC = FRCPLL           // Oscillator Selection Bits (Fast RC Osc with PLL)
#pragma config FSOSCEN = OFF            // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF               // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = OFF            // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor Selection (Clock Switch Enable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25     // Watchdog Timer Window Size (Window Size is 25%)

// DEVCFG0
#pragma config DEBUG = OFF              // Background Debugger Enable (Debugger is Disabled)
#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx1        // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)

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


#include <xc.h>
#include <cp0defs.h> 
#include <sys/attribs.h>

#define SYSCLK      80000000L		// System clock 80Mhz
#define CTCLK		(SYSCLK / 2)    // CoreTimerCLK SystemClock/2
#define CTus 		(CTCLK / 1000000)	// us delay unit Term
#define CTms     	(CTCLK / 1000)	// ms delay unit Term

/**
 * __delay_ms
 * @param _ms
 */
void __delay_ms(long _ms)
{
    long count;
    count=_ms*CTms;
    _CP0_SET_COUNT(0);
    while(_CP0_GET_COUNT()<=count);
}

/**
 * __delay_us
 * @param _us
 */
void __delay_us(long _us)
{
    long count;
    count=_us*CTus;
    _CP0_SET_COUNT(0);
    while(_CP0_GET_COUNT()<=count);
}

void main(void) 
{
    uint32_t i,j;
    
    
    TRISB=0x0000;
   
    ANSELB=0x0000;
   
    PORTB=0x0000;
    
    while(1)
    {
        __delay_ms(500);
        LATBbits.LATB0=~LATBbits.LATB0;
    }
    
    
    return;
}

```
ポートBしか初期化してませんが、本来は、ポートB,C,D,E,F,Gすべて初期化します。