4B的引脚以下图所示:git
其中Pin1九、2一、23是SPI0,接口定义以下所示:数组
在使用 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
指令以下所示:
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; }
运行效果以下所示: