如何确定flash和spi連接?來源:百問網_嵌入式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套