STM32访问外部存储器-NOR-Flash

简介:

基本说明

STM32访问外部存储器是需要配置FSMC的相关函数,在STM32固件库函数说明的中文翻译版中并没有这部分的说明,因此需要参考库函数的相关说明和库中自带的例程。

以下内容来自AN2784应用笔记:

2 与非总线复用模式的异步16位NOR闪存接口

2.1

FSMC配置

控制一个NOR闪存存储器,需要FSMC提供下述功能:

选择合适的存储块映射NOR闪存存储器:共有4个独立的存储块可以用于与NOR闪存、SRAM和PSRAM存储器接口,每个存储块都有一个专用的片选管脚。

使用或禁止地址/数据总线的复用功能。

选择所用的存储器类型:NOR闪存、SRAM或PSRAM。

定义外部存储器的数据总线宽度:8或16位。

使用或关闭同步NOR闪存存储器的突发访问模式。

配置等待信号的使用:开启或关闭,极性设置,时序配置。

使用或关闭扩展模式:扩展模式用于访问那些具有不同读写操作时序的存储器。

因为NOR闪存/SRAM控制器可以支持异步和同步存储器,用户只须根据存储器的参数配置使用到的参数。

FSMC提供了一些可编程的参数,可以正确地与外部存储器接口。依存储器类型的不同,有些参数是不需要的。

当使用一个外部异步存储器时,用户必须按照存储器的数据手册给出的时序数据,计算和设置下列参数:

ADDSET:地址建立时间

ADDHOLD:地址保持时间

DATAST:数据建立时间

ACCMOD:访问模式 这个参数允许 FSMC可以灵活地访问多种异步的静态存储器。共有4种扩展模式允许以不同的时序分别读写存储器。 在扩展模式下,FSMC_BTR用于配置读操作,FSMC_BWR用于配置写操作。(译注:如果读时序与写时序相同,只须使用FSMC_BTR即可。)

如果使用了同步的存储器,用户必须计算和设置下述参数:

CLKDIV:时钟分频系数

DATLAT:数据延时

如果存储器支持的话,NOR闪存的读操作可以是同步的,而写操作仍然是异步的。

当对一个同步的NOR闪存编程时,存储器会自动地在同步与异步之间切换;因此,必须正确地设置所有的参数

 

 

 

程序分析

  1.  /*-- FSMC Configuration ----------------------------------------------------*/  
  2.   p.FSMC_AddressSetupTime = 0x05;     /*ADDSET  地址建立时间*/  
  3.   p.FSMC_AddressHoldTime = 0x00;    /*ADDHOLD 地址保持时间*/  
  4.   p.FSMC_DataSetupTime = 0x07;     /*DATAST 数据建立时间*/  
  5.   p.FSMC_BusTurnAroundDuration = 0x00;   /*BUSTURN 总线返转时间*/  
  6.   p.FSMC_CLKDivision = 0x00;      /*CLKDIV 时钟分频*/  
  7.   p.FSMC_DataLatency = 0x00;     /*DATLAT 数据保持时间*/  
  8.   p.FSMC_AccessMode = FSMC_AccessMode_B;   /*访问模式*/  
  9. /*NOR/SRAM的存储块,共4个选项*/  
  10.   FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;      
  11. /*是否选择地址和数据复用数据线*/  
  12.   FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;    
  13. /*连接到相应存储块的外部存储器类型*/  
  14.   FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;     
  15. /*存储器数据总线宽度*/  
  16.   FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;    
  17. /*使能或关闭同步NOR闪存存储器的突发访问模式设置是否使用迸发访问模式(应该就是连续读写模式吧)*/  
  18.   FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;     
  19. /*设置WAIT信号的有效电平*/  
  20.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;     
  21.  /*设置是否使用环回模式*/  
  22.   FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;      
  23. /*设置WAIT信号有效时机*/  
  24.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;   
  25. /*设定是否使能写操作*/  
  26.   FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;    
  27. /*设定是否使用WAIT信号*/  
  28.   FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;     
  29. /*使能或关闭扩展模式,扩展模式用于访问具有不同读写操作时序的存储器,设定是否使用单独的写时序*/       
  30.   FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;    
  31. /*设定是否使用异步等待信号*/  
  32.   FSMC_NORSRAMInitStructure.FSMC_AsyncWait = FSMC_AsyncWait_Disable;    
  33. /*设定是否使用迸发写模式*/    
  34.   FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;    
  35.  /*设定读写时序*/  
  36.   FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;    //       
  37.   FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;    //  
  38.                    
  39.   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);        //  
  40.   /* Enable FSMC Bank1_NOR Bank */  
  41.   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);        //  
  42. }  
 

实际例程

以下例程来自  stm3210e_eval_fsmc_nor.c具体信息参加固件库中源文件。

  1. /** 
  2.   ****************************************************************************** 
  3.   * @file    stm3210e_eval_fsmc_nor.c 
  4.   * @author  MCD Application Team 
  5.   * @version V4.3.0 
  6.   * @date    10/15/2010 
  7.   * @brief   This file provides a set of functions needed to drive the M29W128FL,  
  8.   *          M29W128GL and S29GL128P NOR memories mounted on STM3210E-EVAL board. 
  9.   ****************************************************************************** 
  10.   * @copy 
  11.   * 
  12.   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 
  13.   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 
  14.   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 
  15.   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 
  16.   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 
  17.   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 
  18.   * 
  19.   * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2> 
  20.   */   
  21. /* Includes ------------------------------------------------------------------*/  
  22. #include "stm3210e_eval_fsmc_nor.h"  
  23. /** @addtogroup Utilities 
  24.   * @{ 
  25.   */  
  26.     
  27. /** @addtogroup STM32_EVAL 
  28.   * @{ 
  29.   */   
  30. /** @addtogroup STM3210E_EVAL 
  31.   * @{ 
  32.   */  
  33.     
  34. /** @addtogroup STM3210E_EVAL_FSMC_NOR 
  35.   * @brief      This file provides a set of functions needed to drive the M29W128FL,  
  36.   *             M29W128GL and S29GL128P NOR memories mounted on STM3210E-EVAL board. 
  37.   * @{ 
  38.   */   
  39. /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Types 
  40.   * @{ 
  41.   */   
  42. /** 
  43.   * @} 
  44.   */   
  45. /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Defines 
  46.   * @{ 
  47.   */   
  48. /**  
  49.   * @brief  FSMC Bank 1 NOR/SRAM2   
  50.   */  
  51. #define Bank1_NOR2_ADDR       ((uint32_t)0x64000000)  
  52. /* Delay definition */     
  53. #define BlockErase_Timeout    ((uint32_t)0x00A00000)  
  54. #define ChipErase_Timeout     ((uint32_t)0x30000000)   
  55. #define Program_Timeout       ((uint32_t)0x00001400)       
  56. /** 
  57.   * @} 
  58.   */   
  59.   
  60. /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Macros 
  61.   * @{ 
  62.   */  
  63. #define ADDR_SHIFT(A) (Bank1_NOR2_ADDR + (2 * (A)))  
  64. #define NOR_WRITE(Address, Data)  (*(__IO uint16_t *)(Address) = (Data))    
  65. /** 
  66.   * @} 
  67.   */   
  68.     
  69. /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Variables 
  70.   * @{ 
  71.   */   
  72. /** 
  73.   * @} 
  74.   */   
  75.   
  76. /** @defgroupSTM3210E_EVAL_FSMC_NOR_Private_Function_Prototypes 
  77.   * @{ 
  78.   */   
  79. /** 
  80.   * @} 
  81.   */   
  82.   
  83. /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Functions 
  84.   * @{ 
  85.   */  
  86. /** 
  87.   * @brief  Configures the FSMC and GPIOs to interface with the NOR memory. 
  88.   *         This function must be called before any write/read operation 
  89.   *         on the NOR. 
  90.   * @param  None 
  91.   * @retval None 
  92.   */  
  93. void NOR_Init(void)  
  94. {  
  95.   FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;  
  96.   FSMC_NORSRAMTimingInitTypeDef  p;  
  97.   GPIO_InitTypeDef GPIO_InitStructure;  
  98.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |   
  99.                          RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);  
  100.   /*-- GPIO Configuration ------------------------------------------------------*/  
  101.   /*!< NOR Data lines configuration */  
  102.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |  
  103.                                 GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;  
  104.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  105.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  106.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  107.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |  
  108.                                 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |  
  109.                                 GPIO_Pin_14 | GPIO_Pin_15;  
  110.   GPIO_Init(GPIOE, &GPIO_InitStructure);  
  111.   /*!< NOR Address lines configuration */  
  112.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |  
  113.                                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |  
  114.                                 GPIO_Pin_14 | GPIO_Pin_15;  
  115.   GPIO_Init(GPIOF, &GPIO_InitStructure);  
  116.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |  
  117.                                 GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;  
  118.   GPIO_Init(GPIOG, &GPIO_InitStructure);  
  119.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;  
  120.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  121.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;  
  122.   GPIO_Init(GPIOE, &GPIO_InitStructure);  
  123.   /*!< NOE and NWE configuration */  
  124.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;  
  125.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  126.   /*!< NE2 configuration */  
  127.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  128.   GPIO_Init(GPIOG, &GPIO_InitStructure);  
  129.   /*!< Configure PD6 for NOR memory Ready/Busy signal */  
  130.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
  131.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  132.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  133.     
  134.   /*-- FSMC Configuration ----------------------------------------------------*/  
  135.   p.FSMC_AddressSetupTime = 0x02;  
  136.   p.FSMC_AddressHoldTime = 0x00;  
  137.   p.FSMC_DataSetupTime = 0x05;  
  138.   p.FSMC_BusTurnAroundDuration = 0x00;  
  139.   p.FSMC_CLKDivision = 0x00;  
  140.   p.FSMC_DataLatency = 0x00;  
  141.   p.FSMC_AccessMode = FSMC_AccessMode_B;  
  142.   FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;  
  143.   FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;  
  144.   FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;  
  145.   FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;  
  146.   FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;  
  147.   FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;    
  148.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;  
  149.   FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;  
  150.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  
  151.   FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;  
  152.   FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;  
  153.   FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;  
  154.   FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;  
  155.   FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;  
  156.   FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;  
  157.   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  
  158.   /*!< Enable FSMC Bank1_NOR Bank */  
  159.   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);  
  160. }  
  161. /** 
  162.   * @brief  Reads NOR memory's Manufacturer and Device Code. 
  163.   * @param  NOR_ID: pointer to a NOR_IDTypeDef structure which will hold the  
  164.   *         Manufacturer and Device Code.   
  165.   * @retval None 
  166.   */  
  167. void NOR_ReadID(NOR_IDTypeDef* NOR_ID)  
  168. {  
  169.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  170.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  171.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0090);  
  172.   NOR_ID->Manufacturer_Code = *(__IO uint16_t *) ADDR_SHIFT(0x0000);  
  173.   NOR_ID->Device_Code1 = *(__IO uint16_t *) ADDR_SHIFT(0x0001);  
  174.   NOR_ID->Device_Code2 = *(__IO uint16_t *) ADDR_SHIFT(0x000E);  
  175.   NOR_ID->Device_Code3 = *(__IO uint16_t *) ADDR_SHIFT(0x000F);  
  176. }  
  177. /** 
  178.   * @brief  Erases the specified Nor memory block. 
  179.   * @param  BlockAddr: address of the block to erase. 
  180.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  181.   *         or NOR_TIMEOUT 
  182.   */  
  183. NOR_Status NOR_EraseBlock(uint32_t BlockAddr)  
  184. {  
  185.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  186.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  187.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);  
  188.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  189.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  190.   NOR_WRITE((Bank1_NOR2_ADDR + BlockAddr), 0x30);  
  191.   return (NOR_GetStatus(BlockErase_Timeout));  
  192. }  
  193. /** 
  194.   * @brief  Erases the entire chip. 
  195.   * @param  None                       
  196.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  197.   *         or NOR_TIMEOUT 
  198.   */  
  199. NOR_Status NOR_EraseChip(void)  
  200. {  
  201.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  202.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  203.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);  
  204.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  205.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  206.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0010);  
  207.   return (NOR_GetStatus(ChipErase_Timeout));  
  208. }  
  209. /** 
  210.   * @brief  Writes a half-word to the NOR memory. 
  211.   * @param  WriteAddr: NOR memory internal address to write to. 
  212.   * @param  Data: Data to write.  
  213.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  214.   *         or NOR_TIMEOUT 
  215.   */  
  216. NOR_Status NOR_WriteHalfWord(uint32_t WriteAddr, uint16_t Data)  
  217. {  
  218.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  219.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  220.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);  
  221.   NOR_WRITE((Bank1_NOR2_ADDR + WriteAddr), Data);  
  222.   return (NOR_GetStatus(Program_Timeout));  
  223. }  
  224. /** 
  225.   * @brief  Writes a half-word buffer to the FSMC NOR memory.  
  226.   * @param  pBuffer: pointer to buffer.  
  227.   * @param  WriteAddr: NOR memory internal address from which the data will be  
  228.   *         written. 
  229.   * @param  NumHalfwordToWrite: number of Half words to write.  
  230.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  231.   *         or NOR_TIMEOUT 
  232.   */  
  233. NOR_Status NOR_WriteBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)  
  234. {  
  235.   NOR_Status status = NOR_ONGOING;   
  236.   do  
  237.   {  
  238.     /*!< Transfer data to the memory */  
  239.     status = NOR_WriteHalfWord(WriteAddr, *pBuffer++);  
  240.     WriteAddr = WriteAddr + 2;  
  241.     NumHalfwordToWrite--;  
  242.   }  
  243.   while((status == NOR_SUCCESS) && (NumHalfwordToWrite != 0));  
  244.     
  245.   return (status);   
  246. }  
  247. /** 
  248.   * @brief  Writes a half-word buffer to the FSMC NOR memory. This function  
  249.   *         must be used only with S29GL128P NOR memory. 
  250.   * @param  pBuffer: pointer to buffer.  
  251.   * @param  WriteAddr: NOR memory internal address from which the data will be  
  252.   *         written. 
  253.   * @param  NumHalfwordToWrite: number of Half words to write. 
  254.   *         The maximum allowed value is 32 Half words (64 bytes). 
  255.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  256.   *         or NOR_TIMEOUT 
  257.   */  
  258. NOR_Status NOR_ProgramBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)  
  259. {  
  260.   uint32_t lastloadedaddress = 0x00;  
  261.   uint32_t currentaddress = 0x00;  
  262.   uint32_t endaddress = 0x00;  
  263.   /*!< Initialize variables */  
  264.   currentaddress = WriteAddr;  
  265.   endaddress = WriteAddr + NumHalfwordToWrite - 1;  
  266.   lastloadedaddress = WriteAddr;  
  267.   /*!< Issue unlock command sequence */  
  268.   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);  
  269.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);    
  270.   /*!< Write Write Buffer Load Command */  
  271.   NOR_WRITE(ADDR_SHIFT(WriteAddr), 0x0025);  
  272.   NOR_WRITE(ADDR_SHIFT(WriteAddr), (NumHalfwordToWrite - 1));  
  273.   /*!< Load Data into NOR Buffer */  
  274.   while(currentaddress <= endaddress)  
  275.   {  
  276.     /*!< Store last loaded address & data value (for polling) */  
  277.     lastloadedaddress = currentaddress;  
  278.    
  279.     NOR_WRITE(ADDR_SHIFT(currentaddress), *pBuffer++);  
  280.     currentaddress += 1;   
  281.   }  
  282.   NOR_WRITE(ADDR_SHIFT(lastloadedaddress), 0x29);  
  283.     
  284.   return(NOR_GetStatus(Program_Timeout));  
  285. }  
  286. /** 
  287.   * @brief  Reads a half-word from the NOR memory.  
  288.   * @param  ReadAddr: NOR memory internal address to read from. 
  289.   * @retval Half-word read from the NOR memory 
  290.   */  
  291. uint16_t NOR_ReadHalfWord(uint32_t ReadAddr)  
  292. {  
  293.   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);   
  294.   NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);    
  295.   NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0 );  
  296.   return (*(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr)));  
  297. }  
  298. /** 
  299.   * @brief  Reads a block of data from the FSMC NOR memory. 
  300.   * @param  pBuffer: pointer to the buffer that receives the data read from the  
  301.   *         NOR memory. 
  302.   * @param  ReadAddr: NOR memory internal address to read from. 
  303.   * @param  NumHalfwordToRead : number of Half word to read. 
  304.   * @retval None 
  305.   */  
  306. void NOR_ReadBuffer(uint16_t* pBuffer, uint32_t ReadAddr, uint32_t NumHalfwordToRead)  
  307. {  
  308.   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);  
  309.   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
  310.   NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0);  
  311.   for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) /*!< while there is data to read */  
  312.   {  
  313.     /*!< Read a Halfword from the NOR */  
  314.     *pBuffer++ = *(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr));  
  315.     ReadAddr = ReadAddr + 2;   
  316.   }    
  317. }  
  318. /** 
  319.   * @brief  Returns the NOR memory to Read mode. 
  320.   * @param  None 
  321.   * @retval NOR_SUCCESS 
  322.   */  
  323. NOR_Status NOR_ReturnToReadMode(void)  
  324. {  
  325.   NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0);  
  326.   return (NOR_SUCCESS);  
  327. }  
  328. /** 
  329.   * @brief  Returns the NOR memory to Read mode and resets the errors in the NOR  
  330.   *         memory Status Register.   
  331.   * @param  None 
  332.   * @retval NOR_SUCCESS 
  333.   */  
  334. NOR_Status NOR_Reset(void)  
  335. {  
  336.   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);   
  337.   NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);   
  338.   NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0);   
  339.   return (NOR_SUCCESS);  
  340. }  
  341. /** 
  342.   * @brief  Returns the NOR operation status. 
  343.   * @param  Timeout: NOR progamming Timeout 
  344.   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR 
  345.   *         or NOR_TIMEOUT 
  346.   */  
  347. NOR_Status NOR_GetStatus(uint32_t Timeout)  
  348. {   
  349.   uint16_t val1 = 0x00, val2 = 0x00;  
  350.   NOR_Status status = NOR_ONGOING;   
  351.   uint32_t timeout = Timeout;  
  352.   /*!< Poll on NOR memory Ready/Busy signal ----------------------------------*/  
  353.   while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) != RESET) && (timeout > 0))   
  354.   {  
  355.     timeout--;  
  356.   }  
  357.   timeout = Timeout;  
  358.     
  359.   while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == RESET) && (timeout > 0))     
  360.   {  
  361.     timeout--;  
  362.   }  
  363.     
  364.   /*!< Get the NOR memory operation status -----------------------------------*/  
  365.   while((Timeout != 0x00) && (status != NOR_SUCCESS))  
  366.   {  
  367.     Timeout--;  
  368.     /*!< Read DQ6 and DQ5 */  
  369.     val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);  
  370.     val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);  
  371.     /*!< If DQ6 did not toggle between the two reads then return NOR_Success */  
  372.     if((val1 & 0x0040) == (val2 & 0x0040))   
  373.     {  
  374.       return NOR_SUCCESS;  
  375.     }  
  376.     if((val1 & 0x0020) != 0x0020)  
  377.     {  
  378.       status = NOR_ONGOING;  
  379.     }  
  380.     val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);  
  381.     val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);  
  382.       
  383.     if((val1 & 0x0040) == (val2 & 0x0040))   
  384.     {  
  385.       return NOR_SUCCESS;  
  386.     }  
  387.     else if((val1 & 0x0020) == 0x0020)  
  388.     {  
  389.       return NOR_ERROR;  
  390.     }  
  391.   }  
  392.   if(Timeout == 0x00)  
  393.   {  
  394.     status = NOR_TIMEOUT;  
  395.   }   
  396.   /*!< Return the operation status */  
  397.   return (status);  
  398. }  
  399. /** 
  400.   * @} 
  401.   */  
  402. /** 
  403.   * @} 
  404.   */  
  405. /** 
  406.   * @} 
  407.   */  
  408. /** 
  409.   * @} 
  410.   */  
  411. /** 
  412.   * @} 
  413.   */    
  414. /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/  
  本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2011/01/05/2198192.html,如需转载请自行联系原作者

相关文章
|
存储 内存技术
STM32:DMA直接存储器存储(内含:1.DMA简介+2.存储器映像+3.DMA框图+4.DMA基本结构图+5.数据宽度对齐+6.两种经典转运情景)
STM32:DMA直接存储器存储(内含:1.DMA简介+2.存储器映像+3.DMA框图+4.DMA基本结构图+5.数据宽度对齐+6.两种经典转运情景)
312 0
STM32:DMA直接存储器存储(内含:1.DMA简介+2.存储器映像+3.DMA框图+4.DMA基本结构图+5.数据宽度对齐+6.两种经典转运情景)
|
6月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
460 2
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
743 0
|
7月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
6月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
519 4
|
6月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
740 2
|
6月前
|
存储 数据采集 数据安全/隐私保护
使用STM32F103读取TF卡并模拟U盘:使用标准库实现
通过以上步骤,你可以实现用STM32F103将TF卡内容变成U盘进行读取。这种功能在数据采集、便携式存储设备等应用中非常有用。如果你有更多的需求,可以进一步扩展此项目,例如添加文件管理功能、加密存储等。希望这篇博客能帮到你,如果有任何问题,欢迎在评论区留言讨论!
245 1
|
6月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
603 1
|
5月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
178 0