PIC三昧(14) MSSP(SPI)で23LC512にRWしてみる、PIC16F18855

Joseph Halfmoon

前回はI2C(マスタ)の接続の練習にMicroChip社製24LC64 シリアルE2PROMを使用しました。今回はSPI(マスタ)の接続練習に、やはりMicroChip社製の23LC512 シリアルSRAMを使用してみます。PIC16Fと同じMicroChip社製品なのだから繋がらん筈がないっと。

『PIC三昧』PIC関係の記事総目次はこちら

※作業はMicroChip社の統合開発環境 MPLAB X IDEと、その上で走るコンフィギュレーションツールMCC Classic を使用して行っています。ターゲット・マイコンはPIC16F18855です。

MSSP(Master Synchronous Serial Port)のSPI使い

前回は重厚なお名前のペリフェラルMSSPをI2Cマスタとして使用してみました。今回はSPIマスタです。I2Cスレーブ、SPIスレーブとして設定することもできるので、ようやくその機能の半分だけエクササイズしたって感じですが。

SPI接続するのは23LC512、マイクロチップ社のSRAM

接続してみるのは前回につづいてメモリです。SPIシリアル接続の512KビットSRAMです。8x64K構成です。

23LC512

通常のSPIモード以外にSDI、SQIモードもサポートしており、より高速な伝送が可能です。ただし、今回はフツーのSPIモードです。入出力とも接続は1本づつね。5Vでも3.3Vでも動作可能なので、今回は3.3V電源づかいでPIC16F18855の信号線とは直結デス。

MCC Classicでのコンフィギュレーション

さて、前回とほぼ同様に、MSSP1とEUSARTをプロジェクトに取り込むことから始めます。EUSARTは結果をUSBシリアル経由でprintfするためっす。MSSP1_resource

さて、MSSP1の設定が以下に。前回と異なりSPI Masterを設定です。MSSP1_SPI_setting

SPI Modeという欄がありますが、SCKの立ち上がりでサンプリングするか立下りでするか、デフォルトがLoかHiかで4種類の設定があります。相手の周辺装置次第です。今回の23LC512は「素直な」Mode 0でした。データシートの波形など確認しないとなりませぬ。メンドクセー。

さてコンフィギュレーションしたピン配置が以下に。EUSARTのTX/RXはUSBシリアル用にボード上で配線されているので動かせません。MSSP1_PinMGR

PortAのビット0は例によってLチカ用です。また、PortCのビット6は、SPIのCS信号(ソフトウエア制御)用です。

ハードウエアの接続

今回実験したPIC16F18855と23LC512の接続が以下に。PIC16F18855_23LC512_schematic

ブレッドボード上の23LC512との現物接続の様子が以下に。

PIC16F18855_SPI_23LC512

 

今回実験に使ったソース

23LC512は64Kバイトの容量があるのですが、最初の方の255バイトを読み書きしてお茶を濁してます。高速な転送用にページ・リード、ページライトなどのモードももっているのですが、チマチマとバイト単位で、読んで、書いてを繰り返してます。アドレスの下8ビットから1引いたデータを書いて、しばらくお休みしてから同じアドレスのデータを読んで確かめてます。

#include "mcc_generated_files/mcc.h"

void write23LC512(uint16_t adr, uint8_t dat) {
    uint8_t buf[4];
    buf[0] = 0x02;
    buf[1] = (adr >> 8) & 0xFF;
    buf[2] = adr & 0xFF;
    buf[3] = dat;
    RC6=0;
    SPI1_ExchangeBlock(buf, 4);
    RC6=1;
}

uint8_t read23LC512(uint16_t adr) {
    uint8_t buf[4];
    buf[0] = 0x03;
    buf[1] = (adr >> 8) & 0xFF;
    buf[2] = adr & 0xFF;
    buf[3] = 0;
    RC6=0;
    SPI1_ExchangeBlock(buf, 4);
    RC6=1;
    return buf[3];
}

void main(void)
{
    uint16_t adr = 1;
    uint8_t dat;
    SYSTEM_Initialize();
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    printf("23LC512 W/R test.\n");
    RC6=1;
    SPI1_Initialize();
    while (1)
    {
        adr = adr < 0xFF ? adr + 1 : 1;
        dat = (uint8_t)(adr - 1);
        SPI1_Open(0);
        write23LC512(adr, dat);
        RA0 = 1;
        __delay_ms(500);
        printf("ADR=0x%04x DATA=0x%02x\n", adr, read23LC512(adr));
        SPI1_Close();
        RA0 = 0;
        __delay_ms(500);
    }
}

読み書き1バイト毎に標準出力に結果を表示すると同時にLチカもしてます。

実機動作確認

USBシリアルに接続した仮想端末(TeratermPro)の画面が以下に。アドレス引く1の値が読み出せておりますがな。Results

あたりまえか。

PIC三昧(13) MSSP(I2C)で24LC64に読み書きしてみる、PIC16F18855 に戻る

PIC三昧(15) MSSP、SPI Slaveモードでデータを受信、PIC16F18855 へ進む