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

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

[复制链接]
Dylan疾风闪电 发布时间:2016-1-7 14:26
阅读主题, 点击返回1楼
收藏 22 评论60 发布时间:2016-1-7 14:26
60个回答
Dylan疾风闪电 回答时间:2016-1-7 15:06:27
  1. /**
  2.   ******************************************************************************
  3.   * @file /DEBUG.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-19
  7.   * @brief    DEBUG:
  8.   ******************************************************************************
  9.   *用途:方便差错
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()修改以下函数
  13.   
  14.   #define __DEBUG_Example
  15.   void assert_failed(uint8_t* file, uint32_t line)
  16.   {
  17.       // User can add his own implementation to report the file name and line number,
  18.          ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line)
  19.     #ifdef __DEBUG_Example
  20.       printf("Wrong parameters value: file %s on line %d\r\n", file, line);
  21.     #else
  22.       // Infinite loop
  23.       while (1)
  24.       {
  25.       }
  26.     #endif
  27.   }

  28.   //2.PC端USART配置
  29.    - Connect a null-modem female/female RS232 cable between the DB9 connector
  30.         CN2(USART1) and PC serial port.
  31.    
  32.   
  33.    - Hyperterminal configuration:
  34.       - Word Length = 8 Bits
  35.       - One Stop Bit
  36.       - No parity
  37.       - BaudRate = 115200 baud
  38.       - flow control: None

  39.   //3.Terminal I/O中观察
  40.   显示printf的字符串和错误信息
  41.   STM32F10x Firmware Library compiled in DEBUG mode...
  42.   ...Run-time checking enabled

  43.   Wrong parameters value: file D:\xd_ST_ARM\(中文名乱码)\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.cpp on line 1136
  44.   */

  45. #ifndef __DEBUG_H
  46. #define __DEBUG_H
  47. /* Includes ------------------------------------------------------------------*/
  48. #include "std32periph.h"
  49. #include <stdio.h>

  50. /* Private typedef -----------------------------------------------------------*/
  51. /* Private define ------------------------------------------------------------*/
  52. #ifdef __GNUC__
  53.   /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
  54.      set to 'Yes') calls __io_putchar() */
  55.   #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  56. #else
  57.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  58. #endif /* __GNUC__ */
  59. /* Private macro -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. /* Private functions ---------------------------------------------------------*/

  62. void fmain(void)
  63. {
  64.   RCC_HSEConf(9);//72M
  65.   
  66.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
  67.   
  68.   
  69.   GPIO_InitTypeDef GPIO_InitStructure;
  70.   /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  71.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  72.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  73.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  74.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  75.   /* Configure USART1 Rx (PA.10) as input floating */
  76.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  77.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  78.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  79.   

  80. /* USART1 configuration ------------------------------------------------------*/
  81.   /* USART1 configured as follow:
  82.         - BaudRate = 115200 baud  
  83.         - Word Length = 8 Bits
  84.         - One Stop Bit
  85.         - No parity
  86.         - Hardware flow control disabled (RTS and CTS signals)
  87.         - Receive and transmit enabled
  88.   */
  89.   USART_InitTypeDef USART_InitStructure;
  90.   USART_InitStructure.USART_BaudRate = 115200;
  91.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  92.   USART_InitStructure.USART_StopBits = USART_StopBits_1;
  93.   USART_InitStructure.USART_Parity = USART_Parity_No;
  94.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  95.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  96.   USART_Init(USART1, &USART_InitStructure);
  97.   USART_Cmd(USART1, ENABLE);
  98.   
  99.   //在PC端串口助手显示
  100.   u8 buff[] = "\r\n STM32F10x Firmware Library compiled in DEBUG mode... \n\r...Run-time checking enabled  \n\r";
  101.   u8 *p = buff;
  102.   u16 SR = USART1->SR;
  103.   #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))//返回数组元素的个数
  104.   u8 len = ARR_SIZE(buff);
  105.   for(u8 i=0; i<len; i++)
  106.   {
  107.     USART1->DR = *p++;
  108.     while ((USART1->SR & 0x0040) == 0);
  109.   }
  110.   
  111.   //在IAR软件的输出窗口显示
  112.   printf("\r\n STM32F10x Firmware Library compiled in DEBUG mode... \n\r");
  113.   printf("...Run-time checking enabled  \n\r");
  114.   
  115.   //产生错误信息:错误的SPI时钟使能
  116.   /* Simulate wrong parameter passed to library function ---------------------*/
  117.   /* To enable SPI1 clock, RCC_APB2PeriphClockCmd function must be used and
  118.      not RCC_APB1PeriphClockCmd*/
  119.   RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  120.   
  121.   /* Some member of GPIOA_InitStructure structure are not initialized */
  122.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  123.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  124.   /* GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; */
  125.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  126. }

  127. #endif
  128. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:06:46
  1. /**
  2.   ******************************************************************************
  3.   * @file /DMA_ADC_TIM1.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    DMA:通过DMA将ADC采样 反映为TIM1_CH1的脉冲频率(CCR1)
  8.   use a DMA channel to transfer continuously a data from a peripheral (ADC1)
  9.   to another peripheral (TIM1) supporting DMA transfer.
  10.   ******************************************************************************
  11.   *用途:可改为ADC->DR 直接通过 USART->DR等
  12.   */
  13.   /*实例应用步骤:
  14.   //1."main.cpp"调用fmain()
  15.   
  16.   //2.Watch中观察
  17.   TIM1_CCR1
  18.   ADC1_DR
  19.   */

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

  24. /* Private typedef -----------------------------------------------------------*/
  25. /* Private define ------------------------------------------------------------*/
  26. #define ADC1_DR_Address     0x4001244C
  27. #define TIM1_CCR1_Address   0x40012C34
  28. /* Private macro -------------------------------------------------------------*/
  29. /* Private variables ---------------------------------------------------------*/
  30. /* Private functions ---------------------------------------------------------*/

  31. void fmain(void)
  32. {
  33.   RCC_HSEConf(7);//56M

  34.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  35.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
  36.                          RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE);
  37.   //复位ADC
  38.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);
  39.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);


  40.   GPIO_InitTypeDef GPIO_InitStructure;
  41.   /* Configure TIM1 Channel1 output */
  42.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  43.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  44.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  45.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  46.   /* Configure ADC Channel14 as analog input */
  47.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4  ;
  48.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  49.   GPIO_Init(GPIOC, &GPIO_InitStructure);


  50.   /* DMA1 Channel5 configuration ----------------------------------------------*/
  51.   DMA_InitTypeDef           DMA_InitStructure;
  52.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_CCR1_Address;
  53.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC1_DR_Address;
  54.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  55.   DMA_InitStructure.DMA_BufferSize = 1;
  56.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  57.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  58.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  59.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  60.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  61.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  62.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  63.   DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  64.   /* Enable DMA1 Channel5 */
  65.   DMA_Cmd(DMA1_Channel5, ENABLE);

  66.   /* ADC1 configuration ------------------------------------------------------*/
  67.   ADC_InitTypeDef           ADC_InitStructure;
  68.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  69.   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  70.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  71.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  72.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  73.   ADC_InitStructure.ADC_NbrOfChannel = 1;
  74.   ADC_Init(ADC1, &ADC_InitStructure);
  75.   ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);

  76.   // TIM1_channel1:PWM mode、 TIM输出比较极性低、0x7F
  77.   // F = TIMxCLK/(PSC+1)/(ARR+1)  (56/2*2)/4=14M *0x7F
  78.   TIM1->PSC = 3;
  79.   TIM1->ARR = 0xFF0;
  80.   TIM1->CR1 = 0x0000;
  81.   TIM1->CCMR1 &= 0xFF00;
  82.   TIM1->CCMR1 |= 0x0060;
  83.   TIM1->CCER &= 0xFFF0;
  84.   TIM1->CCER |= 0x0001;

  85.   TIM_Cmd(TIM1, ENABLE);
  86.   TIM_CtrlPWMOutputs(TIM1, ENABLE);

  87.   TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);

  88.   ADC_Cmd(ADC1, ENABLE);
  89.   ADC_ResetCalibration(ADC1);
  90.   while(ADC_GetResetCalibrationStatus(ADC1));
  91.   ADC_StartCalibration(ADC1);
  92.   while(ADC_GetCalibrationStatus(ADC1));

  93.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  94. }

  95. #endif
  96. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:12:13
  1. /**
  2.   ******************************************************************************
  3.   * @file /DMA_FlashRAM.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-15
  7.   * @brief    DMA:从ROM中拷贝数组常量到RAM中 (存在弊端,不复位的情况下可能 FAILED)
  8.   ******************************************************************************
  9.   *用途:快速读取ROM
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //2."stm32f10x_it.cpp"拷贝
  15.   extern vu16 CurrDataCounterEnd;
  16.   void DMA1_Channel6_IRQHandler(void)
  17.   {
  18.     if(DMA_GetITStatus(DMA1_IT_TC6))
  19.     {
  20.       CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA1_Channel6);
  21.       DMA_ClearITPendingBit(DMA1_IT_GL6);
  22.     }
  23.   }

  24.   //3."stm32f10x_it.h"声明
  25.   void DMA1_Channel6_IRQHandler(void);

  26.   //4.Watch中观察
  27.   SRC_Const_Buffer[]
  28.   DST_Buffer[]
  29.   */

  30. #ifndef __DMA_FLASHRAM_H
  31. #define __DMA_FLASHRAM_H
  32. /* Includes ------------------------------------------------------------------*/
  33. #include "std32periph.h"

  34. /* Private typedef -----------------------------------------------------------*/
  35. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  36. /* Private define ------------------------------------------------------------*/
  37. #define BufferSize  32
  38. /* Private macro -------------------------------------------------------------*/
  39. /* Private variables ---------------------------------------------------------*/
  40. vu16 CurrDataCounterBegin = 0, CurrDataCounterEnd = 0;
  41. volatile TestStatus TransferStatus = FAILED;
  42. uc32 SRC_Const_Buffer[BufferSize]= {0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
  43.                                     0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
  44.                                     0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
  45.                                     0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
  46.                                     0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
  47.                                     0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
  48.                                     0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
  49.                                     0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};
  50. u32 DST_Buffer[BufferSize];
  51. /* Private functions ---------------------------------------------------------*/

  52. TestStatus Buffercmp(uc32* pBuffer, u32* pBuffer1, u16 BufferLength)
  53. {
  54.   while(BufferLength--)
  55.   {
  56.     if(*pBuffer != *pBuffer1)
  57.     {
  58.       return FAILED;
  59.     }
  60.    
  61.     pBuffer++;
  62.     pBuffer1++;
  63.   }

  64.   return PASSED;  
  65. }

  66. void fmain(void)
  67. {
  68.   RCC_HSEConf(9);//72M

  69.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  70.   NVIC_GroupSet(NVIC_PriorityGroup_0, DMA1_Channel6_IRQn, 0);

  71.   /* DMA1 channel6 configuration */
  72.   DMA_InitTypeDef  DMA_InitStructure;
  73.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Const_Buffer;
  74.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer;
  75.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  76.   DMA_InitStructure.DMA_BufferSize = BufferSize;
  77.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  78.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  79.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  80.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  81.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  82.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  83.   DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
  84.   DMA_Init(DMA1_Channel6, &DMA_InitStructure);

  85.   /* Enable DMA1 Channel6 Transfer Complete interrupt */
  86.   DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

  87.   /* Get Current Data Counter value before transfer begins */
  88.   CurrDataCounterBegin = DMA_GetCurrDataCounter(DMA1_Channel6);

  89.   /* Enable DMA1 Channel6 transfer */
  90.   DMA_Cmd(DMA1_Channel6, ENABLE);

  91.   /* Wait the end of transmission */
  92.   while (CurrDataCounterEnd != 0)
  93.   {
  94.   }
  95.   
  96.   /* Check if the transmitted and received data are equal */
  97.   TransferStatus = Buffercmp(SRC_Const_Buffer, DST_Buffer, BufferSize);
  98.   /* TransferStatus = PASSED, if the transmitted and received data
  99.      are the same */
  100.   /* TransferStatus = FAILED, if the transmitted and received data
  101.      are different */
  102. }

  103. #endif
  104. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:12:29
  1. /**
  2.   ******************************************************************************
  3.   * @file /DMA_FSMC.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-15
  7.   * @brief    DMA:通过2个DMA通道,
  8.   将32位数据SRC_Const_Buffer[]从FLASH_ROM写入外设FSMC的SRAM,
  9.   然后从外设FSMC的SRAM以8位DST_Buffer[]逐个读取数据存入 (存在弊端,不复位的情况下可能 卡while)
  10.   use two DMA channels to transfer a word data buffer from Flash memory to external SRAM memory
  11.   and to recuperate the written data from external SRAM to be stored in internal SRAM.
  12.   ******************************************************************************
  13.   *用途:快速的将32位数据转换成8位数据
  14.   */
  15.   /*实例应用步骤:
  16.   //1."main.cpp"调用fmain()

  17.   //2.Watch中观察
  18.   SRC_Const_Buffer[]
  19.   DST_Buffer[]
  20.   */

  21. #ifndef __DMA_FSMC_H
  22. #define __DMA_FSMC_H
  23. /* Includes ------------------------------------------------------------------*/
  24. #include "std32periph.h"

  25. /* Private typedef -----------------------------------------------------------*/
  26. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  27. /* Private define ------------------------------------------------------------*/
  28. #define BufferSize  32
  29. #define Bank1_SRAM3_ADDR    ((u32)0x68000000)
  30. /* Private macro -------------------------------------------------------------*/
  31. /* Private variables ---------------------------------------------------------*/
  32. volatile TestStatus TransferStatus;
  33. uc32 SRC_Const_Buffer[BufferSize]= {0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
  34.                             0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
  35.                             0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
  36.                             0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
  37.                             0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
  38.                             0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
  39.                             0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
  40.                             0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80};
  41. u8 DST_Buffer[4*BufferSize], Idx = 0;
  42. /* Private functions ---------------------------------------------------------*/

  43. void FSMC_SRAM_Init(void)
  44. {
  45.   FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  46.   FSMC_NORSRAMTimingInitTypeDef  p;
  47.   GPIO_InitTypeDef GPIO_InitStructure;
  48.   
  49.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
  50.                          RCC_APB2Periph_GPIOF, ENABLE);
  51.   
  52. /*-- GPIO Configuration ------------------------------------------------------*/
  53.   /* SRAM Data lines configuration */
  54.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
  55.                                 GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
  56.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  57.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
  59.   
  60.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
  61.                                 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
  62.                                 GPIO_Pin_15;
  63.   GPIO_Init(GPIOE, &GPIO_InitStructure);
  64.   
  65.   /* SRAM Address lines configuration */
  66.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
  67.                                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
  68.                                 GPIO_Pin_14 | GPIO_Pin_15;
  69.   GPIO_Init(GPIOF, &GPIO_InitStructure);
  70.   
  71.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
  72.                                 GPIO_Pin_4 | GPIO_Pin_5;
  73.   GPIO_Init(GPIOG, &GPIO_InitStructure);
  74.   
  75.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
  76.   GPIO_Init(GPIOD, &GPIO_InitStructure);
  77.    
  78.   /* NOE and NWE configuration */  
  79.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
  80.   GPIO_Init(GPIOD, &GPIO_InitStructure);
  81.   
  82.   /* NE3 configuration */
  83.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  84.   GPIO_Init(GPIOG, &GPIO_InitStructure);
  85.   
  86.   /* NBL0, NBL1 configuration */
  87.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  88.   GPIO_Init(GPIOE, &GPIO_InitStructure);
  89.   
  90. /*-- FSMC Configuration ------------------------------------------------------*/
  91.   p.FSMC_AddressSetupTime = 0;
  92.   p.FSMC_AddressHoldTime = 0;
  93.   p.FSMC_DataSetupTime = 2;
  94.   p.FSMC_BusTurnAroundDuration = 0;
  95.   p.FSMC_CLKDivision = 0;
  96.   p.FSMC_DataLatency = 0;
  97.   p.FSMC_AccessMode = FSMC_AccessMode_A;

  98.   FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
  99.   FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  100.   FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
  101.   FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  102.   FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  103.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  104.   FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  105.   FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  106.   FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  107.   FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  108.   FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  109.   FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  110.   FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  111.   FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

  112.   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

  113.   /* Enable FSMC Bank1_SRAM Bank */
  114.   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);  
  115. }

  116. TestStatus Buffercmp(uc32* pBuffer, u32* pBuffer1, u16 BufferLength)
  117. {
  118.   while(BufferLength--)
  119.   {
  120.     if(*pBuffer != *pBuffer1)
  121.     {
  122.       return FAILED;
  123.     }
  124.    
  125.     pBuffer++;
  126.     pBuffer1++;
  127.   }

  128.   return PASSED;  
  129. }

  130. void fmain(void)
  131. {
  132.   RCC_HSEConf(9);//72M

  133.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2 | RCC_AHBPeriph_FSMC, ENABLE);

  134.   
  135.   /* FSMC for SRAM and SRAM pins configuration */
  136.   FSMC_SRAM_Init();

  137.   DMA_InitTypeDef    DMA_InitStructure;
  138.   /* Write to FSMC -----------------------------------------------------------*/
  139.   /* DMA2 channel5 configuration */
  140.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Const_Buffer;
  141.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Bank1_SRAM3_ADDR;   
  142.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  143.   DMA_InitStructure.DMA_BufferSize = 32;
  144.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  145.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  146.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  147.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  148.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  149.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  150.   DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
  151.   DMA_Init(DMA2_Channel5, &DMA_InitStructure);
  152.   DMA_Cmd(DMA2_Channel5, ENABLE);
  153.   while(!DMA_GetFlagStatus(DMA2_FLAG_TC5));
  154.   DMA_ClearFlag(DMA2_FLAG_TC5);

  155.   /* Read from FSMC ----------------------------------------------------------*/
  156.   /* Destination buffer initialization */
  157.   for(Idx=0; Idx<128; Idx++)
  158.     DST_Buffer[Idx]=0;
  159.   /* DMA1 channel3 configuration */
  160.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)Bank1_SRAM3_ADDR;  
  161.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer;
  162.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  163.   DMA_InitStructure.DMA_BufferSize = 128;
  164.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
  165.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  166.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  167.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  168.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  169.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  170.   DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
  171.   DMA_Init(DMA1_Channel3, &DMA_InitStructure);
  172.   DMA_Cmd(DMA1_Channel3, ENABLE);
  173.   while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));
  174.   DMA_ClearFlag(DMA1_FLAG_TC3);

  175.   /* Check if the transmitted and received data are equal */
  176.   TransferStatus = Buffercmp(SRC_Const_Buffer, (u32*)DST_Buffer, BufferSize);
  177.   /* TransferStatus = PASSED, if the transmitted and received data
  178.      are the same */
  179.   /* TransferStatus = FAILED, if the transmitted and received data
  180.      are different */
  181. }

  182. #endif
  183. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:12:56
  1. /**
  2.   ******************************************************************************
  3.   * @file /EXTI_Example.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-17
  7.   * @brief    EXTI:按下PB10(Key4) 翻转绿灯(PF6)上的电平
  8.   ******************************************************************************
  9.   *用途:执行外部中断,来切换某些功能
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //2."stm32f10x_it.cpp"拷贝
  15.   #define GPIO_LED  GPIOF
  16.   void EXTI15_10_IRQHandler(void)
  17.   {
  18.       if(EXTI_GetITStatus(EXTI_Line10) != RESET)
  19.     {
  20.       GPIO_WriteBit(GPIO_LED, GPIO_Pin_6, (BitAction)((1-GPIO_ReadOutputDataBit(GPIO_LED, GPIO_Pin_6))));
  21.   
  22.       EXTI_ClearITPendingBit(EXTI_Line10);
  23.     }
  24.   }
  25.   
  26.   //3."stm32f10x_it.h"声明
  27.   void EXTI15_10_IRQHandler(void);

  28.   //4.Watch中观察
  29.   LED
  30.   */

  31. #ifndef __EXTI_EXAMPLE_H
  32. #define __EXTI_EXAMPLE_H
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "std32periph.h"

  35. /* Private typedef -----------------------------------------------------------*/
  36. /* Private define ------------------------------------------------------------*/
  37.   #define GPIO_LED        GPIOF   
  38.   #define RCC_LED         RCC_APB2Periph_GPIOF
  39.   #define GPIO_EXTI       GPIOB
  40.   #define RCC_EXTI        RCC_APB2Periph_GPIOB
  41. /* Private macro -------------------------------------------------------------*/
  42. /* Private variables ---------------------------------------------------------*/
  43. /* Private functions ---------------------------------------------------------*/

  44. void fmain(void)
  45. {
  46.   RCC_HSEConf(9);//72M

  47.   RCC_APB2PeriphClockCmd(RCC_EXTI | RCC_LED | RCC_APB2Periph_AFIO, ENABLE);
  48.   
  49.   GPIO_InitTypeDef GPIO_InitStructure;
  50.   /* Configure GPIO Led pin 6 as Output push-pull */
  51.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  52.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  53.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  54.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  55.   /* Configure Key Button GPIO Pin as input pull-up (Key Button EXTI Line) */
  56.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  57.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  58.   GPIO_Init(GPIO_EXTI, &GPIO_InitStructure);
  59.   

  60.   //NVIC for EXTI
  61.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI15_10_IRQn, 0);

  62.   
  63.   /* Connect Key Button EXTI Line to Key Button GPIO Pin */
  64.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
  65.   /* Configure Key Button EXTI Line to generate an interrupt on falling edge */  
  66.   EXTI_InitTypeDef EXTI_InitStructure;
  67.   EXTI_InitStructure.EXTI_Line = EXTI_Line10;
  68.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  69.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  70.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  71.   EXTI_Init(&EXTI_InitStructure);

  72.   /* Generate software interrupt: simulate a falling edge applied on Key Button EXTI line */
  73.   EXTI_GenerateSWInterrupt(EXTI_Line10);
  74. }

  75. #endif
  76. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
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****/
复制代码
wolfgang 回答时间:2016-1-7 15:25:19

@file /EXTI_Example.h

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

所属标签

相似分享

官网相关资源

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