分享一个代码模块,网上找的一个STM32的SPI2通讯的FM25CL64历程,我自己结合自己的板子改成SPI1很快成功了。1FM25CL64确实简单,通讯和使用都比W25Q64容易
2写之前没有必要擦除 类似EEPROM
先看我板子原理图
两个存储设备挂在SPI1上,CS脚铁电就是PA4
上代码:
- #ifndef __FM25CL64_H_
- #define __FM25CL64_H_
- #include "sys.h"
- #define FM25CL64_CS PAout(4) //FM25CL64片选
- ////FM25CL64指令定义
- #define FM25CL64_WREN 0x06 //使能
- #define FM25CL64_WRDI 0x04 //失能
- #define FM25CL64_RDSR 0x05 //读状态
- #define FM25CL64_WRSR 0x01 //写状态
- #define FM25CL64_READ 0x03 //读数据
- #define FM25CL64_WRITE 0x02 //写数据
- void fm25cl64_init(void);//初始化
- uint8_t fm25cl64_read_sr(void);//读状态
- void fm25cl4_write_sr(uint8_t sr);//写状态
- void fm25cl64_write_enable(void);//使能
- void fm25cl64_write_disable(void);//失能
- void fm25cl6_read_nbyte(uint8_t *pbuff, uint16_t read_addr, uint16_t read_byte);//连续读取N个字节
- void fm25cl6_write_nbyte(uint8_t *pbuff, uint16_t write_addr, uint16_t write_byte);//连续写入N个字节
- uint8_t fm25cl6_read_1byte(uint16_t read_addr);//读取一个字节
- void fm25cl6_write_1byte(uint16_t write_addr, uint8_t write_data);//写入一个字节
- void fm25cl6_clear_data(uint16_t write_addr, uint8_t len);//清除LEN长度数据
- #endif
复制代码
- #include "fm25cl64.h"
- #include "spi.h"
- /*********************************************************************************************************
- **函数名称: void fm25cl64_init(void)
- **函数功能:fm25cl64初始化
- **入口参数:无
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl64_init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_SetBits(GPIOA, GPIO_Pin_4);
- FM25CL64_CS=1; //SPI FLASH不选中
- SPI1_Init(); //初始化SPI
- SPI1_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
- }
- /*********************************************************************************************************
- **函数名称: fm25cl64_read_sr
- **函数功能:读取fm25cl64状态
- **入口参数:无
- **返回值:读取到的字节
- **注释:
- **********************************************************************************************************/
- uint8_t fm25cl64_read_sr(void)
- {
- uint8_t byte = 0;
-
- FM25CL64_CS = 0; //片选
- SPI1_ReadWriteByte(FM25CL64_RDSR); //写入读状态命令
- byte = SPI1_ReadWriteByte(0xFF); //写一个空字节再读数据
- FM25CL64_CS = 1; //取消片选
-
- return byte; //返回数据
- }
- /*********************************************************************************************************
- **函数名称: fm25cl64_write_sr
- **函数功能:写fm25cl64状态
- **入口参数:状态数据
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl4_write_sr(uint8_t sr)
- {
- FM25CL64_CS = 0; //片选
- SPI1_ReadWriteByte(FM25CL64_WRSR);//写入写状态命令
- SPI1_ReadWriteByte(sr); //写入状态数据
- FM25CL64_CS = 1; //取消片选
- }
- /*********************************************************************************************************
- **函数名称: fm25cl64_write_enable
- **函数功能:使能FM25CL64
- **入口参数:无
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl64_write_enable(void)
- {
- FM25CL64_CS = 0;//片选
- SPI1_ReadWriteByte(FM25CL64_WREN);//写入写使能命令
- FM25CL64_CS = 1;//取消片选
- }
- /*********************************************************************************************************
- **函数名称: fm25cl64_write_disable
- **函数功能:失能FM25CL64
- **入口参数:无
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl64_write_disable(void)
- {
- FM25CL64_CS = 0;//片选
- SPI1_ReadWriteByte(FM25CL64_WRDI);//写入写失能命令
- FM25CL64_CS = 1;//取消片选
- }
- /*********************************************************************************************************
- **函数名称: fm25cl6_read_nbyte
- **函数功能:连续读取N字节数据
- **入口参数:*pbuff,读取数据到指针,,read_addr,读数据首址,,read_byte,读多少字节
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl6_read_nbyte(uint8_t *pbuff, uint16_t read_addr, uint16_t read_byte)
- {
- uint16_t i;
-
-
- FM25CL64_CS = 0;//片选
- SPI1_ReadWriteByte(FM25CL64_READ);//写入读数据命令
- SPI1_ReadWriteByte((uint8_t)((read_addr&0xE0)>>8));//写入高8位址,最大地址13位
- SPI1_ReadWriteByte((uint8_t)(read_addr));//写入低8位址,
-
- for(i=0;i<read_byte;i++)//连续读取数据
- {
- pbuff[i] = SPI1_ReadWriteByte(0xFF);
- }
- FM25CL64_CS = 1;//取消片选
-
- }
- /*********************************************************************************************************
- **函数名称: fm25cl6_write_nbyte
- **函数功能:连续写入N字节数据
- **入口参数:*pbuff,写入的数据指针,,write_addr,写入数据首址,,write_byte写多少字节
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl6_write_nbyte(uint8_t *pbuff, uint16_t write_addr, uint16_t write_byte)
- {
- uint16_t i;
-
- fm25cl64_write_enable();//使能写操作,一定要先使能,取消片选后再写作下面操作
-
- FM25CL64_CS = 0;//片选
-
- SPI1_ReadWriteByte(FM25CL64_WRITE);//写数据命令
- SPI1_ReadWriteByte((uint8_t)((write_addr&0xE0)>>8));//写入高8位址,最大地址13位
- SPI1_ReadWriteByte((uint8_t)(write_addr));//写入低8位址,
-
- for(i=0;i<write_byte;i++)//连续写入数据
- {
- SPI1_ReadWriteByte(pbuff[i]);
- }
- FM25CL64_CS = 1;//取消片选
- }
- /*********************************************************************************************************
- **函数名称: fm25cl6_read_data_1byte
- **函数功能:读1字节数据
- **入口参数:read_addr,读取数据地址
- **返回值:返回读取的数据
- **注释:
- **********************************************************************************************************/
- uint8_t fm25cl6_read_1byte(uint16_t read_addr)
- {
- uint8_t dat;
-
- FM25CL64_CS = 0;//片选
-
- SPI1_ReadWriteByte(FM25CL64_READ);//写入读数据命令
- SPI1_ReadWriteByte((uint8_t)((read_addr)>>8));//最大地址13位
- SPI1_ReadWriteByte((uint8_t)(read_addr));//
-
- dat = SPI1_ReadWriteByte(0xFF);//读一字节数据
- FM25CL64_CS = 1;//取消片选
- return dat;
- }
- /*********************************************************************************************************
- **函数名称: fm25cl6_read_data_1byte
- **函数功能:写入1字节数据
- **入口参数:write_addr,写入数据地址,,write_data,写入的数据
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl6_write_1byte(uint16_t write_addr, uint8_t write_data)
- {
-
- fm25cl64_write_enable();//使能写操作,一定要先使能,取消片选后再写作下面操作
-
-
- FM25CL64_CS = 0;//片选
-
- SPI1_ReadWriteByte(FM25CL64_WRITE);//写数据命令
- SPI1_ReadWriteByte((uint8_t)((write_addr)>>8));//最大地址13位
- SPI1_ReadWriteByte((uint8_t)(write_addr));//
-
- SPI1_ReadWriteByte(write_data);//写一字节数据
- FM25CL64_CS = 1;//取消片选
- }
- /*********************************************************************************************************
- **函数名称: fm25cl6_clear_data
- **函数功能:清除指定长度数据
- **入口参数:write_addr,清除数据地址,,len,清除的数据长度
- **返回值:无
- **注释:
- **********************************************************************************************************/
- void fm25cl6_clear_data(uint16_t write_addr, uint8_t len)
- {
-
- fm25cl64_write_enable();//使能写操作,一定要先使能,取消片选后再写作下面操作
-
-
- FM25CL64_CS = 0;//片选
-
- SPI1_ReadWriteByte(FM25CL64_WRITE);//写数据命令
- SPI1_ReadWriteByte((uint8_t)((write_addr)>>8));//最大地址13位
- SPI1_ReadWriteByte((uint8_t)(write_addr));//
-
- while(len--)
- {
- SPI1_ReadWriteByte(0x00);//
- }
-
- FM25CL64_CS = 1;//取消片选
- }
复制代码 其实如果面向接口编程,模块调用SPI的函数SPI1_ReadWriteByte还可以抽象,以备可以切换为SPIX_ReadWriteByte。
测试代码
- fm25cl64_init();
- fm25cl6_write_1byte(0,0xAB);
- GG=fm25cl6_read_1byte(0);
- // fm25cl6_clear_data(0,1);
- fm25cl6_write_1byte(0,0xCD);
- GG=fm25cl6_read_1byte(0);
复制代码
|
十多年来一ˊ直在用 24C64 的 FRAM 路过...