樹莓派4B-SPI讀寫flash-FM25CL16B(同時支持FM25CL64等其它系列Flash)

1.樹莓派SPI介紹

 4B的引腳以下圖所示:git

其中Pin1九、2一、23是SPI0,接口定義以下所示:數組

  • 時鐘(SPI CLK, SCLK)
  • 主機輸出、從機輸入(MOSI)
  • 主機輸入、從機輸出(MISO)

在使用 SPI 接口前,你須要使用 gpio 命令來加載 SPI 驅勱到內核中:函數

gpio load spi

若是您須要的緩衝區大於 4KB,須要在命令行迕行指定緩衝區的大小,單位是 KB:spa

gpio load spi 100

上述命令將會分配 100KB 的緩衝區.(您可能不多須要改變返項謳置,默認值對於絕大多數應用程序來講已經足夠了). 爲了使用 SPI 庫,你也須要在你的程序中添加以下語句:命令行

#include <wiringPiSPI.h>

程序在編譯鏈接時,仍然須要添加-lwiringPi 選項code

須要用到的函數以下所示:blog

int wiringPiSPISetup(int channel, int speed);
//使用該函數能夠初始化一個 SPI 通道,樹莓派有兩個 SPI 通道(0 和 1)。
//speed 參數是一個整數值,其範圍爲 500000~32000000,表明 SPI 時鐘速度,單位是 Hz。
//返回值爲-1,則失敗。則須要檢查一下電路鏈接和是否開啓了樹莓派的SPI。

int wiringPiSPIDataRW(int channel, unsigned char* data, int len);
//該函數執行一個同時讀寫操做,經過選定的 SPI 總線。緩衝區中的數據,將會被 SPI總線的返回數據所覆蓋。

void delay (unsigned int howLong)
//延時ms,最大傳入32位無符號型整數,大約49天。

void delayMicroseconds (unsigned int howLong)
//延時微秒,最大傳入32位無符號型整數,大約71分鐘

 

2.FM25L16B芯片介紹接口

    FM25L16是採用先進的鐵電工藝製造的1024*16位的非易失性存儲器(2048個字節)。鐵電隨機存儲器(FRAM)具備非易失性,而且能夠象RAM同樣快速讀寫。FM25L16中的數據在掉電後能夠保存45年。相對EEPROM或其餘非易失性存儲器,FM25L16具備結構更簡單,系統可靠性更高等諸多優勢。
   與EEPROM系列不一樣的是,FM25L16以總線速度進行寫操做,無須延時。數據發到FM25L16後直接寫到具體的單元地址,下一個總線操做能夠當即開始,無需數據輪詢。此外,FM25L16的讀/寫次數幾乎爲無限次,比EEPROM高得多。同時,FM25L16的功耗也遠比EEPROM低。內存

引腳定義以下所示:string

 

  • /CS: 片選,低電平爲激活設備
  • SCK: SPI輸入時鐘,頻率最高支持20MHZ
  • /HOLD: 輸入保持,好比當咱們在進行讀寫的時候,假如產生了一箇中斷,因爲時序已經在進行了,這時能夠給個低電平讓芯片保持時序,等待中斷處理完成後,再來置高,繼續讀寫數據.
  • /WP: 寫保護,爲低電平則不能寫操做
  • SI、SO: SPI輸入輸出數據引腳

指令以下所示:

 

 

2.1 狀態寄存器(0x01)介紹

狀態寄存器的每一個bit位意義以下所示:

 

其中BP1和BP0是設置寫保護區域的.以下圖所示:

 

咱們必須將BP1和BP0設置爲0,才能夠有寫全部地址的權限.

 

2.2 寫寄存器(0x06)介紹

全部對內存數組的寫入都以WREN(0X06)操做碼開頭,下一個操做碼是WRITE指令,這個操做碼後面跟着一個雙字節地址。地址的前5位將被忽略(最多存儲2048字節),而後就能夠一直寫入數據.最後將CS置高則完成寫操做.

 

3.最終代碼

#include<stdio.h>
#include <cstring>
#include<wiringPi.h>
#include <wiringPiSPI.h>

typedef unsigned char u8;
typedef unsigned short u16;

#define FM25CL16_WREN       0x06       // 寫使能
#define FM25CL16_WRITE      0x02       // 寫寄存器
#define FM25CL16_READ       0x03       // 讀寄存器
#define FM25CL64_WRSR       0x01       // 狀態寄存器
#define FM25L16_CSPIN       21         // 片選引腳

void initSPI()
{
    //初始化所用到的IO引腳
    pinMode(FM25L16_CSPIN, OUTPUT);
    digitalWrite(FM25L16_CSPIN, HIGH);

    //初始化SPI通道0,並設置爲速度
    if(wiringPiSPISetup(0,5000000)==-1) {
        printf("init spi failed!\n");
    }
}


// 片選
void fm25l16Cs(u8 select)
{
    if (select == 0) {
       digitalWrite(FM25L16_CSPIN, LOW);
    } else {
       digitalWrite(FM25L16_CSPIN, HIGH);
    }
}

// 向FLASH寫入一個字節數據
static u8 fm25l16WriteByte(u8 Temp)
{
    return wiringPiSPIDataRW(0,&Temp,1);
}

// FLASH寫使能
static void fm25l16WriteEnable()
{
    fm25l16Cs(0);
    fm25l16WriteByte(FM25CL16_WREN);
    fm25l16Cs(1);

}

// 寫入一串數據
void fm25l16WriteBuff(u16 addr,u8* buff,u16 len)
{
    u8 buffHead[3]; // 數據頭

    fm25l16WriteEnable();
    fm25l16Cs(0);
    buffHead[0] = FM25CL16_WRITE;
    buffHead[1] = (addr&0xFF00)>>8;
    buffHead[2] = (addr&0x00FF);
    wiringPiSPIDataRW(0,buffHead,3);
    wiringPiSPIDataRW(0,buff,len);
    fm25l16Cs(1);
}


// 讀出一串數據到buff中
void fm25l16ReadBuff(u16 addr,u8* buff,u16 len)
{
    u8 buffHead[3]; // 數據頭

    fm25l16Cs(0);
    buffHead[0] = FM25CL16_READ;
    buffHead[1] = (addr&0xFF00)>>8;
    buffHead[2] = (addr&0x00FF);
    wiringPiSPIDataRW(0,buffHead,3);
    wiringPiSPIDataRW(0,buff,len);
    fm25l16Cs(1);
}

// 寫狀態
void fm25l16Status()
{
    u8 buff[2] = {FM25CL64_WRSR, 0X00};
    fm25l16WriteEnable();
    fm25l16Cs(0);
    wiringPiSPIDataRW(0,buff,2); // 取消寫保護
    fm25l16Cs(1);
}

int main()
{
    u8 data[10];
    u8 i=0;
    u8 beginData = 0;
    //初始化wiringPI的庫函數
    if(wiringPiSetup()<0) {
        printf("init wiringPi error\n");
    }
    initSPI();          //spi的初始化
    fm25l16Status();    // 寫狀態寄存器
    while(1) {
        for(i=0;i<10;i++) {
            data[i] = beginData++;
        }
        fm25l16WriteBuff(0,data,10);
        printf("write ok\n");
        fm25l16ReadBuff(0,data,10);
        printf("read: ");
        for(i=0;i<10;i++) {
             printf("%d ",data[i]);
        }
        printf("\n");
        delay(20);
    }
    return 0;
} 

運行效果以下所示:

相關文章
相關標籤/搜索