你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

陈酿!四年陈的STM32F103外设测试代码!希望对你有帮助~~~ 精华  

[复制链接]
Dylan疾风闪电 发布时间:2016-1-7 14:26
阅读主题, 点击返回1楼
收藏 22 评论60 发布时间:2016-1-7 14:26
60个回答
Dylan疾风闪电 回答时间:2016-1-7 15:13:12
  1. /**
  2.   ******************************************************************************
  3.   * @file /FLASH_Program.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-17
  7.   * @brief    FLASH:擦写数据到FLASH地址
  8.   ******************************************************************************
  9.   *用途:将某些掉电保持的数据存入FLASH,供下次上电检测
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //2.Watch中观察
  15.   FLASH地址0x08008000~0x0800C000中的数据:
  16.     从0xFFFFFFFF修改为Data = 0x15041979;
  17.   */

  18. #ifndef __FLASH_PROGRAM_H
  19. #define __FLASH_PROGRAM_H
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "std32periph.h"

  22. /* Private typedef -----------------------------------------------------------*/
  23. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  24. /* Private define ------------------------------------------------------------*/
  25. #define FLASH_PAGE_SIZE     ((u16)0x800)
  26. #define StartAddr           ((u32)0x08008000)
  27. #define EndAddr             ((u32)0x0800C000)
  28. /* Private macro -------------------------------------------------------------*/
  29. /* Private variables ---------------------------------------------------------*/
  30. /* Private functions ---------------------------------------------------------*/

  31. void fmain(void)
  32. {
  33.   u32 EraseCounter = 0x00, Address = 0x00;
  34.   vu32 NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE;
  35.   u32 Data = 0x15041979;
  36.   /*  typedef enum{FLASH_BUSY = 1,  FLASH_ERROR_PG,  FLASH_ERROR_WRP,  FLASH_COMPLETE,  FLASH_TIMEOUT}FLASH_Status;  */
  37.   volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
  38.   volatile TestStatus MemoryProgramStatus = PASSED;
  39.   
  40.   
  41.   RCC_HSEConf(9);//72M

  42.   
  43.   FLASH_Unlock();
  44.   /* Clear All pending flags */
  45.   FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);       

  46.   /* Erase the FLASH pages */
  47.   for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  48.   {
  49.     FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));
  50.   }
  51.   
  52.   /*  FLASH Word program of data 0x15041979 at addresses defined by StartAddr and EndAddr*/
  53.   Address = StartAddr;
  54.   while((Address < EndAddr) && (FLASHStatus == FLASH_COMPLETE))
  55.   {
  56.     FLASHStatus = FLASH_ProgramWord(Address, Data);
  57.     Address = Address + 4;
  58.   }
  59.   
  60.   /* Check the corectness of written data */
  61.   Address = StartAddr;
  62.   while((Address < EndAddr) && (MemoryProgramStatus != FAILED))
  63.   {
  64.     if((*(vu32*) Address) != Data)
  65.     {
  66.       MemoryProgramStatus = FAILED;
  67.     }
  68.     Address += 4;
  69.   }
  70. }

  71. #endif
  72. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:13:27
  1. /**
  2.   ******************************************************************************
  3.   * @file /FLASH_WriteProtection.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-17
  7.   * @brief    FLASH:写保护(写保护部分存在问题,无法设置保护)
  8.   ******************************************************************************
  9.   *用途:将某些掉电保持的数据存入FLASH,供下次上电检测
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //2.Watch中观察
  15.   FLASH地址0x08006000~0x08008000中的数据:
  16.     从0xFFFFFFFF修改为 0x17531753;
  17.   */

  18. #ifndef __FLASH_WRITEPROTECTION_H
  19. #define __FLASH_WRITEPROTECTION_H
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "std32periph.h"

  22. /* Private typedef -----------------------------------------------------------*/
  23. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  24. /* Private define ------------------------------------------------------------*/
  25. #define FLASH_PAGE_SIZE     ((u16)0x800)
  26. #define StartAddr           ((u32)0x08006000)
  27. #define EndAddr             ((u32)0x08008000)
  28. /* Uncomment this line to Enable Write Protection */
  29. //#define WriteProtection_Enable
  30. /* Uncomment this line to Disable Write Protection */
  31. #define WriteProtection_Disable
  32. /* Private macro -------------------------------------------------------------*/
  33. /* Private variables ---------------------------------------------------------*/
  34. /* Private functions ---------------------------------------------------------*/

  35. void fmain(void)
  36. {
  37.   u32 EraseCounter = 0, Address;
  38.   u16 Data = 0x1753;
  39.   vu32 WRPR_Value = 0xFFFFFFFF, ProtectedPages = 0x0;
  40.   vu8 NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE;
  41.   /*  typedef enum{FLASH_BUSY = 1,  FLASH_ERROR_PG,  FLASH_ERROR_WRP,  FLASH_COMPLETE,  FLASH_TIMEOUT}FLASH_Status;  */
  42.   volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;
  43.   volatile TestStatus MemoryProgramStatus = PASSED;  
  44.   
  45.   
  46.   RCC_HSEConf(9);//72M

  47.   
  48.   //CR_LOCK位=1执行解锁序列
  49.   FLASH->KEYR = 0x45670123;
  50.   FLASH->KEYR = 0xCDEF89AB;
  51.   
  52.   FLASH->SR = 0x35;//写1清除SR寄存器所有状态

  53.   //获取信息最后8页的写保护状态,判断是否写保护
  54.   ProtectedPages = (FLASH->WRPR) & 0x000000C0;

  55. #ifdef WriteProtection_Disable
  56.   if (ProtectedPages == 0x00)
  57.   {/* Pages are write protected */
  58.     FLASHStatus = FLASH_EraseOptionBytes();//Erases the FLASH option bytes.
  59.     /* ---------------------------------------------------------------------------------------
  60.     要将访问钥匙 0x05FA0000 与我们的操作 SYSRESETREQ[2]=1 相或,一起写入 SCB->AIRCR,才被CM3接受
  61.     //NVIC_GenerateSystemReset();
  62.     --------------------------------------------------------------------------------------- */
  63.     SCB->AIRCR = (u32)0x05FA0000 | (u32)0x04;//先键入钥匙(u32)0x05FA0000,然后产生一个系统复位
  64.   }
  65. #elif defined WriteProtection_Enable
  66.   if (ProtectedPages != 0x00)
  67.   {/* Pages not write protected */
  68.     /* Enable the pages write protection */
  69.     FLASHStatus = FLASH_EnableWriteProtection(0x000000C0);
  70.    
  71.     /* ---------------------------------------------------------------------------------------
  72.     要将访问钥匙 0x05FA0000 与我们的操作 SYSRESETREQ[2]=1 相或,一起写入 SCB->AIRCR,才被CM3接受
  73.     //NVIC_GenerateSystemReset();
  74.     --------------------------------------------------------------------------------------- */
  75.     SCB->AIRCR = (u32)0x05FA0000 | (u32)0x04;//先键入钥匙(u32)0x05FA0000,然后产生一个系统复位
  76.   }
  77. #endif
  78.   
  79.   /* If Pages are not write protected, perform erase and program operations
  80.      Else nothing */
  81.   if (ProtectedPages != 0x00)
  82.   {
  83.     FLASH->SR = 0x35;//写1清除SR寄存器所有状态

  84.     //擦除指定FLASH页
  85.     for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  86.     {
  87.       FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));
  88.     }
  89.   
  90.     //将数据0x1753 写入指定FLASH地址
  91.     Address = StartAddr;
  92.     while((Address < EndAddr) && (FLASHStatus == FLASH_COMPLETE))
  93.     {
  94.       FLASHStatus = FLASH_ProgramHalfWord(Address, Data);
  95.       Address = Address + 2;
  96.     }

  97.     //检测写入的数据
  98.     Address = StartAddr;
  99.     while((Address < EndAddr) && (MemoryProgramStatus != FAILED))
  100.     {
  101.       if((*(vu16*) Address) != Data)
  102.       {
  103.         MemoryProgramStatus = FAILED;
  104.       }
  105.       Address += 2;
  106.     }
  107.   }
  108. }



  109. #endif
  110. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:13:42
  1. /**
  2.   ******************************************************************************
  3.   * @file /FSMC_NAND.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-17
  7.   * @brief    FSMC:(未研究)
  8.   use the FSMC firmware library and an associate driver to perform erase/read/write operations
  9.   on the NAND512W3A2CN6E memory mounted on STM3210E-LK board.
  10.   ******************************************************************************
  11.   *用途:将某些掉电保持的数据存入FLASH,供下次上电检测
  12.   */
  13.   /*实例应用步骤:
  14.   //1."main.cpp"调用fmain()
  15.   
  16.   //2.Watch中观察
  17.   LED
  18.   TxBuffer,RxBuffer
  19.   */

  20. #ifndef __FSMC_NAND_H
  21. #define __FSMC_NAND_H
  22. /* Includes ------------------------------------------------------------------*/
  23. #include "std32periph.h"

  24. /* Private typedef -----------------------------------------------------------*/
  25. typedef struct
  26. {
  27.   u8 Maker_ID;
  28.   u8 Device_ID;
  29.   u8 Third_ID;
  30.   u8 Fourth_ID;
  31. }NAND_IDTypeDef;

  32. typedef struct
  33. {
  34.   u16 Block;
  35.   u16 Page;
  36. } NAND_ADDRESS;
  37. /* Private define ------------------------------------------------------------*/
  38. #define BUFFER_SIZE         0x80//0x1000
  39. #define NAND_HY_ManufactureCode 0xAD
  40. #define NAND_HY_DeviceCode      0xF1
  41. #define NAND_HY_3rdCode         0x80
  42. #define NAND_HY_4thCode         0x1D

  43. #define FSMC_Bank_NAND     FSMC_Bank2_NAND
  44. #define Bank_NAND_ADDR     Bank2_NAND_ADDR
  45. #define Bank2_NAND_ADDR    ((u32)0x70000000)

  46. /* Private macro -------------------------------------------------------------*/
  47. /*row address is in the unit of page
  48. for HY nand data sheet --> address sequence --> A0~A11 as tail --> discard 1st & 2nd address cycle*/
  49. #define ROW_ADDRESS (Address.Page + Address.Block * NAND_BLOCK_SIZE)

  50. /* NAND Area definition  for STM3210E-LK Board  */
  51. #define CMD_AREA                   (u32)(1<<16)  /* A16 = CLE  high */
  52. #define ADDR_AREA                  (u32)(1<<17)  /* A17 = ALE high */

  53. #define DATA_AREA                  ((u32)0x00000000)

  54. /* FSMC NAND memory command */
  55. #define        NAND_CMD_AREA_A            ((u8)0x00)
  56. //#define        NAND_CMD_AREA_B            ((u8)0x01)
  57. //#define NAND_CMD_AREA_C            ((u8)0x50)
  58. #define NAND_CMD_AREA_TRUE1        ((u8)0x30)

  59. #define NAND_CMD_WRITE0            ((u8)0x80)
  60. #define NAND_CMD_WRITE_TRUE1       ((u8)0x10)
  61.        
  62. #define NAND_CMD_ERASE0            ((u8)0x60)
  63. #define NAND_CMD_ERASE1            ((u8)0xD0)  

  64. #define NAND_CMD_READID            ((u8)0x90)       
  65. #define NAND_CMD_STATUS            ((u8)0x70)
  66. #define NAND_CMD_LOCK_STATUS       ((u8)0x7A)
  67. #define NAND_CMD_RESET             ((u8)0xFF)

  68. /* NAND memory status */
  69. #define NAND_VALID_ADDRESS         ((u32)0x00000100)
  70. #define NAND_INVALID_ADDRESS       ((u32)0x00000200)
  71. #define NAND_TIMEOUT_ERROR         ((u32)0x00000400)
  72. #define NAND_BUSY                  ((u32)0x00000000)
  73. #define NAND_ERROR                 ((u32)0x00000001) // bit0
  74. #define NAND_READY                 ((u32)0x00000040) // bit6

  75. /* FSMC NAND memory parameters */
  76. #define NAND_PAGE_SIZE             ((u16)0x0800) /* 2k bytes per page without Spare Area */
  77. #define NAND_BLOCK_SIZE            ((u16)0x0040) /* 64 pages per block */
  78. #define NAND_SPARE_AREA_SIZE       ((u16)0x0040) /* last 64 bytes as spare area */
  79. #define NAND_MAX_BLOCK             ((u16)0x0400) /* max 1024 block */

  80. /* FSMC NAND memory address computation */
  81. #define ADDR_1st_CYCLE(ADDR)       (u8)((ADDR)& 0xFF)               /* 1st addressing cycle */
  82. #define ADDR_2nd_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF00) >> 8)      /* 2nd addressing cycle */
  83. #define ADDR_3rd_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF0000) >> 16)   /* 3rd addressing cycle */
  84. #define ADDR_4th_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF000000) >> 24) /* 4th addressing cycle */
  85. /* Private macro -------------------------------------------------------------*/
  86. /* Private variables ---------------------------------------------------------*/
  87. u8 page_data[NAND_PAGE_SIZE]; /*for temparoily hold the page data*/
  88. u8 page_data_tmp; /* store 1st 2k main array data(flush) */

  89. NAND_IDTypeDef NAND_ID;
  90. NAND_ADDRESS WriteReadAddr;
  91. u8 TxBuffer[BUFFER_SIZE], RxBuffer[BUFFER_SIZE];
  92. vu32 PageNumber = 2, WriteReadStatus = 0, status= 0;
  93. u32 j = 0;
  94. /* Private functions ---------------------------------------------------------*/
  95. void FSMC_NAND_Init(void);
  96. void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);
  97. u32 FSMC_NAND_ProgramPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite);
  98. u32 FSMC_NAND_ReadPage (u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead);
  99. u32 FSMC_NAND_WriteSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaTowrite);
  100. u32 FSMC_NAND_ReadSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaToRead);
  101. u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address);
  102. u32 FSMC_NAND_Reset(void);
  103. u32 FSMC_NAND_GetStatus(void);
  104. u32 FSMC_NAND_ReadStatus(void);
  105. u32 FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);

  106. void FSMC_NAND_Init(void)
  107. {
  108.   GPIO_InitTypeDef GPIO_InitStructure;
  109.   FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
  110.   FSMC_NAND_PCCARDTimingInitTypeDef  p;
  111.   
  112.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
  113.                          RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
  114.   
  115. /*-- GPIO Configuration ------------------------------------------------------*/
  116. /* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */
  117.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |  
  118.                                  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
  119.                                  GPIO_Pin_7;                                 
  120.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  121.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  122.   GPIO_Init(GPIOD, &GPIO_InitStructure);

  123. /* D4->D7 NAND pin configuration  */  
  124.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;

  125.   GPIO_Init(GPIOE, &GPIO_InitStructure);


  126. /* NWAIT NAND pin configuration */
  127.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                                            
  128.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  129.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  130.   GPIO_Init(GPIOD, &GPIO_InitStructure);

  131. /* INT2 NAND pin configuration */  
  132.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                                            
  133.   GPIO_Init(GPIOG, &GPIO_InitStructure);

  134.   /*-- FSMC Configuration ------------------------------------------------------*/
  135.   p.FSMC_SetupTime = 0x1;
  136.   p.FSMC_WaitSetupTime = 0x3;
  137.   p.FSMC_HoldSetupTime = 0x2;
  138.   p.FSMC_HiZSetupTime = 0x1;

  139.   FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
  140.   FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
  141.   FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
  142.   FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
  143.   FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
  144.   //FSMC_NANDInitStructure.FSMC_AddressLowMapping = FSMC_AddressLowMapping_Direct;
  145.   FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
  146.   FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
  147.   FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
  148.   FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
  149.   FSMC_NANDInit(&FSMC_NANDInitStructure);

  150.   /* FSMC NAND Bank Cmd Test */
  151.   FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
  152. }

  153. void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
  154. {
  155.   u32 data = 0;

  156.   /* writing 90h to the command register, followed by an address input of 00h*/        
  157.   *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;
  158.   *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;

  159.    /* Four read cycles sequentially output the 1st cycle (ADh), and 2nd cycle (the device code) and
  160.       3rd cycle ID, 4th cycle ID */       
  161.    data = *(vu32 *)(Bank_NAND_ADDR | DATA_AREA);

  162.    NAND_ID->Maker_ID   = ADDR_1st_CYCLE (data);
  163.    NAND_ID->Device_ID  = ADDR_2nd_CYCLE (data);
  164.    NAND_ID->Third_ID   = ADDR_3rd_CYCLE (data);
  165.    NAND_ID->Fourth_ID  = ADDR_4th_CYCLE (data);  
  166. }

  167. u32 FSMC_NAND_ProgramPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite)
  168. {
  169.   u32 index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  170.   u32 status = NAND_READY, size = 0x00;

  171.   while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  172.   {
  173.     /* begins by inputting the Serial Data Input command (80h)*/
  174.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
  175.     /* followed by the four cycle address inputs */
  176.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;  
  177.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;  
  178.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);  
  179.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);  

  180.     /* Calculate number of write operatin (the size of main array to be programed)*/
  181.     size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);

  182.     /* then serial data and tADL of min=100ns should be guaranteed */
  183.     /* tADL is the time from the WE rising edge of final address cycle
  184.     to the WE rising of first data cycle. */
  185.     for(; index < size; index++)
  186.     {
  187.       *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
  188.     }
  189.    
  190.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;

  191.     /* PG.6(FSMC_INT2) connect to R/!B of NAND flash */
  192.     while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
  193.    
  194.     /* Check status for successful operation */
  195.     status = FSMC_NAND_GetStatus();
  196.    
  197.     if(status == NAND_READY)
  198.     {
  199.       numpagewritten++;

  200.       NumPageToWrite--;

  201.       /* Calculate Next small page Address */
  202.       addressstatus = FSMC_NAND_AddressIncrement(&Address);   
  203.     }   
  204.   }
  205.   
  206.   return (status | addressstatus);
  207. }

  208. u32 FSMC_NAND_ReadPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead)
  209. {
  210.   u32 index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
  211.   u32 status = NAND_READY, size = 0x00;

  212.   while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  213.   {          
  214.     /* Page Read command and page address */
  215.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
  216.    
  217.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  218.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  219.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  220.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  221.    
  222.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;

  223.     /* PG.6(FSMC_INT2) connect to R/!B of NAND flash */
  224.     while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
  225.    
  226.     /* Calculate the size */
  227.     size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
  228.    
  229.     /* Get Data into Buffer */   
  230.     for(; index < size; index++)
  231.     {
  232.       pBuffer[index]= *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
  233.     }

  234.     numpageread++;
  235.    
  236.     NumPageToRead--;

  237.     /* Calculate page address */                                    
  238.     addressstatus = FSMC_NAND_AddressIncrement(&Address);
  239.   }

  240.   status = FSMC_NAND_GetStatus();
  241.   
  242.   return (status | addressstatus);
  243. }

  244. u32 FSMC_NAND_WriteSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaTowrite)
  245. {
  246.   u32 index = 0x00, numsparesreawritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  247.   u32 status = NAND_READY, size = 0x00;


  248.   while((NumSpareAreaTowrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  249.   {   
  250.     /* read out main array data into page_data[] firstly */
  251.     FSMC_NAND_ReadPage(page_data, Address, 1);
  252.    
  253.    
  254.     /* Page write Spare area command and address */
  255.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;

  256.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  257.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  258.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  259.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);

  260.     /* PG.6(FSMC_INT2) connect to R/!B of NAND flash */
  261.     while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );

  262.     /* total number of write operation */
  263.     size = (NAND_SPARE_AREA_SIZE+NAND_PAGE_SIZE) + ((NAND_SPARE_AREA_SIZE+NAND_PAGE_SIZE) * numsparesreawritten);

  264.     /* Write the data */
  265.     for(; index < size; index++)
  266.     {
  267.       if (index < size - NAND_SPARE_AREA_SIZE)
  268.         *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = page_data[index - (NAND_PAGE_SIZE + NAND_SPARE_AREA_SIZE)*numsparesreawritten];
  269.       else
  270.         *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index - NAND_PAGE_SIZE * (numsparesreawritten+1)];
  271.     }
  272.    
  273.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;

  274.     /* Check status for successful operation */
  275.     status = FSMC_NAND_GetStatus();

  276.     if(status == NAND_READY)
  277.     {
  278.       numsparesreawritten++;      

  279.       NumSpareAreaTowrite--;  
  280.    
  281.       /* Calculate Next page Address */
  282.       addressstatus = FSMC_NAND_AddressIncrement(&Address);
  283.     }      
  284.   }
  285.   
  286.   return (status | addressstatus);
  287. }

  288. u32 FSMC_NAND_ReadSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaToRead)
  289. {
  290.   u32 numsparearearead = 0x00, index = 0x00, addressstatus = NAND_VALID_ADDRESS;
  291.   u32 status = NAND_READY, size = 0x00;

  292.   while((NumSpareAreaToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  293.   {     
  294.     /* Page Read command and page address */     
  295.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A; // no area B/C for HY

  296.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  297.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;     
  298.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);     
  299.     *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);   

  300.     *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;

  301.     /* PG.6(FSMC_INT2) connect to R/!B of NAND flash */
  302.     while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
  303.    
  304.     /* total number of write operation */
  305.     size = (NAND_SPARE_AREA_SIZE+NAND_PAGE_SIZE) +  ((NAND_SPARE_AREA_SIZE+NAND_PAGE_SIZE) * numsparearearead);//
  306.        
  307.     /* Get page data into temp-space and get spare data into Buffer */
  308.     for ( ;index < size; index++)
  309.     {
  310.       if (index < size - NAND_SPARE_AREA_SIZE)
  311.         page_data_tmp = *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
  312.       else
  313.         pBuffer[index - NAND_PAGE_SIZE * (numsparearearead+1)] = *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
  314.     }
  315.    
  316.     numsparearearead++;
  317.    
  318.     NumSpareAreaToRead--;

  319.     /* Calculate page address */                                    
  320.     addressstatus = FSMC_NAND_AddressIncrement(&Address);
  321.   }

  322.   status = FSMC_NAND_GetStatus();

  323.   return (status | addressstatus);
  324. }

  325. u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address)
  326. {
  327.   *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;

  328.   *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  329.   *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  330.                
  331.   *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;

  332.   /* PG.6(FSMC_INT2) connect to R/!B of NAND flash */
  333.   while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
  334.    
  335.   return (FSMC_NAND_GetStatus());
  336. }

  337. u32 FSMC_NAND_Reset(void)
  338. {
  339.   *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;

  340.   return (NAND_READY);
  341. }

  342. u32 FSMC_NAND_GetStatus(void)
  343. {
  344.   u32 timeout = 0x1000000, status = NAND_READY;

  345.   status = FSMC_NAND_ReadStatus();

  346.   /* Wait for a NAND operation to complete or a TIMEOUT to occur */
  347.   while ((status != NAND_READY) &&( timeout != 0x00))
  348.   {
  349.      status = FSMC_NAND_ReadStatus();
  350.      timeout --;      
  351.   }

  352.   if(timeout == 0x00)
  353.   {         
  354.     status =  NAND_TIMEOUT_ERROR;      
  355.   }

  356.   /* Return the operation status */
  357.   return (status);      
  358. }

  359. u32 FSMC_NAND_ReadStatus(void)
  360. {
  361.   u32 data = 0x00, status = NAND_BUSY;

  362.   /* Read status operation ------------------------------------ */
  363.   *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
  364.   data = *(vu8 *)(Bank_NAND_ADDR);

  365.   if((data & NAND_ERROR) == NAND_ERROR)
  366.   {
  367.     status = NAND_ERROR;
  368.   }
  369.   else if((data & NAND_READY) == NAND_READY)
  370.   {
  371.     status = NAND_READY;
  372.   }
  373.   else
  374.   {
  375.     status = NAND_BUSY;
  376.   }
  377.   
  378.   return (status);
  379. }

  380. u32 FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address)
  381. {
  382.   u32 status = NAND_VALID_ADDRESS;

  383.   Address->Page++;

  384.   if(Address->Page == NAND_BLOCK_SIZE)
  385.   {
  386.     Address->Page = 0;
  387.     Address->Block++;
  388.    
  389.     if(Address->Block == NAND_MAX_BLOCK)
  390.     {
  391.       status = NAND_INVALID_ADDRESS;
  392.     }
  393.   }
  394.   
  395.   return (status);
  396. }


  397. void Fill_Buffer(u8 *pBuffer, u16 BufferLenght, u32 Offset)
  398. {
  399.   u16 IndexTmp = 0;

  400.   /* Put in global buffer same values */
  401.   for (IndexTmp = 0; IndexTmp < BufferLenght; IndexTmp++ )
  402.   {
  403.     pBuffer[IndexTmp] = IndexTmp + Offset;
  404.   }
  405. }

  406. void fmain(void)
  407. {
  408.   RCC_HSEConf(9);//72M

  409.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
  410.   
  411.   /* Configure PF.06, PF.07 and PF.08 as Output push-pull */
  412.   GPIO_InitTypeDef GPIO_InitStructure;
  413.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
  414.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  415.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  416.   GPIO_Init(GPIOF, &GPIO_InitStructure);

  417.   /* Enable the FSMC Clock */
  418.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
  419.   
  420.   /* FSMC Initialization */
  421.   FSMC_NAND_Init();

  422.   /* NAND read ID command */
  423.   FSMC_NAND_ReadID(&NAND_ID);

  424.   /* Verify the NAND ID */
  425.   if((NAND_ID.Maker_ID == NAND_HY_ManufactureCode) && (NAND_ID.Device_ID == NAND_HY_DeviceCode))
  426.   {

  427.     /* NAND memory address to write to */
  428.     WriteReadAddr.Block = 0x00;
  429.     WriteReadAddr.Page = 0x00;

  430.     /* Erase the NAND first Block */
  431.     status = FSMC_NAND_EraseBlock(WriteReadAddr);

  432.     /* Write data to FSMC NAND memory */
  433.     /* Fill the buffer to send */
  434.     Fill_Buffer(TxBuffer, BUFFER_SIZE , 0x66);

  435.     status = FSMC_NAND_WriteSpareArea(TxBuffer, WriteReadAddr, PageNumber);

  436.     /* Read back the written data */
  437.     status = FSMC_NAND_ReadSpareArea(RxBuffer, WriteReadAddr, PageNumber);
  438.    
  439.     /* Verify the written data */
  440.     for(j = 0; j < BUFFER_SIZE; j++)
  441.     {
  442.       if(TxBuffer[j] != RxBuffer[j])
  443.       {     
  444.         WriteReadStatus++;
  445.       }
  446.     }

  447.     if (WriteReadStatus == 0)
  448.     {
  449.       GPIO_SetBits(GPIOF, GPIO_Pin_6);//执行结果
  450.     }
  451.     else
  452.     {
  453.       GPIO_SetBits(GPIOF, GPIO_Pin_7);     
  454.     }
  455.   }
  456.   else
  457.   {
  458.     GPIO_SetBits(GPIOF, GPIO_Pin_8);  
  459.   }
  460. }

  461. #endif
  462. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:14:08
  1. /**
  2.   ******************************************************************************
  3.   * @file /I2C_M24C02EEPROM.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-17
  7.   * @brief    I2C:(ST的I2C问题很多,建议不用,选择IO口模拟)--测试不通过,待调整《申明:这里只是老的资料,描述也是以前的。故对存在问题的代码也不进行优化!》
  8.   ******************************************************************************
  9.   *用途:
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //2.Watch中观察
  15.   Tx1_Buffer == Rx1_Buffer
  16.   Tx2_Buffer == Rx2_Buffer
  17.   TransferStatus1,TransferStatus2
  18.   */

  19. #ifndef __I2C_M24C02EEPROM_H
  20. #define __I2C_M24C02EEPROM_H
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "std32periph.h"

  23. /* Private typedef -----------------------------------------------------------*/
  24. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  25. typedef struct
  26. {
  27.   u8  *Tx,*Rx;
  28.   u16 Address,count,Max;
  29. }I2CTYPE;
  30. /* Private define ------------------------------------------------------------*/
  31. #define EEPROM_WriteAddress1    0x05
  32. #define EEPROM_ReadAddress1     0x05
  33. #define BufferSize1             (countof(Tx1_Buffer)-1)
  34. #define BufferSize2             (countof(Tx2_Buffer)-1)
  35. #define EEPROM_WriteAddress2    (EEPROM_WriteAddress1 + BufferSize1)
  36. #define EEPROM_ReadAddress2     (EEPROM_ReadAddress1 + BufferSize1)

  37. #define I2C_Speed               400000
  38. #define I2C1_SLAVE_ADDRESS7     0xA0
  39. #define I2C_PageSize            8 /* page size of the I2C M24C02 EEPROM */
  40.                                  /*  implemented on the STM3210E-LK board*/
  41. /* Private macro -------------------------------------------------------------*/
  42. #define countof(a) (sizeof(a) / sizeof(*(a)))
  43. /* Private variables ---------------------------------------------------------*/
  44. u8 Tx1_Buffer[] = "LLKKMMJJ";//"/* STM32F10x I2C Firmware ";
  45. u8 Tx2_Buffer[] = "Library Example */";
  46. u8 Rx1_Buffer[BufferSize1], Rx2_Buffer[BufferSize2];
  47. volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;
  48. const u16 EEPROM_ADDRESS = 0xA0;//#define EEPROM_Block0_ADDRESS   0xA0   /* A1 = 0  A2 = 0 A3 = 0*/

  49. I2CTYPE msgI2C;
  50. bool status = false;
  51. /* Private functions ---------------------------------------------------------*/


  52. bool I2C_Event(I2CTYPE &msg)
  53. {
  54.   //#define  I2CMode_Slave
  55.   //Read SR1 and SR2,then save as I2CdwSR
  56.   u32 SR32 = I2C1->SR1 & 0x4FF;
  57.   SR32 |= (I2C1->SR2 & 0x7)<<16;
  58.   
  59.   switch (SR32)
  60.   {
  61. #ifdef  I2CMode_Slave
  62.   //Slave Mode处理事件的优先级 EV2=EV3 > EV4=EV3_2 > EV1=EV3_1
  63.   case  0x00020040://I2C_SR_EV2:           // BUSY and RXNE flags
  64.     msg.Rx[msg.count++] = I2C1->DR;
  65.     break;
  66.   case  0x00060080://I2C_ST_EV3:           // TRA, BUSY and TXE flags
  67.   case  0x00060084://I2C_ST_EV3_1:         // TRA, BUSY, TXE and BTF flags
  68.     I2C1->DR = msg.Tx[msg.count++];
  69.     break;
  70.    
  71.   case  0x00000010://I2C_SR_EV4:           // STOPF flag
  72.     I2C1->CR1 |= 0x0001;
  73.     break;
  74.   case  0x00000400://I2C_ST_EV3_2:         // AF flag
  75.     I2C1->SR1 &= 0xFBFF;
  76.     break;
  77.    
  78.   case  0x00060082://I2C_ST_EV1:           // TRA, BUSY, TXE and ADDR flags
  79.     msg.count = 0;
  80.     break;
  81.   case  0x00020002://I2C_SR_EV1:           // BUSY and ADDR flags
  82.     msg.count = 0;
  83.     break;
  84.    
  85. #else
  86.   //Master Mode处理事件的优先级 EV8=EV6_1=EV7_1 > EV7= > EV5=EV6=EV8_1=EV8_2
  87.   case  0x00070080://I2C_MT_EV8:           // TRA, BUSY, MSL, TXE flags
  88.     if (msg.count < msg.Max)
  89.     {
  90.       I2C1->DR = msg.Tx[msg.count++];
  91.     }
  92.     else
  93.     {
  94.       I2C1->CR2 &= 0xF9FF;
  95.       I2C1->CR1 |= 0x0200;//STOP
  96.     }
  97.     break;
  98.   case  0x00030002://I2C_MR_EV6(EV6_1):    // BUSY, MSL and ADDR flags
  99.     msg.count = 0;
  100.     if (msg.Max == 1)//只接收1个字节的情况
  101.     {
  102.       I2C1->CR1 &= 0xFBFF;//ACK=0
  103.       I2C1->CR1 |= 0x0200;//STOP
  104.     }
  105.     break;
  106.   case  0x00030040://I2C_MR_EV7:(EV7_1):    // BUSY, MSL and RXNE flags
  107.     msg.Rx[msg.count++] = I2C1->DR;
  108.     if (msg.count == (msg.Max-1))
  109.     {
  110.       I2C1->CR1 &= 0xFBFF;//ACK=0
  111.       I2C1->CR1 |= 0x0200;//STOP
  112.     }
  113.     break;
  114.    
  115.   case  0x00030001://I2C_MTR_EV5:          // BUSY, MSL and SB flag
  116.     I2C1->DR = msg.Address;
  117.     break;
  118.   case  0x00070082://I2C_MT_EV6:           // BUSY, MSL, ADDR, TXE and TRA flags
  119.     msg.count = 0;
  120.     break;
  121.   case  0x00070084://I2C_MT_EV8_2:         // TRA, BUSY, MSL, TXE and BTF flags
  122.     I2C1->CR1 |= 0x0200;//STOP
  123.     break;
  124. #endif
  125.   default:
  126.     return false;//异常状态
  127.   }
  128.   return true;
  129. }

  130. void I2C_EE_WaitEepromStandbyState(void)      
  131. {
  132.   vu16 SR1_Tmp = 0;

  133.   do
  134.   {
  135.     /* Send START condition */
  136.     I2C_GenerateSTART(I2C1, ENABLE);
  137.     /* Read I2C1 SR1 register */
  138.     SR1_Tmp = I2C1->SR1;
  139.     I2C1->DR = EEPROM_ADDRESS & 0xFE;/* Send EEPROM address for write */
  140.   }while(!(I2C1->SR1 & 0x0002));
  141.   
  142.   
  143.   if(I2C_GetFlagStatus(I2C1, I2C_FLAG_AF))
  144.   {
  145.     /* Clear AF flag */
  146.     I2C_ClearFlag(I2C1, I2C_FLAG_AF);
  147.   }
  148.   
  149.   /* STOP condition */   
  150.   I2C_GenerateSTOP(I2C1, ENABLE);
  151.   
  152.   /* While the stop bit is set */  
  153.   while (I2C1->CR1 & 0x200);
  154. }

  155. bool I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
  156. {
  157.   u16 Timeout = 0x2000;
  158.   
  159.   while((I2C1->SR2 & 0x2) && Timeout)// While the bus is busy
  160.     Timeout--;
  161.   if (Timeout==0)
  162.     return false;
  163.   
  164.   msgI2C.Address = EEPROM_ADDRESS & 0xFE;
  165.   msgI2C.Tx = &WriteAddr;
  166.   
  167.   I2C1->CR1 |= 0x0100;// Send START condition
  168.   
  169.   //EV5
  170.   Timeout = 0x2000;
  171.   while(!I2C_Event(msgI2C) && Timeout)
  172.   {
  173.     Timeout--;
  174.   }
  175.   if (Timeout==0)
  176.     return false;

  177.   msgI2C.Tx = pBuffer;
  178.   msgI2C.Max = NumByteToWrite;
  179.   //EV6
  180.   Timeout = 0x2000;
  181.   while(!I2C_Event(msgI2C) && Timeout)
  182.   {
  183.     Timeout--;
  184.   }
  185.   if (Timeout==0)
  186.     return false;
  187.   
  188.   //EV8
  189.   Timeout = 0x2000;
  190.   while(!I2C_Event(msgI2C) && Timeout)
  191.   {
  192.     Timeout--;
  193.   }
  194.   if (Timeout==0)
  195.     return false;
  196.   
  197.   /* While there is data to be written */
  198.   while(NumByteToWrite--)  
  199.   {
  200.     //EV8
  201.     Timeout = 0x2000;
  202.     while(!I2C_Event(msgI2C) && Timeout)
  203.     {
  204.       Timeout--;
  205.     }
  206.     if (Timeout==0)
  207.       return false;
  208.   }

  209.   I2C1->CR1 |= 0x0200;/* Send STOP condition */
  210.   
  211.   return true;
  212. }

  213. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  214. {
  215.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

  216.   Addr = WriteAddr % I2C_PageSize;
  217.   count = I2C_PageSize - Addr;
  218.   NumOfPage =  NumByteToWrite / I2C_PageSize;
  219.   NumOfSingle = NumByteToWrite % I2C_PageSize;

  220.   /* If WriteAddr is I2C_PageSize aligned  */
  221.   if(Addr == 0)
  222.   {
  223.     /* If NumByteToWrite < I2C_PageSize */
  224.     if(NumOfPage == 0)
  225.     {
  226.       status = I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  227.       I2C_EE_WaitEepromStandbyState();
  228.     }
  229.     /* If NumByteToWrite > I2C_PageSize */
  230.     else  
  231.     {
  232.       while(NumOfPage--)
  233.       {
  234.         status = I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  235.             I2C_EE_WaitEepromStandbyState();
  236.         WriteAddr +=  I2C_PageSize;
  237.         pBuffer += I2C_PageSize;
  238.       }

  239.       if(NumOfSingle!=0)
  240.       {
  241.         status = I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  242.         I2C_EE_WaitEepromStandbyState();
  243.       }
  244.     }
  245.   }
  246.   /* If WriteAddr is not I2C_PageSize aligned  */
  247.   else
  248.   {
  249.     /* If NumByteToWrite < I2C_PageSize */
  250.     if(NumOfPage== 0)
  251.     {
  252.       status = I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  253.       I2C_EE_WaitEepromStandbyState();
  254.     }
  255.     /* If NumByteToWrite > I2C_PageSize */
  256.     else
  257.     {
  258.       NumByteToWrite -= count;
  259.       NumOfPage =  NumByteToWrite / I2C_PageSize;
  260.       NumOfSingle = NumByteToWrite % I2C_PageSize;       
  261.       
  262.       if(count != 0)
  263.       {  
  264.         status = I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  265.         I2C_EE_WaitEepromStandbyState();
  266.         WriteAddr += count;
  267.         pBuffer += count;
  268.       }
  269.       
  270.       while(NumOfPage--)
  271.       {
  272.         status = I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  273.         I2C_EE_WaitEepromStandbyState();
  274.         WriteAddr +=  I2C_PageSize;
  275.         pBuffer += I2C_PageSize;  
  276.       }
  277.       if(NumOfSingle != 0)
  278.       {
  279.         status = I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  280.         I2C_EE_WaitEepromStandbyState();
  281.       }
  282.     }
  283.   }  
  284. }

  285. bool I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
  286. {
  287.   u16 Timeout = 0x2000;
  288.   
  289.   while((I2C1->SR2 & 0x2) && Timeout)// While the bus is busy
  290.     Timeout--;
  291.   if (Timeout==0)
  292.     return false;
  293.   
  294.   msgI2C.Address = EEPROM_ADDRESS & 0xFE;/* Send EEPROM address for write */
  295.   msgI2C.Tx = &ReadAddr;/* Send the EEPROM's internal address to write to */
  296.   msgI2C.Max = 1;
  297.   
  298.   I2C1->CR1 |= 0x0100;// Send START condition
  299.   
  300.   //EV5
  301.   Timeout = 0x2000;
  302.   while(!I2C_Event(msgI2C) && Timeout)
  303.   {
  304.     Timeout--;
  305.   }
  306.   if (Timeout==0)
  307.     return false;

  308.   //EV6
  309.   Timeout = 0x2000;
  310.   while(!I2C_Event(msgI2C) && Timeout)
  311.   {
  312.     Timeout--;
  313.   }
  314.   if (Timeout==0)
  315.     return false;
  316.   
  317.   I2C_Cmd(I2C1, ENABLE);/* Clear EV6 by setting again the PE bit */

  318.   //EV8
  319.   Timeout = 0x2000;
  320.   while(!I2C_Event(msgI2C) && Timeout)
  321.   {
  322.     Timeout--;
  323.   }
  324.   if (Timeout==0)
  325.     return false;
  326.   
  327.   
  328.   msgI2C.Address = EEPROM_ADDRESS | 0x01;/* Send EEPROM address for read */
  329.   msgI2C.Tx = pBuffer;
  330.   msgI2C.Max = NumByteToRead;
  331.   I2C1->CR1 |= 0x0100;/* Send STRAT condition a second time */  
  332.   
  333.   //EV5
  334.   Timeout = 0x2000;
  335.   while(!I2C_Event(msgI2C) && Timeout)
  336.   {
  337.     Timeout--;
  338.   }
  339.   if (Timeout==0)
  340.     return false;
  341.   
  342.   //EV6
  343.   Timeout = 0x2000;
  344.   while(!I2C_Event(msgI2C) && Timeout)
  345.   {
  346.     Timeout--;
  347.   }
  348.   if (Timeout==0)
  349.     return false;
  350.   
  351.   /* While there is data to be read */
  352.   while(NumByteToRead)  
  353.   {
  354.     //EV7
  355.     Timeout = 0x2000;
  356.     while(!I2C_Event(msgI2C) && Timeout)
  357.     {
  358.       Timeout--;
  359.     }
  360.     if (Timeout==0)
  361.       return false;

  362.     NumByteToRead--;
  363.   }

  364.   /* Enable Acknowledgement to be ready for another reception */
  365.   I2C_AcknowledgeConfig(I2C1, ENABLE);
  366.   
  367.   return true;
  368. }


  369. TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)
  370. {
  371.   while(BufferLength--)
  372.   {
  373.     if(*pBuffer1 != *pBuffer2)
  374.     {
  375.       return FAILED;
  376.     }
  377.    
  378.     pBuffer1++;
  379.     pBuffer2++;
  380.   }

  381.   return PASSED;  
  382. }

  383. void fmain(void)
  384. {
  385.   RCC_HSEConf(9);//72M

  386.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  387.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  388.   //复位I2C
  389.   RCC_APB2PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
  390.   
  391.   
  392.   /* Initialize the I2C EEPROM driver ----------------------------------------*/
  393.   /* Configure I2C1 pins: SCL and SDA */
  394.   GPIO_InitTypeDef  GPIO_InitStructure;
  395.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  396.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  397.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  398.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  399.   /* I2C configuration */
  400.   I2C_InitTypeDef  I2C_InitStructure;
  401.   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  402.   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  403.   I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
  404.   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  405.   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  406.   I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
  407.   /* I2C Peripheral Enable */
  408.   I2C_Cmd(I2C1, ENABLE);
  409.   /* Apply I2C configuration after enabling it -----注意点:先使能后初始化*/
  410.   I2C_Init(I2C1, &I2C_InitStructure);


  411.   /* First write in the memory followed by a read of the written data --------*/
  412.   /* Write on I2C EEPROM from EEPROM_WriteAddress1 */
  413.   I2C_EE_BufferWrite(Tx1_Buffer, EEPROM_WriteAddress1, BufferSize1);

  414.   status = false;
  415.   /* Read from I2C EEPROM from EEPROM_ReadAddress1 */
  416.   status = I2C_EE_BufferRead(Rx1_Buffer, EEPROM_ReadAddress1, BufferSize1);

  417.   TransferStatus1 = Buffercmp(Tx1_Buffer, Rx1_Buffer, BufferSize1);

  418.   /* Wait for EEPROM standby state */
  419.   I2C_EE_WaitEepromStandbyState();

  420.   /* Second write in the memory followed by a read of the written data -------*/
  421.   /* Write on I2C EEPROM from EEPROM_WriteAddress2 */
  422.   I2C_EE_BufferWrite(Tx2_Buffer, EEPROM_WriteAddress2, BufferSize2);

  423.   /* Read from I2C EEPROM from EEPROM_ReadAddress2 */
  424.   I2C_EE_BufferRead(Rx2_Buffer, EEPROM_ReadAddress2, BufferSize2);

  425.   TransferStatus2 = Buffercmp(Tx2_Buffer, Rx2_Buffer, BufferSize2);
  426. }

  427. #endif
  428. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:14:29
  1. /**
  2.   ******************************************************************************
  3.   * @file /IWDG_Example.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-18
  7.   * @brief    IWDG:The IWDG timeout is set to 280 ms,Systick Interrupt is 250ms
  8.   黄灯闪烁,表示每250ms喂狗一次
  9.   亮绿灯,表示系统已经由IWDG复位,resumed from IWDG reset
  10.   按下Keyer4 进入EXTI中断,关闭Systick,使IWDG不能喂狗,系统复位
  11.   ******************************************************************************
  12.   *用途:可用来检测和解决由软件错误引起的故障;当计数器超时时,产生系统复位。
  13.   */
  14.   /*实例应用步骤:
  15.   //1."main.cpp"调用fmain()
  16.   
  17.   //2."stm32f10x_it.cpp"拷贝
  18.   #define __IWDG_Example
  19.   extern void IWDG_Feed();
  20.   void SysTick_Handler(void)
  21.   {
  22.   #if defined __IWDG_Example
  23.     IWDG_Feed();
  24.    
  25.     GPIO_WriteBit(GPIOF, GPIO_Pin_7, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_7)));
  26.   #endif
  27.   }

  28.   void EXTI15_10_IRQHandler(void)
  29.   {
  30.     if(EXTI_GetITStatus(EXTI_Line10) != RESET)
  31.     {
  32.       #if defined __IWDG_Example
  33.         GPIO_ResetBits(GPIOF, GPIO_Pin_7);
  34.         SysTick->CTRL = 0x00000;//复位,关闭计数器
  35.       #endif
  36.       EXTI_ClearITPendingBit(EXTI_Line10);
  37.     }
  38.   }
  39.   
  40.   //3."stm32f10x_it.h"声明
  41.   void EXTI15_10_IRQHandler(void);

  42.   //4.Watch中观察
  43.   LED
  44.   */

  45. #ifndef __IWDG_EXAMPLE_H
  46. #define __IWDG_EXAMPLE_H
  47. /* Includes ------------------------------------------------------------------*/
  48. #include "std32periph.h"

  49. /* Private typedef -----------------------------------------------------------*/
  50. /* Private define ------------------------------------------------------------*/
  51.   #define GPIO_LED          GPIOF
  52.   #define RCC_LED           RCC_APB2Periph_GPIOF
  53. /* Private macro -------------------------------------------------------------*/
  54. /* Private variables ---------------------------------------------------------*/
  55. /* Private functions ---------------------------------------------------------*/

  56. void IWDG_Init(u8 prer, u16 rlr)
  57. {
  58.   IWDG->KR=0X5555;//使能对IWDG->PR和IWDG->RLR的写
  59.   IWDG->PR=prer; //LSI/32=40Khz/4*2^pre
  60.   IWDG->RLR=rlr; //从加载寄存器 IWDG->RLR
  61.   IWDG->KR=0XAAAA;//reload
  62.   IWDG->KR=0XCCCC;//使能看门狗
  63. }

  64. void IWDG_Feed(void)
  65. {
  66.   IWDG->KR=0XAAAA;//reload
  67. }

  68. void fmain(void)
  69. {
  70.   RCC_HSEConf(9);//72M

  71.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_LED | RCC_APB2Periph_AFIO, ENABLE);

  72.   
  73.   GPIO_InitTypeDef GPIO_InitStructure;
  74.   /* Configure GPIO_LED pin 6 and pin 7 as Output push-pull */
  75.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  76.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  77.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  78.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  79.   /* Configure Key Button GPIO Pin as input pull-up (Key Button EXTI Line) */
  80.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  81.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  82.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  83.   
  84.   
  85.   /* Check if the system has resumed from IWDG reset */
  86.   if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
  87.   {/* IWDGRST flag set */
  88.     /* Set GPIO_LED pin 6 */
  89.     GPIO_SetBits(GPIO_LED, GPIO_Pin_6);

  90.     /* Clear reset flags */
  91.     RCC_ClearFlag();
  92.   }
  93.   else
  94.   {/* IWDGRST flag is not set */
  95.     /* Reset GPIO_LED pin 6 */
  96.     GPIO_ResetBits(GPIO_LED, GPIO_Pin_6);
  97.   }

  98.   /* Configure Key Button EXTI Line to generate an interrupt on falling edge */
  99.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
  100.   /* Configure Key Button EXTI Line to generate an interrupt on falling edge */
  101.   EXTI_InitTypeDef EXTI_InitStructure;
  102.   EXTI_ClearITPendingBit(EXTI_Line10);
  103.   EXTI_InitStructure.EXTI_Line = EXTI_Line10;
  104.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  105.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  106.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  107.   EXTI_Init(&EXTI_InitStructure);

  108.   /* NVIC configuration */
  109.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI15_10_IRQn, 0);
  110.   NVIC_GroupSet(NVIC_PriorityGroup_0, SysTick_IRQn, 1);

  111.   /* Configure SysTick to generate an interrupt each 250ms */
  112.   SysTick->LOAD = 250000*9;
  113.   SysTick->VAL = 0x00;//清空计数器
  114.   /* ---------------------------------------------------------------------
  115.   SysTick 控制与状态寄存器的位
  116.   SysTick->CTRL: CountFlag【16】,CLKSource【2】,TickINT【1】,ENABLE【0】
  117.   --------------------------------------------------------------------- */
  118.   //CLKSource【2】=0  使用外部时钟源HCLK(1:内核时钟HCLK/8)
  119.   //  TickINT【1】=0  向下计数至0,不会挂起Systick(1:至0会挂起Systick)
  120.   //   ENABLE【0】=0  禁止计数器(1:使能,至0将CountFlag置1)
  121.   SysTick->CTRL = 0x00003;

  122.   
  123.   /* IWDG timeout equal to 280 ms (40KHz/32=1.25KHz T=[349+1]/1.25=280ms) */
  124.   IWDG_Init(0x3, 349);
  125. }

  126. #endif
  127. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:14:43
  1. /**
  2.   ******************************************************************************
  3.   * @file /NVIC_CM3LPModes.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-19
  7.   * @brief    NVIC:低功耗
  8.   WFE事件  新来的中断、之前悬起的中断等(比较容易唤醒)
  9.   WFI中断  
  10.   ******************************************************************************
  11.   *用途:
  12.   1.睡眠模式
  13.     进入:
  14.       SLEEP-NOW模式:立即进入睡眠模式
  15.         SLEEPDEEP = 0 , SLEEPONEXIT = 0
  16.       SLEEP-ON-EXIT模式:从*****最低优先级*****的中断中退出时,进入睡眠模式(没有成功)
  17.         SLEEPDEEP = 0 , SLEEPONEXIT = 1
  18.       然后执行WFI(等待中断)或WFE(等待事件)指令
  19.     唤醒:WFI(任意中断可唤醒)或WFE(唤醒事件)
  20.     唤醒延时:无

  21.   2.停机模式
  22.     进入:
  23.       设置CM3中的SLEEPDEEP位 , PWR_CR中清除PDDS位 , 设置LPDS位
  24.       然后执行WFI(等待中断)或WFE(等待事件)指令
  25.     唤醒:任意外部中断可唤醒
  26.     唤醒延时:HSI RC唤醒时间 + 电压调节器从低功耗唤醒的时间

  27.   3.待机模式:可实现系统的最低功耗
  28.     进入:
  29.       设置CM3系中的SLEEPDEEP位 , PWR_CR中设置PDDS位 , CWUF位
  30.       然后执行WFI(等待中断)或WFE(等待事件)指令
  31.     唤醒:WKUP引脚的上升沿、RTC闹钟事件、NRST引脚上的外部复位、IWDG复位
  32.     唤醒延时:复位阶段时电压调节器的启动

  33.   SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  34.   */
  35.   /*实例应用步骤:
  36.   //1."main.cpp"调用fmain()
  37.   
  38.   //2."stm32f10x_it.cpp"拷贝
  39.   //#define __NVIC_CM3LPModes
  40.   #if defined __NVIC_CM3LPModes
  41.     extern u8 LowPowerMode;
  42.   #endif
  43.   void EXTI15_10_IRQHandler(void)
  44.   {
  45.     if(EXTI_GetITStatus(EXTI_Line11) != RESET)
  46.     {
  47.       #if defined __NVIC_CM3LPModes
  48.         LowPowerMode = 1;
  49.       #endif
  50.       EXTI_ClearITPendingBit(EXTI_Line11);
  51.     }
  52.   }
  53.   void EXTI0_IRQHandler(void)
  54.   {
  55.     #if defined __NVIC_CM3LPModes
  56.       GPIO_WriteBit(GPIOF, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_8)));
  57.     #endif
  58.     EXTI_ClearITPendingBit(EXTI_Line0);
  59.   }
  60.   
  61.   //3."stm32f10x_it.h"声明
  62.   void EXTI15_10_IRQHandler(void);
  63.   void EXTI0_IRQHandler(void);
  64.   
  65.   //4.Watch中观察
  66.   无动作------蓝灯闪烁    主程序正常运行中
  67.   SleepNow,SleepOnExti,
  68.   按下Sel-----绿灯翻转    进入指定模式
  69.   按下Key1----红灯翻转    唤醒
  70.   Stopping,
  71.   按下Sel-----绿灯翻转    进入指定模式
  72.   按下Key1----红灯翻转    唤醒,时钟变慢(开启或处于低功耗模式(PWR_CR)的设定)
  73.   Standby
  74.   按下Sel-----灯全灭      进入指定模式
  75.   按下Key1----红灯翻转    唤醒
  76.   */

  77. #ifndef __NVIC_CM3LPMODES_H
  78. #define __NVIC_CM3LPMODES_H
  79. /* Includes ------------------------------------------------------------------*/
  80. #include "std32periph.h"

  81. /* Private typedef -----------------------------------------------------------*/
  82. typedef enum
  83. {
  84.   Normal = 0,
  85.   SleepNow = 1,
  86.   SleepOnExti = 2,
  87.   Stopping = 3,
  88.   Standby = 4
  89. }RunMode;
  90. /* Private define ------------------------------------------------------------*/
  91.   #define GPIO_LED      GPIOF   
  92.   #define RCC_LED       RCC_APB2Periph_GPIOF
  93.   #define RCC_EXTI      RCC_APB2Periph_GPIOB
  94. /* Private macro -------------------------------------------------------------*/
  95. /* Private variables ---------------------------------------------------------*/
  96. EXTI_InitTypeDef EXTI_InitStructure;
  97. RunMode rm;
  98. u8 LowPowerMode;
  99. /* Private functions ---------------------------------------------------------*/

  100. void Delay(vu32 nCount)
  101. {
  102.   for(; nCount != 0; nCount--);
  103. }

  104. void fmain(void)
  105. {
  106.   RCC_HSEConf(9);//72M
  107.   
  108.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_LED | RCC_EXTI | RCC_APB2Periph_AFIO, ENABLE);

  109.   //GPIO_LED
  110.   GPIO_InitTypeDef GPIO_InitStructure;
  111.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9;
  112.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  113.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  114.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  115.   //GPIO_WakeUp
  116.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  117.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  118.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  119.   //GPIO_EXTI
  120.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  121.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  122.   GPIO_Init(GPIOB, &GPIO_InitStructure);

  123.   // Connect EXTI Line0 to PA.00
  124.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
  125.   EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  126.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  127.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  128.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  129.   EXTI_Init(&EXTI_InitStructure);
  130.   // Connect EXTI Line11 to PB.11
  131.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);  
  132.   EXTI_InitStructure.EXTI_Line = EXTI_Line11;
  133.   EXTI_Init(&EXTI_InitStructure);
  134.   
  135.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI15_10_IRQn, 1);
  136.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI0_IRQn, 0);
  137.   
  138.   GPIO_ResetBits(GPIO_LED, GPIO_Pin_6);
  139.   rm = SleepNow;//Normal, SleepNow, SleepOnExti(没有成功), Stopping, Standby
  140.   while (1)
  141.   {
  142.     if(LowPowerMode == 1)
  143.     {
  144.       LowPowerMode = 0;
  145.       GPIO_WriteBit(GPIO_LED, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIO_LED, GPIO_Pin_6)));
  146.       
  147.       //SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  148.       switch(rm)
  149.       {
  150.       case SleepNow:
  151.         SCB->SCR &= 0xFFFFFFF0;//SLEEPDEEP = 0 , SLEEPONEXIT = 0
  152.         __WFE();
  153.         break;
  154.       case SleepOnExti:
  155.         SCB->SCR &= 0xFFFFFFF2;//SLEEPDEEP = 0 , SLEEPONEXIT = 1
  156.         SCB->SCR |= 0x00000002;
  157.         __WFE();
  158.         break;
  159.       case Stopping:
  160.         RCC->APB1ENR |= 0x10000000;//PWREN:电源接口时钟使能
  161.         SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  162.         PWR->CR &= 0x1FD;//PWR_CR中清除PDDS位 , 设置LPDS位
  163.         PWR->CR |= 0x001;
  164.         __WFE();
  165.         break;
  166.       case Standby:
  167.         RCC->APB1ENR |= 0x10000000;//PWREN:电源接口时钟使能
  168.         PWR->CSR |= 0x100;//PWR_CSR中设置EWUP位(WakeUp引脚PA0)
  169.         SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  170.         PWR->CR |= 0x006;//PWR_CR中设置PDDS位 , CWUF位
  171.         __WFE();
  172.         break;
  173.       default:
  174.         break;
  175.       }
  176.     }

  177.     Delay(0xFFFFF);
  178.     GPIO_WriteBit(GPIO_LED, GPIO_Pin_9, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIO_LED, GPIO_Pin_9)));
  179.   }
  180. }

  181. #endif
  182. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:19:03
  1. /**
  2.   ******************************************************************************
  3.   * @file /PWR_STANDBY.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-19
  7.   * @brief    PWR:待机模式
  8.   WFE事件  新来的中断、之前悬起的中断等(比较容易唤醒)
  9.   WFI中断  
  10.   ******************************************************************************
  11.   *用途:
  12.   3.待机模式:可实现系统的最低功耗
  13.     进入:
  14.       设置CM3系中的SLEEPDEEP位 , PWR_CR中设置PDDS位 , CWUF位
  15.       然后执行WFI(等待中断)或WFE(等待事件)指令
  16.     唤醒:WKUP引脚的上升沿、RTC闹钟事件、NRST引脚上的外部复位、IWDG复位
  17.     唤醒延时:复位阶段时电压调节器的启动

  18.   SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  19.   */
  20.   /*实例应用步骤:
  21.   //1."main.cpp"调用fmain()
  22.   
  23.   //2."stm32f10x_it.cpp"拷贝
  24.   void SysTick_Handler(void)
  25.   {
  26.     #if defined __PWR_STANDBY
  27.       GPIO_WriteBit(GPIOF, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_6)));
  28.     #endif
  29.   }
  30.   void EXTI15_10_IRQHandler(void)
  31.   {
  32.     if(EXTI_GetITStatus(EXTI_Line11) != RESET)
  33.     {
  34.       #if defined __PWR_STANDBY
  35.         GPIO_SetBits(GPIOF, GPIO_Pin_6);
  36.         RTC_ClearFlag(RTC_FLAG_SEC);
  37.         while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);// Wait till RTC Second event occurs
  38.         RTC_SetAlarm(RTC_GetCounter()+ 3);// Set the RTC Alarm after 3s
  39.         RTC_WaitForLastTask();
  40.         //PWR_EnterSTANDBYMode();
  41.         SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  42.         PWR->CR |= 0x006;//PWR_CR中设置PDDS位 , CWUF位
  43.         __WFE();
  44.       #endif
  45.       EXTI_ClearITPendingBit(EXTI_Line11);
  46.     }
  47.   }
  48.   
  49.   //3."stm32f10x_it.h"声明
  50.   #define __PWR_STANDBY
  51.   void EXTI15_10_IRQHandler(void);
  52.   void SysTick_Handler(void);
  53.   
  54.   //4.Watch中观察
  55.   LED绿灯闪烁
  56.   按下Sel后进入待机模式,3s后RTC闹钟唤醒,黄灯点亮
  57.   */

  58. #ifndef __PWR_STANDBY_H
  59. #define __PWR_STANDBY_H
  60. /* Includes ------------------------------------------------------------------*/
  61. #include "std32periph.h"

  62. /* Private typedef -----------------------------------------------------------*/
  63. /* Private define ------------------------------------------------------------*/
  64.   #define GPIO_LED      GPIOF   
  65.   #define RCC_LED       RCC_APB2Periph_GPIOF
  66.   #define RCC_EXTI      RCC_APB2Periph_GPIOB
  67. /* Private macro -------------------------------------------------------------*/
  68. /* Private variables ---------------------------------------------------------*/
  69. /* Private functions ---------------------------------------------------------*/

  70. void RTC_Configuration(void)
  71. {
  72.   if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)/* System resumed from STANDBY mode */
  73.   {
  74.    
  75.     GPIO_SetBits(GPIO_LED, GPIO_Pin_7);

  76.     /* Clear StandBy flag */
  77.     PWR_ClearFlag(PWR_FLAG_SB);

  78.     RTC_WaitForSynchro();
  79.   }
  80.   else
  81.   {
  82.     /* StandBy flag is not set */
  83.     /* RTC clock source configuration ----------------------------------------*/
  84.     BKP_DeInit();
  85.   
  86.     RCC_LSEConfig(RCC_LSE_ON);
  87.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  88.     {
  89.     }

  90.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  91.     RCC_RTCCLKCmd(ENABLE);

  92.     /* RTC configuration -----------------------------------------------------*/
  93.     RTC_WaitForSynchro();
  94.     /* Set the RTC time base to 1s */
  95.     RTC_SetPrescaler(32767);  
  96.     RTC_WaitForLastTask();
  97.   }
  98. }

  99. void fmain(void)
  100. {
  101.   RCC_HSEConf(9);//72M
  102.   
  103.   RCC_APB2PeriphClockCmd(RCC_EXTI | RCC_LED | RCC_APB2Periph_AFIO, ENABLE);
  104.   
  105.   GPIO_InitTypeDef GPIO_InitStructure;
  106.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  107.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  108.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  109.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);

  110.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  111.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  112.   GPIO_Init(GPIOB, &GPIO_InitStructure);  

  113.   GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
  114.   
  115.   
  116.   /* Enable PWR and BKP clock */
  117.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  118.   /* Enable WKUP pin */
  119.   PWR_WakeUpPinCmd(ENABLE);
  120.   /* Allow access to BKP Domain */
  121.   PWR_BackupAccessCmd(ENABLE);

  122.   /* Configure RTC clock source and prescaler */
  123.   RTC_Configuration();

  124.   /* Configure EXTI Line to generate an interrupt on falling edge */
  125.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
  126.   EXTI_InitTypeDef EXTI_InitStructure;
  127.   EXTI_InitStructure.EXTI_Line = EXTI_Line11;
  128.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  129.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  130.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  131.   EXTI_Init(&EXTI_InitStructure);  

  132.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI15_10_IRQn, 1);

  133.   /* Configure SysTick to generate an interrupt each 250ms */
  134.   SysTick->LOAD = 250000*9;
  135.   SysTick->VAL = 0x00;//清空计数器
  136.   /* ---------------------------------------------------------------------
  137.   SysTick 控制与状态寄存器的位
  138.   SysTick->CTRL: CountFlag【16】,CLKSource【2】,TickINT【1】,ENABLE【0】
  139.   --------------------------------------------------------------------- */
  140.   //CLKSource【2】=0  使用外部时钟源HCLK(1:内核时钟HCLK/8)
  141.   //  TickINT【1】=0  向下计数至0,不会挂起Systick(1:至0会挂起Systick)
  142.   //   ENABLE【0】=0  禁止计数器(1:使能,至0将CountFlag置1)
  143.   SysTick->CTRL = 0x00003;
  144. }

  145. #endif
  146. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:19:19
  1. /**
  2.   ******************************************************************************
  3.   * @file /PWR_STOP.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-19
  7.   * @brief    PWR:停机模式
  8.   WFE事件  新来的中断、之前悬起的中断等(比较容易唤醒)
  9.   WFI中断  
  10.   ******************************************************************************
  11.   *用途:
  12.   2.停机模式
  13.     进入:
  14.       设置CM3中的SLEEPDEEP位 , PWR_CR中清除PDDS位 , 设置LPDS位
  15.       然后执行WFI(等待中断)或WFE(等待事件)指令
  16.     唤醒:任意外部中断可唤醒
  17.     唤醒延时:HSI RC唤醒时间 + 电压调节器从低功耗唤醒的时间

  18.   SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  19.   */
  20.   /*实例应用步骤:
  21.   //1."main.cpp"调用fmain()
  22.   
  23.   //2."stm32f10x_it.cpp"拷贝
  24.   #ifdef  __PWR_STOP
  25.   void RTCAlarm_IRQHandler(void)
  26.   {
  27.     if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
  28.     {
  29.       GPIO_WriteBit(GPIOF, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_8)));
  30.   
  31.       EXTI_ClearITPendingBit(EXTI_Line17);
  32.   
  33.       if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
  34.       {
  35.         PWR_ClearFlag(PWR_FLAG_WU);
  36.       }
  37.   
  38.       RTC_WaitForLastTask();   
  39.   
  40.       RTC_ClearITPendingBit(RTC_IT_ALR);
  41.   
  42.       RTC_WaitForLastTask();
  43.     }
  44.   }
  45.   #endif
  46.   
  47.   //3."stm32f10x_it.h"声明
  48.   #define __PWR_STOP
  49.   void RTCAlarm_IRQHandler(void);
  50.   
  51.   //4.Watch中观察
  52.   LED绿灯变化
  53.   进入停机模式,3s后RTC闹钟唤醒,红灯点亮,循环
  54.   */

  55. #ifndef __PWR_STOP_H
  56. #define __PWR_STOP_H
  57. /* Includes ------------------------------------------------------------------*/
  58. #include "std32periph.h"

  59. /* Private typedef -----------------------------------------------------------*/
  60. /* Private define ------------------------------------------------------------*/
  61.   #define GPIO_LED      GPIOF   
  62.   #define RCC_LED       RCC_APB2Periph_GPIOF
  63. /* Private macro -------------------------------------------------------------*/
  64. /* Private variables ---------------------------------------------------------*/
  65. /* Private functions ---------------------------------------------------------*/

  66. void SYSCLKConfig_STOP(void)
  67. {
  68.   /* Enable HSE */
  69.   RCC_HSEConfig(RCC_HSE_ON);

  70.   /* Wait till HSE is ready */
  71.   ErrorStatus HSEStartUpStatus;
  72.   HSEStartUpStatus = RCC_WaitForHSEStartUp();

  73.   if(HSEStartUpStatus == SUCCESS)
  74.   {
  75.     /* Enable PLL */
  76.     RCC_PLLCmd(ENABLE);

  77.     /* Wait till PLL is ready */
  78.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  79.     {
  80.     }

  81.     /* Select PLL as system clock source */
  82.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  83.     /* Wait till PLL is used as system clock source */
  84.     while(RCC_GetSYSCLKSource() != 0x08)
  85.     {
  86.     }
  87.   }
  88. }

  89. void RTC_Configuration(void)
  90. {
  91.   /* RTC clock source configuration ------------------------------------------*/
  92.   /* Reset Backup Domain */
  93.   BKP_DeInit();
  94.   
  95.   /* Enable the LSE OSC */
  96.   RCC_LSEConfig(RCC_LSE_ON);
  97.   /* Wait till LSE is ready */
  98.   while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  99.   {
  100.   }

  101.   /* Select the RTC Clock Source */
  102.   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  103.   /* Enable the RTC Clock */
  104.   RCC_RTCCLKCmd(ENABLE);

  105.   /* RTC configuration -------------------------------------------------------*/
  106.   /* Wait for RTC APB registers synchronisation */
  107.   RTC_WaitForSynchro();

  108.   /* Set the RTC time base to 1s */
  109.   RTC_SetPrescaler(32767);  
  110.   /* Wait until last write operation on RTC registers has finished */
  111.   RTC_WaitForLastTask();

  112.   /* Enable the RTC Alarm interrupt */
  113.   RTC_ITConfig(RTC_IT_ALR, ENABLE);
  114.   /* Wait until last write operation on RTC registers has finished */
  115.   RTC_WaitForLastTask();
  116. }


  117. void fmain(void)
  118. {
  119.   RCC_HSEConf(9);//72M
  120.   
  121.   RCC_APB2PeriphClockCmd(RCC_LED | RCC_APB2Periph_AFIO, ENABLE);
  122.   
  123.   GPIO_InitTypeDef GPIO_InitStructure;
  124.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
  125.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  126.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  127.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);


  128.   /* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */
  129.   EXTI_ClearITPendingBit(EXTI_Line17);
  130.   EXTI_InitTypeDef EXTI_InitStructure;
  131.   EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  132.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  133.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  134.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  135.   EXTI_Init(&EXTI_InitStructure);

  136.   
  137.   /* Enable PWR and BKP clock */
  138.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  139.   /* Allow access to BKP Domain */
  140.   PWR_BackupAccessCmd(ENABLE);
  141.   /* Configure RTC clock source and prescaler */
  142.   RTC_Configuration();


  143.   NVIC_GroupSet(NVIC_PriorityGroup_0, RTCAlarm_IRQn, 0);

  144.   GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
  145.   
  146.   while (1)
  147.   {
  148.     /* Insert 1.5 second delay */
  149.     Delay_us(1.5e6, 72);

  150.    
  151.     RTC_ClearFlag(RTC_FLAG_SEC);
  152.     while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);

  153.     RTC_SetAlarm(RTC_GetCounter()+ 3);
  154.     RTC_WaitForLastTask();


  155.     GPIO_ResetBits(GPIO_LED, GPIO_Pin_6);


  156.     //PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
  157.     RCC->APB1ENR |= 0x10000000;//PWREN:电源接口时钟使能
  158.     SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  159.     PWR->CR &= 0x1FD;//PWR_CR中清除PDDS位 , 设置LPDS位
  160.     PWR->CR |= 0x001;
  161.     __WFI();
  162.    

  163.     GPIO_SetBits(GPIO_LED, GPIO_Pin_6);

  164.     SYSCLKConfig_STOP();
  165.   }
  166. }

  167. #endif
  168. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:19:38
  1. /**
  2.   ******************************************************************************
  3.   * @file /SPI_Example.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-5-16
  7.   * @brief    SPI:
  8.   ******************************************************************************
  9.   *用途:
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()

  13.   //2.Watch中观察
  14.   Tx_Buffer:Rx_Buffer
  15.   */

  16. #ifndef __SPI_EXAMPLE_H
  17. #define __SPI_EXAMPLE_H
  18. /* Includes ------------------------------------------------------------------*/
  19. #include "std32periph.h"

  20. /* Private typedef -----------------------------------------------------------*/
  21. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  22. /* Private define ------------------------------------------------------------*/
  23.   #define GPIO_CS           GPIOB
  24.   #define RCC_CS            RCC_APB2Periph_GPIOB
  25.   #define Pin_CS            GPIO_Pin_2
  26.   #define SPI_FLASH_CS_LOW()       GPIO_ResetBits(GPIO_CS, Pin_CS)
  27.   #define SPI_FLASH_CS_HIGH()      GPIO_SetBits(GPIO_CS, Pin_CS)

  28.   #define  FLASH_WriteAddress     0x700000
  29.   #define  FLASH_ReadAddress      FLASH_WriteAddress
  30.   #define  FLASH_SectorToErase    FLASH_WriteAddress
  31.   #define  M25P64_FLASH_ID        0x202017
  32.   #define  BufferSize (countof(Tx_Buffer)-1)

  33.   #define SPI_FLASH_PageSize    0x100
  34.   #define WRITE      0x02  /* Write to Memory instruction */
  35.   #define WRSR       0x01  /* Write Status Register instruction */
  36.   #define WREN       0x06  /* Write enable instruction */
  37.   #define READ       0x03  /* Read from Memory instruction */
  38.   #define RDSR       0x05  /* Read Status Register instruction  */
  39.   #define RDID       0x9F  /* Read identification */
  40.   #define SE         0xD8  /* Sector Erase instruction */
  41.   #define BE         0xC7  /* Bulk Erase instruction */
  42.   #define WIP_Flag   0x01  /* Write In Progress (WIP) flag */
  43.   #define Dummy_Byte 0xA5
  44. /* Private macro -------------------------------------------------------------*/
  45.   #define countof(a) (sizeof(a) / sizeof(*(a)))  
  46. /* Private variables ---------------------------------------------------------*/
  47.   u8 Tx_Buffer[] = "STM32F10x SPI Firmware Library Example: communication with an M25P64 SPI FLASH";
  48.   u8 Index, Rx_Buffer[BufferSize];
  49.   volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = PASSED;
  50.   vu32 FLASH_ID = 0;
  51. /* Private functions ---------------------------------------------------------*/
  52.   TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);
  53.   /*----- High layer function -----*/
  54.   void SPI_FLASH_Init(void);
  55.   void SPI_FLASH_SectorErase(u32 SectorAddr);
  56.   void SPI_FLASH_BulkErase(void);
  57.   void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
  58.   void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
  59.   void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
  60.   u32 SPI_FLASH_ReadID(void);
  61.   void SPI_FLASH_StartReadSequence(u32 ReadAddr);
  62.   /*----- Low layer function -----*/
  63.   u8 SPI_FLASH_ReadByte(void);
  64.   u8 SPI_FLASH_SendByte(u8 byte);
  65.   u16 SPI_FLASH_SendHalfWord(u16 HalfWord);
  66.   void SPI_FLASH_WriteEnable(void);
  67.   void SPI_FLASH_WaitForWriteEnd(void);

  68.   
  69. void fmain(void)
  70. {
  71.   RCC_HSEConf(9);//72M
  72.   
  73.   /* Initialize the SPI FLASH driver */
  74.   SPI_FLASH_Init();

  75.     /* Perform a write in the Flash followed by a read of the written data */
  76.   /* Erase SPI FLASH Sector to write on */
  77.   SPI_FLASH_SectorErase(FLASH_SectorToErase);

  78.   /* Write Tx_Buffer data to SPI FLASH memory */
  79.   SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);

  80.   /* Read data from SPI FLASH memory */
  81.   SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);

  82.   /* Check the corectness of written dada */
  83.   TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
  84.   /* TransferStatus1 = PASSED, if the transmitted and received data by SPI1
  85.      are the same */
  86.   /* TransferStatus1 = FAILED, if the transmitted and received data by SPI1
  87.      are different */

  88.   /* Perform an erase in the Flash followed by a read of the written data */
  89.   /* Erase SPI FLASH Sector to write on */
  90.   SPI_FLASH_SectorErase(FLASH_SectorToErase);

  91.   /* Read data from SPI FLASH memory */
  92.   SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);

  93.   /* Check the corectness of erasing operation dada */
  94.   for (Index = 0; Index < BufferSize; Index++)
  95.   {
  96.     if (Rx_Buffer[Index] != 0xFF)
  97.     {
  98.       TransferStatus2 = FAILED;
  99.     }
  100.   }
  101.   /* TransferStatus2 = PASSED, if the specified sector part is erased */
  102.   /* TransferStatus2 = FAILED, if the specified sector part is not well erased  */
  103. }

  104. void SPI_FLASH_Init(void)
  105. {
  106.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
  107.                          RCC_CS, ENABLE);

  108.   GPIO_InitTypeDef GPIO_InitStructure;
  109.   /* Configure SPI1 pins: SCK, MISO and MOSI */
  110.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  111.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  112.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  113.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  114.   /* Configure I/O for Flash Chip select */
  115.   GPIO_InitStructure.GPIO_Pin = Pin_CS;
  116.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  117.   GPIO_Init(GPIO_CS, &GPIO_InitStructure);
  118.   /* Deselect the FLASH: Chip Select high */
  119.   SPI_FLASH_CS_HIGH();

  120.   /* SPI1 configuration */
  121.   SPI_InitTypeDef  SPI_InitStructure;
  122.   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  123.   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  124.   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  125.   SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  126.   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  127.   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  128.   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  129.   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  130.   SPI_InitStructure.SPI_CRCPolynomial = 7;
  131.   SPI_Init(SPI1, &SPI_InitStructure);
  132.   /* Enable SPI1  */
  133.   SPI_Cmd(SPI1, ENABLE);
  134. }

  135. void SPI_FLASH_SectorErase(u32 SectorAddr)
  136. {
  137.   /* Send write enable instruction */
  138.   SPI_FLASH_WriteEnable();

  139.   /* Sector Erase */
  140.   /* Select the FLASH: Chip Select low */
  141.   SPI_FLASH_CS_LOW();
  142.   /* Send Sector Erase instruction */
  143.   SPI_FLASH_SendByte(SE);
  144.   /* Send SectorAddr high nibble address byte */
  145.   SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  146.   /* Send SectorAddr medium nibble address byte */
  147.   SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  148.   /* Send SectorAddr low nibble address byte */
  149.   SPI_FLASH_SendByte(SectorAddr & 0xFF);
  150.   /* Deselect the FLASH: Chip Select high */
  151.   SPI_FLASH_CS_HIGH();

  152.   /* Wait the end of Flash writing */
  153.   SPI_FLASH_WaitForWriteEnd();
  154. }

  155. void SPI_FLASH_BulkErase(void)
  156. {
  157.   /* Send write enable instruction */
  158.   SPI_FLASH_WriteEnable();

  159.   /* Bulk Erase */
  160.   /* Select the FLASH: Chip Select low */
  161.   SPI_FLASH_CS_LOW();
  162.   /* Send Bulk Erase instruction  */
  163.   SPI_FLASH_SendByte(BE);
  164.   /* Deselect the FLASH: Chip Select high */
  165.   SPI_FLASH_CS_HIGH();

  166.   /* Wait the end of Flash writing */
  167.   SPI_FLASH_WaitForWriteEnd();
  168. }

  169. void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
  170. {
  171.   /* Enable the write access to the FLASH */
  172.   SPI_FLASH_WriteEnable();

  173.   /* Select the FLASH: Chip Select low */
  174.   SPI_FLASH_CS_LOW();
  175.   /* Send "Write to Memory " instruction */
  176.   SPI_FLASH_SendByte(WRITE);
  177.   /* Send WriteAddr high nibble address byte to write to */
  178.   SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  179.   /* Send WriteAddr medium nibble address byte to write to */
  180.   SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  181.   /* Send WriteAddr low nibble address byte to write to */
  182.   SPI_FLASH_SendByte(WriteAddr & 0xFF);

  183.   /* while there is data to be written on the FLASH */
  184.   while (NumByteToWrite--)
  185.   {
  186.     /* Send the current byte */
  187.     SPI_FLASH_SendByte(*pBuffer);
  188.     /* Point on the next byte to be written */
  189.     pBuffer++;
  190.   }

  191.   /* Deselect the FLASH: Chip Select high */
  192.   SPI_FLASH_CS_HIGH();

  193.   /* Wait the end of Flash writing */
  194.   SPI_FLASH_WaitForWriteEnd();
  195. }

  196. void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
  197. {
  198.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;

  199.   Addr = WriteAddr % SPI_FLASH_PageSize;
  200.   count = SPI_FLASH_PageSize - Addr;
  201.   NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
  202.   NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

  203.   if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned  */
  204.   {
  205.     if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
  206.     {
  207.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  208.     }
  209.     else /* NumByteToWrite > SPI_FLASH_PageSize */
  210.     {
  211.       while (NumOfPage--)
  212.       {
  213.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
  214.         WriteAddr +=  SPI_FLASH_PageSize;
  215.         pBuffer += SPI_FLASH_PageSize;
  216.       }

  217.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  218.     }
  219.   }
  220.   else /* WriteAddr is not SPI_FLASH_PageSize aligned  */
  221.   {
  222.     if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
  223.     {
  224.       if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
  225.       {
  226.         temp = NumOfSingle - count;

  227.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
  228.         WriteAddr +=  count;
  229.         pBuffer += count;

  230.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
  231.       }
  232.       else
  233.       {
  234.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
  235.       }
  236.     }
  237.     else /* NumByteToWrite > SPI_FLASH_PageSize */
  238.     {
  239.       NumByteToWrite -= count;
  240.       NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
  241.       NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

  242.       SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
  243.       WriteAddr +=  count;
  244.       pBuffer += count;

  245.       while (NumOfPage--)
  246.       {
  247.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
  248.         WriteAddr +=  SPI_FLASH_PageSize;
  249.         pBuffer += SPI_FLASH_PageSize;
  250.       }

  251.       if (NumOfSingle != 0)
  252.       {
  253.         SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  254.       }
  255.     }
  256.   }
  257. }

  258. void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
  259. {
  260.   /* Select the FLASH: Chip Select low */
  261.   SPI_FLASH_CS_LOW();

  262.   /* Send "Read from Memory " instruction */
  263.   SPI_FLASH_SendByte(READ);

  264.   /* Send ReadAddr high nibble address byte to read from */
  265.   SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  266.   /* Send ReadAddr medium nibble address byte to read from */
  267.   SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  268.   /* Send ReadAddr low nibble address byte to read from */
  269.   SPI_FLASH_SendByte(ReadAddr & 0xFF);

  270.   while (NumByteToRead--) /* while there is data to be read */
  271.   {
  272.     /* Read a byte from the FLASH */
  273.     *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
  274.     /* Point to the next location where the byte read will be saved */
  275.     pBuffer++;
  276.   }

  277.   /* Deselect the FLASH: Chip Select high */
  278.   SPI_FLASH_CS_HIGH();
  279. }

  280. u32 SPI_FLASH_ReadID(void)
  281. {
  282.   u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;

  283.   /* Select the FLASH: Chip Select low */
  284.   SPI_FLASH_CS_LOW();

  285.   /* Send "RDID " instruction */
  286.   SPI_FLASH_SendByte(0x9F);

  287.   /* Read a byte from the FLASH */
  288.   Temp0 = SPI_FLASH_SendByte(Dummy_Byte);

  289.   /* Read a byte from the FLASH */
  290.   Temp1 = SPI_FLASH_SendByte(Dummy_Byte);

  291.   /* Read a byte from the FLASH */
  292.   Temp2 = SPI_FLASH_SendByte(Dummy_Byte);

  293.   /* Deselect the FLASH: Chip Select high */
  294.   SPI_FLASH_CS_HIGH();

  295.   Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  296.   return Temp;
  297. }

  298. void SPI_FLASH_StartReadSequence(u32 ReadAddr)
  299. {
  300.   /* Select the FLASH: Chip Select low */
  301.   SPI_FLASH_CS_LOW();

  302.   /* Send "Read from Memory " instruction */
  303.   SPI_FLASH_SendByte(READ);

  304.   /* Send the 24-bit address of the address to read from -----------------------*/
  305.   /* Send ReadAddr high nibble address byte */
  306.   SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  307.   /* Send ReadAddr medium nibble address byte */
  308.   SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  309.   /* Send ReadAddr low nibble address byte */
  310.   SPI_FLASH_SendByte(ReadAddr & 0xFF);
  311. }

  312. u8 SPI_FLASH_ReadByte(void)
  313. {
  314.   return (SPI_FLASH_SendByte(Dummy_Byte));
  315. }

  316. u8 SPI_FLASH_SendByte(u8 byte)
  317. {
  318.   /* Loop while DR register in not emplty */
  319.   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

  320.   /* Send byte through the SPI1 peripheral */
  321.   SPI_I2S_SendData(SPI1, byte);

  322.   /* Wait to receive a byte */
  323.   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

  324.   /* Return the byte read from the SPI bus */
  325.   return SPI_I2S_ReceiveData(SPI1);
  326. }

  327. u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
  328. {
  329.   /* Loop while DR register in not emplty */
  330.   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

  331.   /* Send Half Word through the SPI1 peripheral */
  332.   SPI_I2S_SendData(SPI1, HalfWord);

  333.   /* Wait to receive a Half Word */
  334.   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

  335.   /* Return the Half Word read from the SPI bus */
  336.   return SPI_I2S_ReceiveData(SPI1);
  337. }

  338. void SPI_FLASH_WriteEnable(void)
  339. {
  340.   /* Select the FLASH: Chip Select low */
  341.   SPI_FLASH_CS_LOW();

  342.   /* Send "Write Enable" instruction */
  343.   SPI_FLASH_SendByte(WREN);

  344.   /* Deselect the FLASH: Chip Select high */
  345.   SPI_FLASH_CS_HIGH();
  346. }

  347. void SPI_FLASH_WaitForWriteEnd(void)
  348. {
  349.   u8 FLASH_Status = 0;

  350.   /* Select the FLASH: Chip Select low */
  351.   SPI_FLASH_CS_LOW();

  352.   /* Send "Read Status Register" instruction */
  353.   SPI_FLASH_SendByte(RDSR);

  354.   /* Loop as long as the memory is busy with a write cycle */
  355.   do
  356.   {
  357.     /* Send a dummy byte to generate the clock needed by the FLASH
  358.     and put the value of the status register in FLASH_Status variable */
  359.     FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);

  360.   }
  361.   while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */

  362.   /* Deselect the FLASH: Chip Select high */
  363.   SPI_FLASH_CS_HIGH();
  364. }

  365. TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)
  366. {
  367.   while (BufferLength--)
  368.   {
  369.     if (*pBuffer1 != *pBuffer2)
  370.     {
  371.       return FAILED;
  372.     }

  373.     pBuffer1++;
  374.     pBuffer2++;
  375.   }

  376.   return PASSED;
  377. }

  378. #endif
  379. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
wolfgang2015 回答时间:2016-1-7 15:25:19

@file /EXTI_Example.h

检测下降沿触发中断,不过似乎没有处理按键抖动的问题,会出现释放按键后,有闪亮的情况.....

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版