0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32入門學(xué)習(xí)筆記之外置FLASH讀寫實(shí)驗(yàn)(下)

jf_78858299 ? 來(lái)源:滑小稽筆記 ? 作者:電子技術(shù)園地 ? 2023-02-16 14:13 ? 次閱讀

(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; ipageremain
     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
    ROM
    +關(guān)注

    關(guān)注

    4

    文章

    575

    瀏覽量

    85934
  • STM32
    +關(guān)注

    關(guān)注

    2271

    文章

    10923

    瀏覽量

    357219
  • EEPROM
    +關(guān)注

    關(guān)注

    9

    文章

    1033

    瀏覽量

    81890
收藏 人收藏

    評(pí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
    的頭像 發(fā)表于 02-16 14:10 ?9159次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>入門</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b><b class='flag-5'>之外置</b><b class='flag-5'>FLASH</b><b class='flag-5'>讀寫實(shí)驗(yàn)</b>(上)

    【GD32F470紫藤派開發(fā)板使用手冊(cè)】第十二講 SDIO-SD卡讀寫實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?SDIO操作原理 ?SD卡讀寫實(shí)現(xiàn)
    的頭像 發(fā)表于 05-18 09:36 ?1465次閱讀
    【GD32F470紫藤派開發(fā)板使用手冊(cè)】第十二講 SDIO-SD卡<b class='flag-5'>讀寫實(shí)驗(yàn)</b>

    如何對(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次閱讀
    接觸式IC卡<b class='flag-5'>讀寫實(shí)驗(yàn)</b>

    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次閱讀

    STM32_ SPI讀寫Flash

    STM32_SPI讀寫Flash
    的頭像 發(fā)表于 04-08 10:26 ?5648次閱讀
    <b class='flag-5'>STM32</b>_ SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>

    單片機(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次下載
    單片機(jī)<b class='flag-5'>實(shí)驗(yàn)</b>匯編--擴(kuò)展存儲(chǔ)器<b class='flag-5'>讀寫實(shí)驗(yàn)</b>

    STM32內(nèi)部Flash讀寫問題

    STM32Flash讀寫Flash調(diào)試技巧文章目錄先熟悉所用MCU的Flash存儲(chǔ)大小以及扇區(qū)地址Flsah寫之前為什么要先擦除Flash
    發(fā)表于 12-01 20:21 ?20次下載
    <b class='flag-5'>STM32</b>內(nèi)部<b class='flag-5'>Flash</b><b class='flag-5'>讀寫</b>問題

    STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(一)

    STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(一)??此系列文章是小白學(xué)習(xí)
    發(fā)表于 12-02 12:06 ?19次下載
    <b class='flag-5'>STM32</b>F103<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>——SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>(一)

    STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(三)

    ??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.
    發(fā)表于 12-22 19:29 ?11次下載
    <b class='flag-5'>STM32</b>F103<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>——SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>(三)

    STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(二)

    ??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.軟件設(shè)計(jì)流程2.SPI初
    發(fā)表于 12-22 19:30 ?10次下載
    <b class='flag-5'>STM32</b>F103<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>——SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>(二)

    STM32F103學(xué)習(xí)筆記——SPI讀寫Flash(四)

    ??此系列文章是小白學(xué)習(xí)STM32的一些學(xué)習(xí)筆記。小白第一次寫筆記文章,有不足或是錯(cuò)誤之處,請(qǐng)多體諒和交流!目錄1.main函數(shù)編寫2.下載
    發(fā)表于 12-22 19:32 ?6次下載
    <b class='flag-5'>STM32</b>F103<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>——SPI<b class='flag-5'>讀寫</b><b class='flag-5'>Flash</b>(四)

    外置FLASH讀寫實(shí)驗(yàn)

    Flash,全名叫做Flash EEPROM Memory,即平時(shí)所說(shuō)的“閃存”,它結(jié)合了ROM和RAM的長(zhǎng)處,不僅可以反復(fù)擦除,還可以快速讀取數(shù)據(jù),STM32運(yùn)行的程序其實(shí)就是存放在Flas
    的頭像 發(fā)表于 03-01 14:56 ?4982次閱讀

    【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二十三講 SDIO-SD卡讀寫實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?SDIO操作原理 ?SD卡讀寫實(shí)現(xiàn)
    的頭像 發(fā)表于 06-23 10:49 ?705次閱讀
    【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二十三講 SDIO-SD卡<b class='flag-5'>讀寫實(shí)驗(yàn)</b>