如何确定flash和spi连接(SPIFLASH编程读ID)
来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版),我来为大家科普一下关于如何确定flash和spi连接?下面希望有你要的答案,我们一起来看看吧!
如何确定flash和spi连接
来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)
作者:韦东山
本文字数:1277,阅读时长:1.5分钟
这节讲解如何使用SPI操作Flash,我们在上节课的代码上进行修改,添加一个文件 spi_flash.c 和其头文件 spi_flash.h 。
我们先做一个最简单的spi操作,读取Flash的ID, SPIFlashID() 。
Flash的ID有厂家ID和设备ID,分别用pMID和pDID来保存。
根据Flash的芯片手册 W25Q16DV.pdf 可以知道需要先发出一个指令0x90,再发送24位的地址0,再读取数据前8位是设备ID,然后是8位设备ID。进行操作前必须要片选SPI Flash,片选完还是释放SPI Flash:
void SPIFlashReadID(int *pMID, int *pDID)
{
SPIFlash_Set_CS(0); /* 选中SPI FLASH */
SPISendByte(0x90);
SPIFlashSendAddr(0);
*pMID = SPIRecvByte();
*pDID = SPIRecvByte();
SPIFlash_Set_CS(1);
}
把其中的发送24地址封装成了一个函数 SPIFlashSendAddr() :
static void SPIFlashSendAddr(unsigned int addr)
{
SPISendByte(addr >> 16);
SPISendByte(addr >> 8);
SPISendByte(addr & 0xff);
}
依次完成上面的子函数,先是SPI片选,上一节的原理图可以看到SPI Flash的片选是GPG2:
static void SPIFlash_Set_CS(char val)
{
if (val)
GPGDAT |= (1<<2);
else
GPGDAT &= ~(1<<2);
}
SPISendByte() 和前面OLED的是一样的,就不用写了,因此就只剩下 SPIRecvByte() ,放在 gpio_spi.c 里面实现:
unsigned char SPIRecvByte(void)
{
int i;
unsigned char val = 0;
for (i = 0; i < 8; i )
{
val <<= 1;
SPI_Set_CLK(0);
if (SPI_Get_DI())
val |= 1;
SPI_Set_CLK(1);
}
return val;
}
在每个时钟周期读取DI引脚上的值,对于SOC就是MISO引脚:
static char SPI_Get_DI(void)
{
if (GPGDAT & (1<<5))
return 1;
else
return 0;
}
至此,读取Flash的ID基本实现,最后在主函数里调用打印,分别在串口和OLED上显示:
SPIFlashReadID(&mid, &pid);
printf("SPI Flash : MID = 0xx, PID = 0xx\n\r", mid, pid);
sprintf(str, "SPI : x, x", mid, pid);
OLEDPrint(4,0,str);
Makefile记得加上新生成的 spi_flash.o 。
「新品首发」STM32MP157开发板火爆预售!首批仅300套
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com