(2)創(chuàng)建w25q128.c并輸入以下代碼。
/*********************************************************************************************************
FLASH 驅(qū) 動(dòng) 程 序
*********************************************************************************************************/
#include "w25q128.h"
#include "delay.h"
/***************************************************
Name :SPI2_SetSpeed
Function :SPI2速度設(shè)置函數(shù)
Paramater :
SpeedSet:0~7
Return :None
***************************************************/
void SPI2_SetSpeed( u8 SpeedSet )
{
SpeedSet &= 0x07 ; //限制范圍
SPI2->CR1 &= 0xFFC7 ;
SPI2->CR1 |= SpeedSet<<3 ; //設(shè)置SPI2速度
SPI2->CR1 |= 1<<6 ; //SPI設(shè)備使能
}
/***************************************************
Name :SPI2_ReadWriteByte
Function :SPI2讀寫一個(gè)字節(jié)
Paramater :
TxData:要寫入的字節(jié)
Return :讀取到的字節(jié)
***************************************************/
u8 SPI2_ReadWriteByte( u8 TxData )
{
u16 retry=0;
//等待發(fā)送區(qū)空
while( ( SPI2->SR&0x02 )==0 )
{
retry ++ ;
//超時(shí)退出
if( retry>=0xFFFE )
return 0 ;
}
SPI2->DR = TxData ; //發(fā)送一個(gè)byte
//等待接收完一個(gè)byte
retry = 0 ;
while( ( SPI2->SR&0x01 )==0 )
{
retry ++ ;
//超時(shí)退出
if( retry>=0xFFFE )
return 0 ;
}
return SPI2->DR ; //返回收到的數(shù)據(jù)
}
/***************************************************
Name :W25QXX_Init
Function :初始化W25Q128芯片
Paramater :None
Return :None
***************************************************/
void W25QXX_Init()
{
RCC->APB2ENR |= 1<<3 ; //PORTB時(shí)鐘使能
GPIOB->CRH &= 0x0000FFFF ;
GPIOB->CRH |= 0xBBB30000 ; //PB12推挽輸出+PB13/14/15復(fù)用
GPIOB->ODR |= 0x7<<13 ; //PB13/14/15上拉
W25QXX_CS = 1 ; //SPI FLASH不選中
//初始化SPI
RCC->APB1ENR |= 1<<14 ; //SPI2時(shí)鐘使能
SPI2->CR1 |= 0<<10 ; //全雙工模式
SPI2->CR1 |= 1<<9 ; //軟件nss管理
SPI2->CR1 |= 1<<8 ;
SPI2->CR1 |= 1<<2 ; //SPI主機(jī)
SPI2->CR1 |= 0<<11 ; //8bit數(shù)據(jù)格式
SPI2->CR1 |= 1<<1 ; //空閑模式下SCK為1 CPOL=1
SPI2->CR1 |= 1<<0 ; //數(shù)據(jù)采樣從第二個(gè)時(shí)間邊沿開始,CPHA=1
//對(duì)SPI2屬于APB1的外設(shè).時(shí)鐘頻率最大為36M
SPI2->CR1 |= 3<<3 ; //Fsck=Fpclk1/256
SPI2->CR1 |= 0<<7 ; //MSBfirst
SPI2->CR1 |= 1<<6 ; //SPI設(shè)備使能
SPI2_ReadWriteByte( 0xFF ) ; //啟動(dòng)傳輸
SPI2_SetSpeed( SPI_SPEED_2 ) ; //設(shè)置為18M時(shí)鐘,高速模式
}
/***************************************************
Name :W25QXX_Wait_Busy
Function :等待空閑
Paramater :None
Return :None
***************************************************/
void W25QXX_Wait_Busy()
{
u8 byte=0 ;
// 等待BUSY位清空
do
{
W25QXX_CS = 0 ; //使能器件
SPI2_ReadWriteByte( W25X_ReadStatusReg ) ; //發(fā)送讀取狀態(tài)寄存器命令
byte = SPI2_ReadWriteByte( 0xFF ) ; //讀取一個(gè)字節(jié)
W25QXX_CS = 1 ; //取消片選
}while( ( byte&0x01 )==0x01 ) ;
}
/***************************************************
Name :W25QXX_Erase_Chip
Function :擦除整個(gè)芯片
Paramater :None
Return :None
***************************************************/
void W25QXX_Erase_Chip()
{
W25QXX_CS = 0 ; //使能器件
SPI2_ReadWriteByte( W25X_WriteEnable ) ; //發(fā)送寫使能
W25QXX_CS = 1 ; //取消片選
W25QXX_Wait_Busy() ;
W25QXX_CS=0 ; //使能器件
SPI2_ReadWriteByte( W25X_ChipErase ) ; //發(fā)送片擦除命令
W25QXX_CS = 1 ; //取消片選
W25QXX_Wait_Busy() ; //等待芯片擦除結(jié)束
}
/***************************************************
Name :W25QXX_Erase_Sector
Function :擦除一個(gè)扇區(qū)
Paramater :
Address:扇區(qū)地址
Return :None
***************************************************/
void W25QXX_Erase_Sector( u32 Address )
{
Address *= 4096 ;
W25QXX_CS = 0 ; //使能器件
SPI2_ReadWriteByte( W25X_WriteEnable ) ; //發(fā)送寫使能
W25QXX_CS = 1 ; //取消片選
W25QXX_Wait_Busy();
W25QXX_CS = 0 ; //使能器件
SPI2_ReadWriteByte( W25X_SectorErase ) ; //發(fā)送扇區(qū)擦除指令
SPI2_ReadWriteByte( ( u8 )( Address>>16 ) ) ; //發(fā)送24bit地址
SPI2_ReadWriteByte( ( u8 )( Address>>8 ) ) ;
SPI2_ReadWriteByte( ( u8 )Address ) ;
W25QXX_CS = 1 ; //取消片選
W25QXX_Wait_Busy() ; //等待擦除完成
}
/***************************************************
Name :W25QXX_Read
Function :在指定地址開始讀取指定長(zhǎng)度的數(shù)據(jù)
Paramater :
pBuffer:數(shù)據(jù)存儲(chǔ)區(qū)
Address:開始讀取的地址
Len:要讀取的字節(jié)數(shù)
Return :None
***************************************************/
void W25QXX_Read( u8 *pBuffer, u32 Address, u16 Len )
{
u16 i ;
W25QXX_CS = 0 ; //使能器件
SPI2_ReadWriteByte( W25X_ReadData ) ; //發(fā)送讀取命令
SPI2_ReadWriteByte( ( u8 )( Address>>16 ) ) ; //發(fā)送24bit地址
SPI2_ReadWriteByte( ( u8 )( Address>>8 ) ) ;
SPI2_ReadWriteByte( ( u8 )Address );
for( i=0; i >16 ) ) ; //發(fā)送24bit地址
SPI2_ReadWriteByte( ( u8 )( Address>>8 ) ) ;
SPI2_ReadWriteByte( ( u8 )Address ) ;
for( i=0; i pageremain
else
{
pBuffer += pageremain ;
Address += pageremain ;
Len -= pageremain ; //減去已經(jīng)寫入了的字節(jié)數(shù)
//一次可以寫入256個(gè)字節(jié)
if( Len>256 )
pageremain = 256 ;
//不夠256個(gè)字節(jié)了
else
pageremain = Len ;
}
}
}
/***************************************************
Name :W25QXX_Write_NoCheck
Function :在指定地址開始寫入指定長(zhǎng)度的數(shù)據(jù)
Paramater :
pBuffer:數(shù)據(jù)存儲(chǔ)區(qū)
Address:開始寫入的地址
Len:要寫入的字節(jié)數(shù)
Return :None
***************************************************/
u8 W25QXX_BUFFER[ 4096 ] ;
void W25QXX_Write( u8 *pBuffer, u32 Address, u16 Len )
{
u32 secpos ;
u16 secoff ;
u16 secremain ;
u16 i ;
u8 *W25QXX_BUF ;
W25QXX_BUF = W25QXX_BUFFER ;
secpos = Address/4096 ; //扇區(qū)地址
secoff = Address%4096 ; //在扇區(qū)內(nèi)的偏移
secremain = 4096-secoff ; //扇區(qū)剩余空間大小
//不大于4096個(gè)字節(jié)
if( Len<=secremain )
secremain = Len ;
while( 1 )
{
W25QXX_Read( W25QXX_BUF, secpos*4096, 4096 ) ; //讀出整個(gè)扇區(qū)的內(nèi)容
//校驗(yàn)數(shù)據(jù)
for( i=0; i<secremain )
{
W25QXX_Erase_Sector( secpos ) ; //擦除這個(gè)扇區(qū)
//復(fù)制
for( i=0; i<secremain; i++ )
W25QXX_BUF[ i+secoff ] = pBuffer[ i ] ;
W25QXX_Write_NoCheck( W25QXX_BUF, secpos*4096, 4096 ) ; //寫入整個(gè)扇區(qū)
}
else
W25QXX_Write_NoCheck( pBuffer, Address, secremain ) ; //寫已經(jīng)擦除了的,直接寫入扇區(qū)剩余區(qū)間
//寫入結(jié)束了
if( Len==secremain )
break ;
//寫入未結(jié)束
else
{
secpos ++ ; //扇區(qū)地址增1
secoff = 0 ; //偏移位置為0
pBuffer += secremain ; //指針偏移
Address += secremain ; //寫地址偏移
Len -= secremain ; //字節(jié)數(shù)遞減
//下一個(gè)扇區(qū)還是寫不完
if( Len> 4096 )
secremain = 4096 ;
//下一個(gè)扇區(qū)可以寫完了
else
secremain = Len ;
}
}
}
(3)在1.c文件中輸入以下代碼。
#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "lcd.h"
#include "w25q128.h"
const u8 TEXT_Buffer[] = { "WarShip STM32F1 SPI TEST" } ;
#define SIZE sizeof( TEXT_Buffer )
int main()
{
u8 datatemp[ SIZE ] ;
u32 FLASH_SIZE ;
STM32_Clock_Init( 9 ) ; //STM32時(shí)鐘初始化
SysTick_Init( 72 ) ; //SysTick初始化
USART1_Init( 72, 115200 ) ; //初始化串口1波特率115200
LCD_Init() ; //LCD初始化
W25QXX_Init() ; //W25QXX初始化
POINT_COLOR = RED ; //設(shè)置字體為紅色
FLASH_SIZE = 128*1024*1024 ; //FLASH 大小為16M字節(jié)
W25QXX_Write( (u8*)TEXT_Buffer, FLASH_SIZE-100, SIZE ) ; //從倒數(shù)第100個(gè)地址處開始,寫入SIZE長(zhǎng)度的數(shù)據(jù)
W25QXX_Read( datatemp, FLASH_SIZE-100, SIZE ) ; //從倒數(shù)第100個(gè)地址處開始,讀出SIZE個(gè)字節(jié)
LCD_ShowString( 0, 0, datatemp ) ; //顯示讀到的字符串
while( 1 )
{
}
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
閃存
+關(guān)注
關(guān)注
16文章
1799瀏覽量
115081 -
FlaSh
+關(guān)注
關(guān)注
10文章
1642瀏覽量
148508 -
ROM
+關(guān)注
關(guān)注
4文章
575瀏覽量
85934 -
STM32
+關(guān)注
關(guān)注
2271文章
10923瀏覽量
357219 -
EEPROM
+關(guān)注
關(guān)注
9文章
1033瀏覽量
81890
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
STM32入門學(xué)習(xí)筆記之外置FLASH讀寫實(shí)驗(yàn)(上)
Flash,全名叫做Flash EEPROM Memory,即平時(shí)所說(shuō)的“閃存”,它結(jié)合了ROM和RAM的長(zhǎng)處,不僅可以反復(fù)擦除,還可以快速讀取數(shù)據(jù),STM32運(yùn)行的程序其實(shí)就是存放在Flas
【GD32F470紫藤派開發(fā)板使用手冊(cè)】第十二講 SDIO-SD卡讀寫實(shí)驗(yàn)
通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
?SDIO操作原理
?SD卡讀寫實(shí)現(xiàn)
如何對(duì)擴(kuò)展存儲(chǔ)器進(jìn)行讀寫實(shí)驗(yàn)?
擴(kuò)展存儲(chǔ)器讀寫實(shí)驗(yàn)的目的是什么?怎樣去設(shè)計(jì)一種擴(kuò)展存儲(chǔ)器讀寫的電路?擴(kuò)展存儲(chǔ)器讀寫實(shí)驗(yàn)的流程有哪些?
發(fā)表于 07-14 07:04
如何通過(guò)對(duì)flash的讀寫實(shí)現(xiàn)stm32的編程操作?
如何通過(guò)對(duì)flash的讀寫實(shí)現(xiàn)stm32的編程操作?
發(fā)表于 10-29 06:19
接觸式IC卡讀寫實(shí)驗(yàn)
接觸式IC卡讀寫實(shí)驗(yàn)
一. 實(shí)驗(yàn)目的了解接觸式IC 卡的知識(shí),
發(fā)表于 09-22 17:20
?4805次閱讀
AVR內(nèi)部EEPROM讀寫實(shí)驗(yàn)
片內(nèi)EEPROM讀寫實(shí)險(xiǎn)。?1、用內(nèi)部EEPROM記錄CPU啟動(dòng)次數(shù),并在PB口上顯示出來(lái)。?2、內(nèi)部1 M晶振,程序采用單任務(wù)方式,軟件延時(shí)。?3、進(jìn)行此實(shí)驗(yàn)請(qǐng)
發(fā)表于 06-30 11:25
?2574次閱讀
單片機(jī)實(shí)驗(yàn)匯編--擴(kuò)展存儲(chǔ)器讀寫實(shí)驗(yàn)
擴(kuò)展存儲(chǔ)器讀寫實(shí)驗(yàn)一.實(shí)驗(yàn)要求編制簡(jiǎn)單程序,對(duì)實(shí)驗(yàn)板上提供的外部存貯器(62256)進(jìn)行讀寫操作。二.實(shí)驗(yàn)目的1.
發(fā)表于 11-23 09:51
?19次下載
STM32內(nèi)部Flash讀寫問題
STM32Flash讀寫之Flash調(diào)試技巧文章目錄先熟悉所用MCU的Flash存儲(chǔ)大小以及扇區(qū)地址Flsah寫之前為什么要先擦除Flash
發(fā)表于 12-01 20:21
?20次下載
STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(一)
STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(一)??此系列文章是小白學(xué)習(xí)
發(fā)表于 12-02 12:06
?19次下載
STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(三)
??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.
發(fā)表于 12-22 19:29
?11次下載
STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(二)
??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.軟件設(shè)計(jì)流程2.SPI初
發(fā)表于 12-22 19:30
?10次下載
STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(四)
??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.main函數(shù)編寫2.下載
發(fā)表于 12-22 19:32
?6次下載
外置FLASH讀寫實(shí)驗(yàn)
Flash,全名叫做Flash EEPROM Memory,即平時(shí)所說(shuō)的“閃存”,它結(jié)合了ROM和RAM的長(zhǎng)處,不僅可以反復(fù)擦除,還可以快速讀取數(shù)據(jù),STM32運(yùn)行的程序其實(shí)就是存放在Flas
【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二十三講 SDIO-SD卡讀寫實(shí)驗(yàn)
通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
?SDIO操作原理
?SD卡讀寫實(shí)現(xiàn)
評(píng)論