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

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

[复制链接]
Dylan疾风闪电 发布时间:2016-1-7 14:26
一、前言
  今天在论坛上看到有人在讨论STM32睡眠模式的唤醒,一时兴起,就开始打扫“仓库”了。
结果扫出很多“旧货”,拿来分享给刚接触STM32的新人们!希望对你的学习有所帮助~~~


二、目录           

  所有代码的功能使用和描述,均在头文件开头的注释中!(通过点击楼层,直接跳转到目标代码)
注:所有代码均是在例程上改版而来的,所以嵌入自己的程序前需要验证!所有资料都是2012年的,所以部分描述对现有版本不适用!
1)楼层#2
3ADCs_DMA.h  ADC1,2,3:独立模式、单通道、连续转换
  ADC1:通过 DMA1_Channel1 将数据存入 ADC1ConvertedValue 变量地址
  ADC2:用中断 ADC1_2_IRQn 将数据存入 ADC2ConvertedValue 变量
  ADC3:通过 DMA2_Channel5 将数据存入 ADC3ConvertedValue 变量地址
2)楼层#3:ADC_AnalogWatchdog.h
  ADC1:独立模式、单通道、连续转换
  如果ADC转换的模拟电压 超出阀值范围,SR的AWD置1可产生中断.
  阀值位于ADC_HTR和ADC_LTR寄存器的最低12个有效位中.
  阀值独立于由ADC_CR2寄存器上的ALIGN位选择的数据对齐模式.  比较是在对齐之前完成的.
3)楼层#4:ADC_RegSimulDualMode.h
  ADC1,2:双ADC同步规则模式
  注意1: 不要在2个ADC上转换相同的通道(如果转换两个ADC的相同通道,不可能提供重叠的采样时间)。
  注意2: ADC2的外部触发必须使能,否则只能采集一个数据。
4)楼层#5:ADC_TIMTrigAutoInjection.h  
  ADC1:独立模式、单通道、单次转换、外部触发、自动注入
  自动注入 如果设置了JAUTO位,在规则组通道之后,注入组通道被自动转换。
5)楼层#6:BKP_Tamper.h
  BKP:保存VBAT掉电前的数据
  当TAMPER引脚上的信号从’0’变成’1’或者从’1’变成’0’
  (取决于备份控制寄存器BKP_CR的TPAL位),BKP_TamperPinLevelConfig(BKP_TamperPinLevel_Low);//设置侵入检测管脚的有效电平
  会产生一个侵入检测事件。
  侵入检测事件将所有数据备份寄存器内容清除。
  在一个侵入事件被检测到并被清除后,侵入检测引脚TAMPER应该被禁止。
  然后,在再次写入备份数据寄存器前重新用TPE位启动侵入检测功能。
  这样,可以阻止软件在侵入检测引脚上仍然有侵入事件时对备份数据寄存器进行写操作。这相当于对侵入引脚TAMPER进行电平检测。
6)楼层#7:CAN_Example.h
  收发寄存器 RDLR,RDHR,TDLR,TDHR
  例如 CANx->sFIFOMailBox[FIFONumber].RDLR;
7)楼层#9:CM3_BitBand.h  
  CM3:BitBand(别名区域)
  use CortexM3 Bit-Band access to perform atomic read-modify-write and read operations on a varaible in SRAM.
  对Bit-band区域某个字节的写操作,Cortex-M3都将自动转换成对相对应比特位的读-修改-写操作。
  对Bit-band区域某个字节的读操作则将转换成相对应比特位的读操作。
  公式:Bit-Band地址= Bit-Band域首地址 + (操作字节的偏移量× 32) + (操作位的偏移量× 4)
                    = Bit-Band域首地址 | (操作字节的偏移量<<5) | (操作位的偏移量<<2)
  内置SRAM区的Bit-Band域首地址为0x22000000
  外设寄存器区的Bit-Band域首地址为0x42000000
8)楼层#10:CM3_ModePrivilege.h
  CM3:特殊模式 (此例未验证成功:__set_PSP()等宏未定义)
  阀值独立于由ADC_CR2寄存器上的ALIGN位选择的数据对齐模式.  比较是在对齐之前完成的.
9)楼层#11:CRC_Example.h
  CRC:以多项式(0x4C11DB7)进行CRC计算得到一个32位的值
10)楼层#12:DAC_2ChTriangleWave.h  
   DAC:使用不同三角波发生器的同时触发
11)楼层#13:DAC_DMAEscalator.h
  DAC:DMA输出梯形波
12)楼层#14:DAC_DualModeDMASineWave.h
  DAC:双DAC通道转换
  DAC集成了3个供双DAC模式使用的寄存器:DHR8RD、DHR12RD和DHR12LD,
  只需要访问一个寄存器即可完成同时驱动2个DAC通道的操作。
13)楼层#15:DAC_NoiseWave.h
  DAC:噪声生成
  可以利用线性反馈移位寄存器(Linear Feedback Shift Register LFSR)产生幅度变化的伪噪声。
14)楼层#16:DEBUG.h
  printf("...");
15)楼层#17:DMA_ADC_TIM1.h
  DMA:通过DMA将ADC采样 反映为TIM1_CH1的脉冲频率(CCR1)
16)楼层#18:DMA_FlashRAM.h
  DMA:从ROM中拷贝数组常量到RAM中 (存在弊端,不复位的情况下可能 FAILED)
17)楼层#19:DMA_FSMC.h
  DMA:通过2个DMA通道,
  将32位数据SRC_Const_Buffer[]从FLASH_ROM写入外设FSMC的SRAM,
  然后从外设FSMC的SRAM以8位DST_Buffer[]逐个读取数据存入 (存在弊端,不复位的情况下可能 卡while)
18)楼层#20:EXTI_Example.h
  EXTI:按下PB10(Key4) 翻转绿灯(PF6)上的电平
19)楼层#21:FLASH_Program.h
  FLASH:擦写数据到FLASH地址
20)楼层#22:FLASH_WriteProtection.h
  FLASH:写保护(写保护部分存在问题,无法设置保护)
21)楼层#23:FSMC_NAND.h
  FSMC:(未研究)
22)楼层#24:I2C_M24C02EEPROM.h
  I2C:(ST的I2C问题很多,建议不用,选择IO口模拟)--测试不通过,待调整。《申明:这里只是上传老的资料,描述也是以前的。故对存在问题的代码也不进行优化!》
23)楼层#25:IWDG_Example.h
  IWDG:The IWDG timeout is set to 280 ms,Systick Interrupt is 250ms
  黄灯闪烁,表示每250ms喂狗一次
  亮绿灯,表示系统已经由IWDG复位,resumed from IWDG reset
  按下Keyer4 进入EXTI中断,关闭Systick,使IWDG不能喂狗,系统复位
24)楼层#26:NVIC_CM3LPModes.h
  NVIC:低功耗
25)楼层#27:PWR_STANDBY.h
  PWR:待机模式
26)楼层#28:PWR_STOP.h
  PWR:停机模式
27)楼层#29:SPI_Example.h
  无.


三、结语
         
  为了便于大家阅读,所以将代码片段上传。
  可以按照每个示例中的“实例应用步骤:”直接复制粘贴,一步到位的进行测试,测试结果也在“4.Watch中观察”中写明。
  闲话不说,大家往下“看”吧!








收藏 22 评论60 发布时间:2016-1-7 14:26

举报

60个回答
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: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****/
复制代码
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 14:26:10
本帖最后由 Dylan疾风闪电 于 2016-1-8 11:20 编辑

为了大家学习、测试的便利,在这将IAR平台的工程文件打包上传。(文字描述部分不一定正确,毕竟是早期的个人理解。希望不要产生误导信息。) STM32F103ZE例子实施.rar (403.32 KB, 下载次数: 96)
Dylan疾风闪电 回答时间:2016-1-7 14:26:36
  1. /**
  2.   ******************************************************************************
  3.   * @file /ADC_AnalogWatchdog.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-12
  7.   * @brief    ADC1:独立模式、单通道、连续转换
  8.   如果ADC转换的模拟电压 超出阀值范围,SR的AWD置1可产生中断.
  9.   阀值位于ADC_HTR和ADC_LTR寄存器的最低12个有效位中.
  10.   阀值独立于由ADC_CR2寄存器上的ALIGN位选择的数据对齐模式.  比较是在对齐之前完成的.
  11.   ******************************************************************************
  12.   *用途:报警、指示灯
  13.   */
  14.   /*实例应用步骤:
  15.   //1."main.cpp"调用fmain()
  16.   
  17.   //2."stm32f10x_it.cpp"拷贝
  18.   void ADC1_2_IRQHandler(void)
  19.   {
  20.     GPIO_WriteBit(GPIO_LED, GPIO_Pin_6, Bit_SET);// Toggle LED
  21.     GPIO_WriteBit(GPIO_LED, GPIO_Pin_6, Bit_RESET);
  22.   
  23.     ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);// Clear ADC1 AWD pending interrupt bit
  24.   }
  25.   
  26.   //3."stm32f10x_it.h"声明
  27.   void ADC1_2_IRQHandler(void);
  28.   
  29.   //4.Watch中观察
  30.   LED变化
  31.   */

  32. #ifndef __ADC_ANALOGWATCHDOG_H
  33. #define __ADC_ANALOGWATCHDOG_H
  34. /* Includes ------------------------------------------------------------------*/
  35. #include "std32periph.h"

  36. /* Private typedef -----------------------------------------------------------*/
  37. /* Private define ------------------------------------------------------------*/
  38. #define GPIO_LED      GPIOF
  39. #define RCC_LED       RCC_APB2Periph_GPIOF
  40. /* Private macro -------------------------------------------------------------*/
  41. /* Private variables ---------------------------------------------------------*/
  42. /* Private functions ---------------------------------------------------------*/

  43. void fmain(void)
  44. {
  45.   RCC_HSEConf(7);//56M

  46.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_LED, ENABLE);
  47.   //复位ADC
  48.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 , ENABLE);
  49.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 , DISABLE);

  50.   GPIO_InitTypeDef GPIO_InitStructure;
  51.   /* Configure GOIO_LED pin 6 as output push-pull ----------------------------*/
  52.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  53.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  55.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  56.   /* Configure PA.01 (ADC Channel1) as analog input --------------------------*/
  57.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  58.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  59.   GPIO_Init(GPIOA, &GPIO_InitStructure);

  60.   //NVIC for ADC1
  61.   NVIC_GroupSet(NVIC_PriorityGroup_0, ADC1_2_IRQn, 0);

  62.   ADC_InitTypeDef ADC_InitStructure;
  63.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  64.   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  65.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  66.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  67.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  68.   ADC_InitStructure.ADC_NbrOfChannel = 1;
  69.   ADC_Init(ADC1, &ADC_InitStructure);
  70.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5);

  71.   //AnalogWatchdogThresholds 模拟看门狗高低阈yu值
  72.   ADC1->LTR = 0x0300;
  73.   ADC1->HTR = 0x0800;//0x0B00;//设成远大于实际波动的值0x0FF0;便不会超限了//
  74.   
  75.   ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_1);  //本例重点设置:对单个ADC通道设置模拟看门狗
  76.   ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);
  77.   ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);

  78.   ADC_Cmd(ADC1, ENABLE);
  79.   ADC_ResetCalibration(ADC1);
  80.   while(ADC_GetResetCalibrationStatus(ADC1));
  81.   ADC_StartCalibration(ADC1);
  82.   while(ADC_GetCalibrationStatus(ADC1));
  83.   
  84.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  85. }

  86. #endif
  87. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 14:29:07
  1. /**
  2.   ******************************************************************************
  3.   * @file /ADC_RegSimulDualMode.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-12
  7.   * @brief    ADC1,2:双ADC同步规则模式
  8.   注意1: 不要在2个ADC上转换相同的通道(如果转换两个ADC的相同通道,不可能提供重叠的采样时间)。
  9.   注意2: ADC2的外部触发必须使能,否则只能采集一个数据。
  10.   ******************************************************************************
  11.   *用途:同步采样
  12.   */
  13.   /*实例应用步骤:
  14.   //1."main.cpp"调用fmain()
  15.   
  16.   //4.Watch中观察
  17.   LED变化
  18.   */

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

  23. /* Private typedef -----------------------------------------------------------*/
  24. /* Private define ------------------------------------------------------------*/
  25. /* Private macro -------------------------------------------------------------*/
  26. /* Private variables ---------------------------------------------------------*/
  27. vu32 ADC_DualConvertedValueTab[16];
  28. /* Private functions ---------------------------------------------------------*/

  29. void fmain(void)
  30. {
  31.   RCC_HSEConf(7);//56M

  32.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  33.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |
  34.                          RCC_APB2Periph_GPIOA, ENABLE);
  35.   //复位ADC
  36.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 , ENABLE);
  37.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 , DISABLE);

  38.   
  39.   /* PA.01,02,03,04(ADC Channel11,2,3,4) as analog input ---------------------*/
  40.   GPIO_InitTypeDef GPIO_InitStructure;
  41.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
  42.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  43.   GPIO_Init(GPIOA, &GPIO_InitStructure);


  44.   /* DMA1 channel1 configuration ----------------------------------------------*/
  45.   DMA_InitTypeDef   DMA_InitStructure;
  46.   DMA_InitStructure.DMA_PeripheralBaseAddr = ((u32)0x4001244C);//(u32)ADC1_DR_Address;
  47.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_DualConvertedValueTab;
  48.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  49.   DMA_InitStructure.DMA_BufferSize = 16;
  50.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  51.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  52.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  53.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  54.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  55.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  56.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  57.   DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  58.   DMA_Cmd(DMA1_Channel1, ENABLE);

  59.   //ADC Public Setting
  60.   ADC_InitTypeDef   ADC_InitStructure;
  61.   ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//本例重点:双ADC同步规则模式
  62.   ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  63.   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  64.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  65.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  66.   ADC_InitStructure.ADC_NbrOfChannel = 2;
  67.   /* ADC1 configuration ------------------------------------------------------*/
  68.   ADC_Init(ADC1, &ADC_InitStructure);
  69.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);   
  70.   ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5);
  71.   ADC_DMACmd(ADC1, ENABLE);

  72.   /* ADC2 configuration ------------------------------------------------------*/
  73.   ADC_Init(ADC2, &ADC_InitStructure);
  74.   ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 1, ADC_SampleTime_239Cycles5);
  75.   ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 2, ADC_SampleTime_239Cycles5);
  76.   ADC_ExternalTrigConvCmd(ADC2, ENABLE);

  77.   ADC_Cmd(ADC1, ENABLE);
  78.   /* Enable Vrefint channel17 */
  79.   ADC_TempSensorVrefintCmd(ENABLE);//启用温度传感器
  80.   ADC_ResetCalibration(ADC1);//重置校准寄存器
  81.   while(ADC_GetResetCalibrationStatus(ADC1));
  82.   ADC_StartCalibration(ADC1);
  83.   while(ADC_GetCalibrationStatus(ADC1));

  84.   /* Enable ADC2 */
  85.   ADC_Cmd(ADC2, ENABLE);
  86.   ADC_ResetCalibration(ADC2);
  87.   while(ADC_GetResetCalibrationStatus(ADC2));
  88.   ADC_StartCalibration(ADC2);
  89.   while(ADC_GetCalibrationStatus(ADC2));

  90.   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  91.   while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
  92.   DMA_ClearFlag(DMA1_FLAG_TC1);
  93. }

  94. #endif
  95. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 14:53:45
  1. /**
  2.   ******************************************************************************
  3. * @file /ADC_TIMTrigAutoInjection.h  ##此程序有瑕疵:会进入HardFault_Handler中断,疑似程序执行过快跑飞
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-13
  7.   * @brief    ADC1:独立模式、单通道、单次转换、外部触发、自动注入
  8.   自动注入 如果设置了JAUTO位,在规则组通道之后,注入组通道被自动转换。
  9.   ******************************************************************************
  10.   *用途:滞后1个特定转换周期的连续转换
  11.   */
  12.   /*实例应用步骤:
  13.   //1."main.cpp"调用fmain()
  14.   
  15.   //2."stm32f10x_it.cpp"拷贝
  16.   extern vu16 ADC_InjectedConvertedValueTab[32];
  17.   vu32 Index;
  18.   void ADC1_2_IRQHandler(void)
  19.   {
  20.     GPIO_WriteBit(GPIOF, GPIO_Pin_6, Bit_SET);

  21.     ADC_InjectedConvertedValueTab[Index++] = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
  22.     ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);

  23.     GPIO_WriteBit(GPIOF, GPIO_Pin_6, Bit_RESET);
  24.   }
  25.   
  26.   //3."stm32f10x_it.h"声明
  27.   void ADC1_2_IRQHandler(void);
  28.   
  29.   //4.Watch中观察
  30.   LED
  31.   ADC_RegularConvertedValueTab
  32.   ADC_InjectedConvertedValueTab
  33.   */

  34. #ifndef __ADC_TIMTRIGAUTOINJECTION_H
  35. #define __ADC_TIMTRIGAUTOINJECTION_H
  36. /* Includes ------------------------------------------------------------------*/
  37. #include "std32periph.h"

  38. /* Private typedef -----------------------------------------------------------*/
  39. /* Private define ------------------------------------------------------------*/
  40. #define GPIO_LED      GPIOF
  41. #define RCC_LED       RCC_APB2Periph_GPIOF
  42. /* Private macro -------------------------------------------------------------*/
  43. /* Private variables ---------------------------------------------------------*/
  44. vu16 ADC_RegularConvertedValueTab[32], ADC_InjectedConvertedValueTab[32];
  45. /* Private functions ---------------------------------------------------------*/

  46. void fmain(void)
  47. {
  48.   RCC_HSEConf(7);//56M

  49.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  50.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_LED |
  51.                          RCC_APB2Periph_ADC1  | RCC_APB2Periph_TIM1, ENABLE);
  52.   //复位ADC
  53.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 , ENABLE);
  54.   RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1 , DISABLE);

  55.   
  56.   GPIO_InitTypeDef GPIO_InitStructure;
  57.   /* PA.01,02,03,04(ADC Channel11,2,3,4) as analog input ---------------------*/
  58.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  59.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  60.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  61.   /* Configure TIM1_CH1 (PA8) as alternate function push-pull */
  62.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  63.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  64.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  65.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  66.   // LED
  67.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  68.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  69.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);

  70.   
  71.   //NVIC for ADC2
  72.   NVIC_GroupSet(NVIC_PriorityGroup_0, ADC1_2_IRQn, 0);


  73.   /* DMA1 Channel1 Configuration ----------------------------------------------*/
  74.   DMA_InitTypeDef           DMA_InitStructure;
  75.   DMA_InitStructure.DMA_PeripheralBaseAddr = ((u32)0x4001244C);//ADC1_DR_Address;
  76.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_RegularConvertedValueTab;
  77.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  78.   DMA_InitStructure.DMA_BufferSize = 32;
  79.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  80.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  81.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  82.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  83.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  84.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  85.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  86.   DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  87.   DMA_Cmd(DMA1_Channel1, ENABLE);

  88.   /* ADC1 configuration ------------------------------------------------------*/
  89.   ADC_InitTypeDef           ADC_InitStructure;
  90.   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  91.   ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  92.   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  93.   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//本例重点
  94.   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  95.   ADC_InitStructure.ADC_NbrOfChannel = 1;
  96.   ADC_Init(ADC1, &ADC_InitStructure);

  97.   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_13Cycles5);
  98.   ADC_DMACmd(ADC1, ENABLE);
  99.   ADC_ExternalTrigConvCmd(ADC1, ENABLE);

  100.   ADC_InjectedSequencerLengthConfig(ADC1, 1);
  101.   ADC_InjectedChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_71Cycles5);
  102.   ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
  103.   ADC_AutoInjectedConvCmd(ADC1, ENABLE);
  104.   ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);

  105.   // TIM1_channel1:PWM mode、 TIM输出比较极性低、0x7F
  106.   // F = TIMxCLK/(PSC+1)/(ARR+1)  (56/2*2)/4=14M *0x7F
  107.   TIM1->PSC = 3;
  108.   TIM1->ARR = 0xFF;
  109.   TIM1->CR1 = 0x0000;
  110.   TIM1->CCMR1 &= 0xFF00;
  111.   TIM1->CCMR1 |= 0x0060;
  112.   TIM1->CCER &= 0xFFF0;
  113.   TIM1->CCER |= 0x0003;
  114.   TIM1->CCR1 = 0x7F;

  115.   
  116.   ADC_Cmd(ADC1, ENABLE);
  117.   ADC_ResetCalibration(ADC1);
  118.   while(ADC_GetResetCalibrationStatus(ADC1));
  119.   ADC_StartCalibration(ADC1);
  120.   while(ADC_GetCalibrationStatus(ADC1));

  121.   TIM_Cmd(TIM1, ENABLE);
  122.   TIM_CtrlPWMOutputs(TIM1, ENABLE); //TIM1刹车和死区寄存器:主输出使能

  123.   while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
  124.   DMA_ClearFlag(DMA1_FLAG_TC1);

  125.   TIM_Cmd(TIM1, DISABLE);
  126. }

  127. #endif
  128. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 14:54:02
  1. /**
  2.   ******************************************************************************
  3.   * @file /BKP_Tamper.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-13
  7.   * @brief    BKP:保存VBAT掉电前的数据
  8.   当TAMPER引脚上的信号从’0’变成’1’或者从’1’变成’0’
  9.   (取决于备份控制寄存器BKP_CR的TPAL位),BKP_TamperPinLevelConfig(BKP_TamperPinLevel_Low);//设置侵入检测管脚的有效电平
  10.   会产生一个侵入检测事件。
  11.   侵入检测事件将所有数据备份寄存器内容清除。
  12.   在一个侵入事件被检测到并被清除后,侵入检测引脚TAMPER应该被禁止。
  13.   然后,在再次写入备份数据寄存器前重新用TPE位启动侵入检测功能。
  14.   这样,可以阻止软件在侵入检测引脚上仍然有侵入事件时对备份数据寄存器进行写操作。这相当于对侵入引脚TAMPER进行电平检测。
  15.   ******************************************************************************
  16.   *用途:“保密”,即一旦受到意外的侵入,STM32将毁灭数据。这是通过Tamper机制来实现的。
  17.   只要仍有VBAT,那么Tamper检测仍是有效的.
  18.   注意:这个引脚的上拉电阻必须接到VBAT而不是接到VDD。
  19.   否则,如果电源断开(VDD变低),也会引发一次Tamper事件,而这往往并不是设计都的本意。
  20.   */
  21.   /*实例应用步骤:
  22.   //1."main.cpp"调用fmain()
  23.   
  24.   //2."stm32f10x_it.cpp"拷贝
  25.   #define GPIO_LED          GPIOF
  26.   extern u32 IsBackupRegReset(void);
  27.   void TAMPER_IRQHandler(void)
  28.   {
  29.     if(BKP_GetITStatus() != RESET)
  30.     {
  31.       if(IsBackupRegReset() == 0)// Check if Backup registers are cleared
  32.       {
  33.         GPIO_WriteBit(GPIO_LED, GPIO_Pin_8, Bit_SET);
  34.       }
  35.       else
  36.       {
  37.         GPIO_WriteBit(GPIO_LED, GPIO_Pin_9, Bit_SET);
  38.       }
  39.       BKP_ClearITPendingBit();// Clear Tamper pin interrupt pending bit
  40.       BKP_ClearFlag();// Clear Tamper pin Event(TE) pending flag
  41.     }
  42.   }
  43.   
  44.   //3."stm32f10x_it.h"声明
  45.   void TAMPER_IRQHandler(void);
  46.   
  47.   //4.Watch中观察
  48.   LED
  49.   */

  50. #ifndef __BKP_TAMPER_H
  51. #define __BKP_TAMPER_H
  52. /* Includes ------------------------------------------------------------------*/
  53. #include "std32periph.h"

  54. /* Private typedef -----------------------------------------------------------*/
  55. /* Private define ------------------------------------------------------------*/
  56. #define GPIO_LED          GPIOF   
  57. #define RCC_LED           RCC_APB2Periph_GPIOF
  58. #define BKP_DR_NUMBER     42
  59. /* Private macro -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. u16 BKPDataReg[BKP_DR_NUMBER] =
  62. {
  63.   BKP_DR1, BKP_DR2, BKP_DR3, BKP_DR4, BKP_DR5, BKP_DR6, BKP_DR7, BKP_DR8,
  64.   BKP_DR9, BKP_DR10, BKP_DR11, BKP_DR12, BKP_DR13, BKP_DR14, BKP_DR15, BKP_DR16,
  65.   BKP_DR17, BKP_DR18, BKP_DR19, BKP_DR20, BKP_DR21, BKP_DR22, BKP_DR23, BKP_DR24,
  66.   BKP_DR25, BKP_DR26, BKP_DR27, BKP_DR28, BKP_DR29, BKP_DR30, BKP_DR31, BKP_DR32,
  67.   BKP_DR33, BKP_DR34, BKP_DR35, BKP_DR36, BKP_DR37, BKP_DR38, BKP_DR39, BKP_DR40,
  68.   BKP_DR41, BKP_DR42
  69. };
  70. /* Private functions ---------------------------------------------------------*/

  71. u32 IsBackupRegReset(void)
  72. {
  73.   for (u8 index = 0; index < BKP_DR_NUMBER; index++)
  74.   {
  75.     if (BKP_ReadBackupRegister(BKPDataReg[index]) != 0x0000)
  76.       return (index + 1);
  77.   }
  78.   return 0;  
  79. }

  80. u32 CheckBackupReg(u16 FirstBackupData)
  81. {
  82.   for (u8 index = 0; index < BKP_DR_NUMBER; index++)
  83.   {
  84.     if (BKP_ReadBackupRegister(BKPDataReg[index]) != (FirstBackupData + (index * 0x5A)))
  85.       return (index + 1);
  86.   }
  87.   return 0;  
  88. }

  89. void fmain(void)
  90. {
  91.   RCC_HSEConf(9);//72M

  92.   RCC_APB2PeriphClockCmd(RCC_LED, ENABLE);

  93.   /* Configure GPIO_LED Pin 6, Pin 7, Pin 8 and Pin 9 as Output push-pull ----*/
  94.   GPIO_InitTypeDef GPIO_InitStructure;
  95.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  96.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  97.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  98.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  99.   
  100.   
  101.   //NVIC for ADC2
  102.   NVIC_GroupSet(NVIC_PriorityGroup_0, TAMPER_IRQn, 0);

  103.   
  104.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  105.   PWR_BackupAccessCmd(ENABLE);//使能RTC和后备寄存器访问
  106.   BKP_ClearFlag();
  107.   BKP_TamperPinLevelConfig(BKP_TamperPinLevel_Low);//设置侵入检测管脚的有效电平
  108.   BKP_ITConfig(ENABLE);
  109.   BKP_TamperPinCmd(ENABLE);
  110.    
  111.   u16 FirstBackupData = 0xA53C;
  112.   for (u8 index = 0; index < BKP_DR_NUMBER; index++)
  113.   {
  114.     BKP_WriteBackupRegister(BKPDataReg[index], FirstBackupData + (index * 0x5A));
  115.   }  

  116.   if(CheckBackupReg(0xA53C) == 0x00)
  117.   {
  118.     GPIO_Write(GPIO_LED, GPIO_Pin_6);
  119.   }
  120.   else
  121.   {
  122.     GPIO_Write(GPIO_LED, GPIO_Pin_7);
  123.   }
  124. }

  125. #endif
  126. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 14:55:06
本帖最后由 Dylan疾风闪电 于 2016-1-7 15:02 编辑
  1. /**
  2.   ******************************************************************************
  3.   * @file /CAN_Example.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-13
  7.   * @brief    CAN:
  8.   收发寄存器 RDLR,RDHR,TDLR,TDHR
  9.   例如 CANx->sFIFOMailBox[FIFONumber].RDLR;
  10.   ******************************************************************************
  11.   *
  12.   */
  13.   /*实例应用步骤:
  14.   //1."main.cpp"调用fmain()
  15.   
  16.   //2."stm32f10x_it.cpp"拷贝
  17.   extern vu32 ret;
  18.   void USB_LP_CAN1_RX0_IRQHandler(void)
  19.   {
  20.     CanRxMsg RxMessage;
  21.     RxMessage.StdId=0x00;
  22.     RxMessage.ExtId=0x00;
  23.     RxMessage.IDE=0;
  24.     RxMessage.DLC=0;
  25.     RxMessage.FMI=0;
  26.     RxMessage.Data[0]=0x00;
  27.     RxMessage.Data[1]=0x00;
  28.     CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
  29.     if((RxMessage.ExtId==0x1234) && (RxMessage.IDE==CAN_ID_EXT)
  30.        && (RxMessage.DLC==2) && ((RxMessage.Data[1]|RxMessage.Data[0]<<8)==0xDECA))
  31.       ret = 1;
  32.     else
  33.       ret = 0;
  34.   }
  35.   
  36.   //3."stm32f10x_it.h"声明
  37.   void USB_LP_CAN1_RX0_IRQHandler(void);
  38.   
  39.   //4.Watch中观察
  40.   LED
  41.   */

  42. #ifndef __CAN_EXAMPLE_H
  43. #define __CAN_EXAMPLE_H
  44. /* Includes ------------------------------------------------------------------*/
  45. #include "std32periph.h"

  46. /* Private typedef -----------------------------------------------------------*/
  47. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  48. /* Private define ------------------------------------------------------------*/
  49. #define GPIO_LED          GPIOF   
  50. #define RCC_LED           RCC_APB2Periph_GPIOF
  51. /* Private macro -------------------------------------------------------------*/
  52. /* Private variables ---------------------------------------------------------*/
  53. vu32 ret = 0; /* for return of the interrupt handling */
  54. volatile TestStatus TestRx;
  55. /* Private functions ---------------------------------------------------------*/

  56. TestStatus CAN_Polling(void)
  57. {
  58.   CAN_InitTypeDef        CAN_InitStructure;
  59.   CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  60.   CanTxMsg TxMessage;
  61.   CanRxMsg RxMessage;
  62.   u32 i = 0;
  63.   u8 TransmitMailbox = 0;

  64.   /* CAN register init */
  65.   CAN_DeInit(CAN1);
  66.   CAN_StructInit(&CAN_InitStructure);

  67.   /* CAN cell init */
  68.   CAN_InitStructure.CAN_TTCM=DISABLE;
  69.   CAN_InitStructure.CAN_ABOM=DISABLE;
  70.   CAN_InitStructure.CAN_AWUM=DISABLE;
  71.   CAN_InitStructure.CAN_NART=DISABLE;
  72.   CAN_InitStructure.CAN_RFLM=DISABLE;
  73.   CAN_InitStructure.CAN_TXFP=DISABLE;
  74.   CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
  75.   CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  76.   CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
  77.   CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
  78.   CAN_InitStructure.CAN_Prescaler=5;
  79.   CAN_Init(CAN1, &CAN_InitStructure);

  80.   /* CAN filter init */
  81.   CAN_FilterInitStructure.CAN_FilterNumber=0;
  82.   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  83.   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  84.   CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  85.   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  86.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  87.   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  88.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
  89.   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  90.   CAN_FilterInit(&CAN_FilterInitStructure);

  91.   /* transmit */
  92.   TxMessage.StdId=0x11;
  93.   TxMessage.RTR=CAN_RTR_DATA;
  94.   TxMessage.IDE=CAN_ID_STD;
  95.   TxMessage.DLC=2;
  96.   TxMessage.Data[0]=0xCA;
  97.   TxMessage.Data[1]=0xFE;

  98.   TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
  99.   i = 0;
  100.   while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFF))
  101.   {
  102.     i++;
  103.   }

  104.   i = 0;
  105.   while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFF))
  106.   {
  107.     i++;
  108.   }

  109.   /* receive */
  110.   RxMessage.StdId=0x00;
  111.   RxMessage.IDE=CAN_ID_STD;
  112.   RxMessage.DLC=0;
  113.   RxMessage.Data[0]=0x00;
  114.   RxMessage.Data[1]=0x00;
  115.   CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

  116.   if (RxMessage.StdId!=0x11)
  117.   {
  118.     return FAILED;  
  119.   }

  120.   if (RxMessage.IDE!=CAN_ID_STD)
  121.   {
  122.     return FAILED;
  123.   }

  124.   if (RxMessage.DLC!=2)
  125.   {
  126.     return FAILED;  
  127.   }

  128.   if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
  129.   {
  130.     return FAILED;
  131.   }
  132.   
  133.   return PASSED; /* Test Passed */
  134. }

  135. TestStatus CAN_Interrupt(void)
  136. {
  137.   CAN_InitTypeDef        CAN_InitStructure;
  138.   CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  139.   CanTxMsg TxMessage;
  140.   u32 i = 0;

  141.   /* CAN register init */
  142.   CAN_DeInit(CAN1);
  143.   CAN_StructInit(&CAN_InitStructure);

  144.   /* CAN cell init */
  145.   CAN_InitStructure.CAN_TTCM=DISABLE;
  146.   CAN_InitStructure.CAN_ABOM=DISABLE;
  147.   CAN_InitStructure.CAN_AWUM=DISABLE;
  148.   CAN_InitStructure.CAN_NART=DISABLE;
  149.   CAN_InitStructure.CAN_RFLM=DISABLE;
  150.   CAN_InitStructure.CAN_TXFP=DISABLE;
  151.   CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
  152.   CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  153.   CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;
  154.   CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;
  155.   CAN_InitStructure.CAN_Prescaler=1;
  156.   CAN_Init(CAN1, &CAN_InitStructure);

  157.   /* CAN filter init */
  158.   CAN_FilterInitStructure.CAN_FilterNumber=1;
  159.   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  160.   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  161.   CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  162.   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  163.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  164.   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  165.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
  166.   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  167.   CAN_FilterInit(&CAN_FilterInitStructure);

  168.   /* CAN FIFO0 message pending interrupt enable */
  169.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

  170.   /* transmit 1 message */
  171.   TxMessage.StdId=0x00;
  172.   TxMessage.ExtId=0x1234;
  173.   TxMessage.IDE=CAN_ID_EXT;
  174.   TxMessage.RTR=CAN_RTR_DATA;
  175.   TxMessage.DLC=2;
  176.   TxMessage.Data[0]=0xDE;
  177.   TxMessage.Data[1]=0xCA;
  178.   CAN_Transmit(CAN1, &TxMessage);

  179.   /* initialize the value that will be returned */
  180.   ret = 0xFF;
  181.       
  182.   /* receive message with interrupt handling */
  183.   i=0;
  184.   while((ret == 0xFF) && (i < 0xFFF))
  185.   {
  186.     i++;
  187.   }
  188.   
  189.   if (i == 0xFFF)
  190.   {
  191.     ret=0;  
  192.   }

  193.   /* disable interrupt handling */
  194.   CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);

  195.   return (TestStatus)ret;
  196. }

  197. void fmain(void)
  198. {
  199.   RCC_HSEConf(9);//72M

  200.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_LED, ENABLE);
  201.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  202.   //复位CAN
  203.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1 , ENABLE);
  204.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1 , DISABLE);

  205.   GPIO_InitTypeDef GPIO_InitStructure;
  206.   /* Configure GPIO_LED pin6, pin7, pin8 and pin9 as Output push-pull */
  207.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  208.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  209.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  210.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);
  211.   /* Configure CAN pin: RX */
  212.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  213.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  214.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  215.   /* Configure CAN pin: TX */
  216.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  217.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  218.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  219.   
  220.   
  221.   //NVIC for ADC2
  222.   NVIC_GroupSet(NVIC_PriorityGroup_0, USB_LP_CAN1_RX0_IRQn, 0);

  223.   
  224.   TestRx = CAN_Polling();/* CAN transmit at 100Kb/s and receive by polling in loopback mode */
  225.   if (TestRx == FAILED)
  226.   {
  227.     GPIO_SetBits(GPIO_LED, GPIO_Pin_8);
  228.   }
  229.   else
  230.   {
  231.     GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
  232.   }

  233.   TestRx = CAN_Interrupt();/* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */
  234.   if (TestRx == FAILED)
  235.   {
  236.     GPIO_SetBits(GPIO_LED, GPIO_Pin_9);
  237.   }
  238.   else
  239.   {
  240.     GPIO_SetBits(GPIO_LED, GPIO_Pin_7);
  241.   }
  242. }

  243. #endif
  244. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码

zhangdaijin 回答时间:2016-1-7 14:59:19
这个牛!!!
Dylan疾风闪电 回答时间:2016-1-7 15:03:34
  1. /**
  2.   ******************************************************************************
  3.   * @file /CM3_BitBand.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-13
  7.   * @brief    CM3:BitBand(别名区域)
  8.   use CortexM3 Bit-Band access to perform atomic read-modify-write and read operations on a varaible in SRAM.
  9.   对Bit-band区域某个字节的写操作,Cortex-M3都将自动转换成对相对应比特位的读-修改-写操作。
  10.   对Bit-band区域某个字节的读操作则将转换成相对应比特位的读操作。
  11.   公式:Bit-Band地址= Bit-Band域首地址 + (操作字节的偏移量× 32) + (操作位的偏移量× 4)
  12.                     = Bit-Band域首地址 | (操作字节的偏移量<<5) | (操作位的偏移量<<2)
  13.   内置SRAM区的Bit-Band域首地址为0x22000000
  14.   外设寄存器区的Bit-Band域首地址为0x42000000
  15.   ******************************************************************************
  16.   *用途:通过宏BitBand_GetAddr()计算得到别名区域的地址,从而简化位操作
  17.   由"stm32f10x_flash.icf"文件可知,实际可用的Flash空间不是无限的
  18.   ROM = 0x08000000 ~ 0x080FFFFF;
  19.   RAM = 0x20000000 ~ 0x2000FFFF;//64KB
  20.   cstack = 0x800;
  21.   heap = 0x200;
  22.   place in ROM_region   { readonly };//1024KB = u16(2Byte)*512*1024
  23.   place in RAM_region   { readwrite,//61.5KB = u16*123*256=u16*31488
  24.                         block CSTACK,//2KB = u16*1024
  25.                         block HEAP };//512Byte = u16*256
  26.   */
  27.   /*实例应用步骤:
  28.   //1."main.cpp"调用fmain()

  29.   //2.Watch中观察
  30.   LED
  31.   */

  32. #ifndef __CM3_BITBAND_H
  33. #define __CM3_BITBAND_H
  34. /* Includes ------------------------------------------------------------------*/
  35. #include "std32periph.h"

  36. /* Private typedef -----------------------------------------------------------*/
  37. /* Private define ------------------------------------------------------------*/
  38. #define RAM_BASE       0x20000000
  39. #define RAM_BB_BASE    0x22000000
  40. /* Private macro -------------------------------------------------------------*/
  41. #define  Var_ResetBit_BB(VarAddr, BitNumber)    \
  42.           (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 0)
  43.    
  44. #define Var_SetBit_BB(VarAddr, BitNumber)       \
  45.           (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 1)

  46. #define Var_GetBit_BB(VarAddr, BitNumber)       \
  47.           (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)))

  48. //自添加BitBand原始公式
  49. #define BitBand_SetVal(PPP, Offset, BitNo, Val)\
  50.           (*(vu32*) (0x42000000 | ((PPP & 0x0FFFFFFF)<<5) | (Offset<<5) | (BitNo<<2)) = (Val))
  51. #define BitBand_GetAddr(PPP, Offset, BitNo)\
  52.           (0x42000000 | ((PPP & 0x0FFFFFFF)<<5) | (Offset<<5) | (BitNo<<2))
  53. /* Private variables ---------------------------------------------------------*/
  54. vu32 Var, VarAddr = 0, VarBitValue = 0;
  55. /* Private functions ---------------------------------------------------------*/

  56. void fmain(void)
  57. {
  58.   Var = 0x00005AA5;

  59.   RCC_HSEConf(9);//72M

  60. /* A mapping formula shows how to reference each word in the alias region to a corresponding
  61. bit in the bit-band region. The mapping formula is:
  62.   bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number ?4)

  63. where:
  64.    - bit_word_addr: is the address of the word in the alias memory region that maps to the
  65.                     targeted bit.
  66.    - bit_band_base is the starting address of the alias region
  67.    - byte_offset is the number of the byte in the bit-band region that contains the targeted bit
  68.    - bit_number is the bit position (0-7) of the targeted bit */

  69. /* Get the variable address --------------------------------------------------*/
  70.   VarAddr = (u32)&Var;

  71. /* Modify variable bit using bit-band access ---------------------------------*/
  72.   /* Modify Var variable bit 0 -----------------------------------------------*/
  73.   Var_ResetBit_BB(VarAddr, 0);  /* Var = 0x00005AA4 */
  74.   Var_SetBit_BB(VarAddr, 0);    /* Var = 0x00005AA5 */
  75.   
  76.   /* Modify Var variable bit 11 -----------------------------------------------*/
  77.   Var_ResetBit_BB(VarAddr, 11);             /* Var = 0x000052A5 */
  78.   /* Get Var variable bit 11 value */
  79.   VarBitValue = Var_GetBit_BB(VarAddr, 11); /* VarBitValue = 0x00000000 */
  80.   
  81.   Var_SetBit_BB(VarAddr, 11);               /* Var = 0x00005AA5 */
  82.   /* Get Var variable bit 11 value */
  83.   VarBitValue = Var_GetBit_BB(VarAddr, 11);    /* VarBitValue = 0x00000001 */
  84.   
  85.   /* Modify Var variable bit 31 -----------------------------------------------*/
  86.   Var_SetBit_BB(VarAddr, 31);               /* Var = 0x80005AA5 */
  87.   /* Get Var variable bit 31 value */
  88.   VarBitValue = Var_GetBit_BB(VarAddr, 31); /* VarBitValue = 0x00000001 */
  89.    
  90.   Var_ResetBit_BB(VarAddr, 31);             /* Var = 0x00005AA5 */
  91.   /* Get Var variable bit 31 value */
  92.   VarBitValue = Var_GetBit_BB(VarAddr, 31); /* VarBitValue = 0x00000000 */
  93.   
  94.   //自己添加的程序:点亮LED(PF.06)
  95.   (*(vu32*)0x4242031C) = 1;//RCC_APB2...IOFEN
  96.   
  97.   (*(vu32*)0x42238060) = 1;//GPIOF_CRL...MODE6_0(0x4223806?)
  98.   (*(vu32*)0x42238064) = 1;//GPIOF_CRL...MODE6_1
  99.   (*(vu32*)0x42238068) = 0;//GPIOF_CRL...CNF6_0
  100.   (*(vu32*)0x4223806C) = 0;//GPIOF_CRL...CNF6_1
  101.   
  102.   (*(vu32*)0x42238070) = 1;//GPIOF_CRL...MODE7_0(0x4223807?)
  103.   (*(vu32*)0x42238074) = 1;//GPIOF_CRL...MODE7_1
  104.   (*(vu32*)0x42238078) = 0;//GPIOF_CRL...CNF7_0
  105.   (*(vu32*)0x4223807C) = 0;//GPIOF_CRL...CNF7_1
  106.   
  107.   (*(vu32*)0x42238080) = 1;//GPIOF_CRH...MODE8_0(0x4223808?)
  108.   (*(vu32*)0x42238084) = 1;//GPIOF_CRH...MODE8_1
  109.   (*(vu32*)0x42238088) = 0;//GPIOF_CRH...CNF8_0
  110.   (*(vu32*)0x4223808C) = 0;//GPIOF_CRH...CNF8_1
  111.   
  112.   (*(vu32*)0x42238090) = 1;//GPIOF_CRH...MODE9_0(0x4223809?)
  113.   (*(vu32*)0x42238094) = 1;//GPIOF_CRH...MODE9_1
  114.   (*(vu32*)0x42238098) = 0;//GPIOF_CRH...CNF9_0
  115.   (*(vu32*)0x4223809C) = 0;//GPIOF_CRH...CNF9_1

  116.   u8 ms_1 = 10, ms = 100;
  117.   u32 base = 1500;//100~1000
  118.   s8  is = 1;
  119.   while(1)
  120.   {
  121.     (*(vu32*)0x42238198) = 1;//GPIOF_ODR...Pin6
  122.     (*(vu32*)0x4223819C) = 0;//GPIOF_ODR...Pin7
  123.     (*(vu32*)0x422381A0) = 1;//GPIOF_ODR...Pin8
  124.     (*(vu32*)0x422381A4) = 0;//GPIOF_ODR...Pin9
  125.    
  126.     Delay_us(ms_1*base,72);
  127.    
  128.     (*(vu32*)0x42238198) = 0;//GPIOF_ODR...Pin6
  129.     (*(vu32*)0x4223819C) = 1;//GPIOF_ODR...Pin7
  130.     (*(vu32*)0x422381A0) = 0;//GPIOF_ODR...Pin8
  131.     (*(vu32*)0x422381A4) = 1;//GPIOF_ODR...Pin9
  132.    
  133.     Delay_us((ms-ms_1)*base,72);
  134.    
  135.     ms_1 += 10*is;
  136.     if(ms_1 <= 10)
  137.       is = 1;
  138.     else if(ms_1 >= 90)
  139.       is = -1;
  140.   }
  141.   /*同上:区别是,上面直接用已知的地址 操作位,下面宏计算地址 并操作位
  142.   BitBand_SetVal(RCC_BASE, 0x18, 7, 1); //RCC_APB2ENR_IOPFEN
  143.   BitBand_SetVal(GPIOF_BASE, 0, 27, 0);//GPIOF_CRL
  144.   BitBand_SetVal(GPIOF_BASE, 0, 26, 0);
  145.   BitBand_SetVal(GPIOF_BASE, 0, 25, 1);
  146.   BitBand_SetVal(GPIOF_BASE, 0, 24, 1);
  147.   
  148.   BitBand_SetVal(GPIOF_BASE, 0, 31, 0);//GPIOF_CRL
  149.   BitBand_SetVal(GPIOF_BASE, 0, 30, 0);
  150.   BitBand_SetVal(GPIOF_BASE, 0, 29, 1);
  151.   BitBand_SetVal(GPIOF_BASE, 0, 28, 1);
  152.   
  153.   BitBand_SetVal(GPIOF_BASE, 4, 3, 0);//GPIOF_CRH
  154.   BitBand_SetVal(GPIOF_BASE, 4, 2, 0);
  155.   BitBand_SetVal(GPIOF_BASE, 4, 1, 1);
  156.   BitBand_SetVal(GPIOF_BASE, 4, 0, 1);
  157.   
  158.   BitBand_SetVal(GPIOF_BASE, 4, 7, 0);//GPIOF_CRH
  159.   BitBand_SetVal(GPIOF_BASE, 4, 6, 0);
  160.   BitBand_SetVal(GPIOF_BASE, 4, 5, 1);
  161.   BitBand_SetVal(GPIOF_BASE, 4, 4, 1);

  162.   while(1)
  163.   {
  164.     BitBand_SetVal(GPIOF_BASE, 0xC, 6, 1);//GPIOF_ODR
  165.     BitBand_SetVal(GPIOF_BASE, 0xC, 7, 0);//GPIOF_ODR
  166.     BitBand_SetVal(GPIOF_BASE, 0xC, 8, 1);//GPIOF_ODR
  167.     BitBand_SetVal(GPIOF_BASE, 0xC, 9, 0);//GPIOF_ODR
  168.    
  169.     Delay_us(2e5,72);
  170.    
  171.     BitBand_SetVal(GPIOF_BASE, 0xC, 6, 0);//GPIOF_ODR
  172.     BitBand_SetVal(GPIOF_BASE, 0xC, 7, 1);//GPIOF_ODR
  173.     BitBand_SetVal(GPIOF_BASE, 0xC, 8, 0);//GPIOF_ODR
  174.     BitBand_SetVal(GPIOF_BASE, 0xC, 9, 1);//GPIOF_ODR
  175.    
  176.     Delay_us(2e5,72);
  177.   }*/
  178. }

  179. #endif
  180. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:04:51
  1. /**
  2.   ******************************************************************************
  3.   * @file /CM3_ModePrivilege.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    CM3:特殊模式 (此例未验证成功:__set_PSP()等宏未定义)
  8.   ******************************************************************************
  9.   *用途:
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()

  13.   //2."stm32f10x_it.cpp"修改系统中断
  14.   void SVCHandler(void)
  15.   {
  16.     __set_CONTROL(2);// Switch back Thread mode to privileged
  17.   }

  18.   //3.Watch中观察
  19.   */

  20. #ifndef __CM3_MODEPRIVILEGE_H
  21. #define __CM3_MODEPRIVILEGE_H
  22. /* Includes ------------------------------------------------------------------*/
  23. #include "std32periph.h"
  24. #include "core_cm3.h"//宏__...

  25. /* Private typedef -----------------------------------------------------------*/
  26. /* Private define ------------------------------------------------------------*/
  27. #define SP_PROCESS_SIZE             0x200  /* Process stack size */
  28. #define SP_PROCESS                  0x02   /* Process stack */
  29. #define SP_MAIN                     0x00   /* Main stack */
  30. #define THREAD_MODE_PRIVILEGED      0x00   /* Thread mode has privileged access */
  31. #define THREAD_MODE_UNPRIVILEGED    0x01   /* Thread mode has unprivileged access */
  32. /* Private macro -------------------------------------------------------------*/
  33. /* Private variables ---------------------------------------------------------*/
  34. vu8 PSPMemAlloc[SP_PROCESS_SIZE];
  35. vu32 Index = 0, PSPValue = 0, CurrentStack = 0, ThreadMode = 0;
  36. /* Private functions ---------------------------------------------------------*/

  37. void fmain(void)
  38. {
  39.   RCC_HSEConf(9);//72M

  40. /* Switch Thread mode Stack from Main to Process -----------------------------*/
  41.   /* Initialize memory reserved for Process Stack */
  42.   for(Index = 0; Index < SP_PROCESS_SIZE; Index++)
  43.   {
  44.     PSPMemAlloc[Index] = 0x00;
  45.   }

  46.   /* Set Process stack value */
  47.   __set_PSP((u32)PSPMemAlloc + SP_PROCESS_SIZE);
  48.   
  49.   /* Select Process Stack as Thread mode Stack */
  50.   __set_CONTROL(SP_PROCESS);

  51.   /* Get the Thread mode stack used */
  52.   if((__get_CONTROL() & 0x02) == SP_MAIN)
  53.   {
  54.     /* Main stack is used as the current stack */
  55.         CurrentStack = SP_MAIN;
  56.   }
  57.   else
  58.   {
  59.     /* Process stack is used as the current stack */
  60.         CurrentStack = SP_PROCESS;
  61.        
  62.         /* Get process stack pointer value */
  63.         PSPValue = __get_PSP();       
  64.   }
  65.   
  66. /* Switch Thread mode from privileged to unprivileged ------------------------*/
  67.   /* Thread mode has unprivileged access */
  68.   __set_CONTROL(THREAD_MODE_UNPRIVILEGED | SP_PROCESS);
  69.   /* Unprivileged access mainly affect ability to:
  70.       - Use or not use certain instructions such as MSR fields
  71.           - Access System Control Space (SCS) registers such as NVIC and SysTick */

  72.   /* Check Thread mode privilege status */
  73.   if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  74.   {
  75.     /* Thread mode has privileged access  */
  76.         ThreadMode = THREAD_MODE_PRIVILEGED;
  77.   }
  78.   else
  79.   {
  80.     /* Thread mode has unprivileged access*/
  81.         ThreadMode = THREAD_MODE_UNPRIVILEGED;
  82.   }

  83. /* Switch back Thread mode from unprivileged to privileged -------------------*/  
  84.   /* Try to switch back Thread mode to privileged (Not possible, this can be
  85.      done only in Handler mode) */
  86.   __set_CONTROL(THREAD_MODE_PRIVILEGED | SP_PROCESS);

  87.   /* Generate a system call exception, and in the ISR switch back Thread mode
  88.     to privileged */
  89.   //__SVC();

  90.   /* Check Thread mode privilege status */
  91.   if((__get_CONTROL() & 0x01) == THREAD_MODE_PRIVILEGED)
  92.   {
  93.     /* Thread mode has privileged access  */
  94.         ThreadMode = THREAD_MODE_PRIVILEGED;
  95.   }
  96.   else
  97.   {
  98.     /* Thread mode has unprivileged access*/
  99.         ThreadMode = THREAD_MODE_UNPRIVILEGED;
  100.   }
  101. }

  102. #endif
  103. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:05:09
  1. /**
  2.   ******************************************************************************
  3.   * @file /CRC_Example.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    CRC:以多项式(0x4C11DB7)进行CRC计算得到一个32位的值
  8.   use CRC  calculation unit to get a CRC code of a given buffer of data word,
  9.   based on a fixed generator polynomial(0x4C11DB7).
  10.   使用循环冗余校验(CRC) 以CRC-32(以太网)多项式(0x4C11DB7)为基础 得到一个32位的CRC计算结果
  11.   CRC技术主要应用于核实数据传输或者数据存储的正确性和完整性。
  12.   ******************************************************************************
  13.   *用途:校验一组数据
  14.   CRC->DR:写操作时,作为输入寄存器,可以输入要进行CRC计算的新数据。
  15.           读操作时,返回上一次CRC计算的结果。
  16.   每一次写入数据寄存器,其计算结果是前一次CRC计算结果和新计算结果的组合(对整个32位字进行CRC计算,而不是逐字节地计算)。
  17.   */
  18.   /*实例应用步骤:
  19.   //1."main.cpp"调用fmain()
  20.   
  21.   //2.Watch中观察
  22.   LED
  23.   */

  24. #ifndef __CRC_EXAMPLE_H
  25. #define __CRC_EXAMPLE_H
  26. /* Includes ------------------------------------------------------------------*/
  27. #include "std32periph.h"

  28. /* Private typedef -----------------------------------------------------------*/
  29. /* Private define ------------------------------------------------------------*/
  30. #define BUFFER_SIZE    114
  31. /* Private macro -------------------------------------------------------------*/
  32. /* Private variables ---------------------------------------------------------*/
  33. static uc32 DataBuffer[BUFFER_SIZE] =//const uint32_t
  34. {
  35.   0x00001021, 0x20423063, 0x408450a5, 0x60c670e7, 0x9129a14a, 0xb16bc18c,
  36.   0xd1ade1ce, 0xf1ef1231, 0x32732252, 0x52b54294, 0x72f762d6, 0x93398318,
  37.   0xa35ad3bd, 0xc39cf3ff, 0xe3de2462, 0x34430420, 0x64e674c7, 0x44a45485,
  38.   0xa56ab54b, 0x85289509, 0xf5cfc5ac, 0xd58d3653, 0x26721611, 0x063076d7,
  39.   0x569546b4, 0xb75ba77a, 0x97198738, 0xf7dfe7fe, 0xc7bc48c4, 0x58e56886,
  40.   0x78a70840, 0x18612802, 0xc9ccd9ed, 0xe98ef9af, 0x89489969, 0xa90ab92b,
  41.   0x4ad47ab7, 0x6a961a71, 0x0a503a33, 0x2a12dbfd, 0xfbbfeb9e, 0x9b798b58,
  42.   0xbb3bab1a, 0x6ca67c87, 0x5cc52c22, 0x3c030c60, 0x1c41edae, 0xfd8fcdec,
  43.   0xad2abd0b, 0x8d689d49, 0x7e976eb6, 0x5ed54ef4, 0x2e321e51, 0x0e70ff9f,
  44.   0xefbedfdd, 0xcffcbf1b, 0x9f598f78, 0x918881a9, 0xb1caa1eb, 0xd10cc12d,
  45.   0xe16f1080, 0x00a130c2, 0x20e35004, 0x40257046, 0x83b99398, 0xa3fbb3da,
  46.   0xc33dd31c, 0xe37ff35e, 0x129022f3, 0x32d24235, 0x52146277, 0x7256b5ea,
  47.   0x95a88589, 0xf56ee54f, 0xd52cc50d, 0x34e224c3, 0x04817466, 0x64475424,
  48.   0x4405a7db, 0xb7fa8799, 0xe75ff77e, 0xc71dd73c, 0x26d336f2, 0x069116b0,
  49.   0x76764615, 0x5634d94c, 0xc96df90e, 0xe92f99c8, 0xb98aa9ab, 0x58444865,
  50.   0x78066827, 0x18c008e1, 0x28a3cb7d, 0xdb5ceb3f, 0xfb1e8bf9, 0x9bd8abbb,
  51.   0x4a755a54, 0x6a377a16, 0x0af11ad0, 0x2ab33a92, 0xed0fdd6c, 0xcd4dbdaa,
  52.   0xad8b9de8, 0x8dc97c26, 0x5c644c45, 0x3ca22c83, 0x1ce00cc1, 0xef1fff3e,
  53.   0xdf7caf9b, 0xbfba8fd9, 0x9ff86e17, 0x7e364e55, 0x2e933eb2, 0x0ed11ef0
  54. };

  55. vu32 CRCValue = 0;
  56. /* Private functions ---------------------------------------------------------*/

  57. void fmain(void)
  58. {
  59.   RCC_HSEConf(9);//72M

  60.   /* Enable CRC clock */
  61.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);

  62.   /* Compute the CRC of "DataBuffer" */
  63.   //CRCValue = CRC_CalcBlockCRC((u32 *)DataBuffer, BUFFER_SIZE);//此行代码的实现如下
  64.   CRC->CR = 0x1;//复位CRC->DR:如不进行复位,可能残留DR值,导致计算过程不是预期的
  65.   for(u8 index = 0; index < BUFFER_SIZE; index++)
  66.   {
  67.     CRC->DR = DataBuffer[index];
  68.   }
  69.   CRCValue = CRC->DR;
  70. }

  71. #endif
  72. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:05:25
  1. /**
  2.   ******************************************************************************
  3.   * @file /DAC_2ChTriangleWave.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    DAC:使用不同三角波发生器的同时触发
  8.   ******************************************************************************
  9.   *
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //4.Watch中观察
  15.   DAC_DOR1
  16.   DAC_DOR2
  17.   */

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

  22. /* Private typedef -----------------------------------------------------------*/
  23. /* Private define ------------------------------------------------------------*/
  24. /* Private macro -------------------------------------------------------------*/
  25. /* Private variables ---------------------------------------------------------*/
  26. /* Private functions ---------------------------------------------------------*/

  27. void fmain(void)
  28. {
  29.   RCC_HSEConf(7);//56M

  30.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  31.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM2, ENABLE);
  32.   //复位DAC
  33.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
  34.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);


  35.   GPIO_InitTypeDef GPIO_InitStructure;
  36.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;
  37.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  38.   GPIO_Init(GPIOA, &GPIO_InitStructure);


  39.   /* TIM2 Configuration */
  40.   TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
  41.   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  42.   TIM_TimeBaseStructure.TIM_Period = 0xF;         
  43.   TIM_TimeBaseStructure.TIM_Prescaler = 0xF;      
  44.   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   
  45.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  46.   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  47.   /* TIM2 TRGO selection */
  48.   TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

  49.   /* DAC channel1 Configuration */
  50.   DAC_InitTypeDef            DAC_InitStructure;
  51.   DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;
  52.   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;
  53.   DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047;
  54.   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
  55.   DAC_Init(DAC_Channel_1, &DAC_InitStructure);
  56.   /* DAC channel2 Configuration */
  57.   DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023;
  58.   DAC_Init(DAC_Channel_2, &DAC_InitStructure);

  59.   DAC_Cmd(DAC_Channel_1, ENABLE);
  60.   DAC_Cmd(DAC_Channel_2, ENABLE);

  61.   DAC_SetDualChannelData(DAC_Align_12b_R, 0x100, 0x100);/* Set DAC dual channel DHR12RD register */

  62.   TIM_Cmd(TIM2, ENABLE);
  63. }

  64. #endif
  65. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:05:40
  1. /**
  2.   ******************************************************************************
  3.   * @file /DAC_DMAEscalator.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    DAC:DMA输出梯形波
  8.   ******************************************************************************
  9.   *
  10.   */
  11.   /*实例应用步骤:
  12.   //1."main.cpp"调用fmain()
  13.   
  14.   //4.Watch中观察
  15.   DAC_DHR12RD
  16.   */

  17. #ifndef __DAC_DMAESCALATOR_H
  18. #define __DAC_DMAESCALATOR_H
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "std32periph.h"

  21. /* Private typedef -----------------------------------------------------------*/
  22. /* Private define ------------------------------------------------------------*/
  23. /* Private macro -------------------------------------------------------------*/
  24. /* Private variables ---------------------------------------------------------*/
  25. uc8 Escalator8bit[6] = {0x0, 0x33, 0x66, 0x99, 0xCC, 0xFF};
  26. /* Private functions ---------------------------------------------------------*/

  27. void fmain(void)
  28. {
  29.   RCC_HSEConf(7);//56M

  30.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  31.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  32.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM6, ENABLE);
  33.   //复位DAC
  34.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
  35.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);


  36.   GPIO_InitTypeDef GPIO_InitStructure;
  37.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
  38.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  39.   GPIO_Init(GPIOA, &GPIO_InitStructure);


  40.   /* TIM6 Configuration */
  41.   TIM_PrescalerConfig(TIM6, 0xF, TIM_PSCReloadMode_Update);
  42.   TIM_SetAutoreload(TIM6, 0xFF);
  43.   /* TIM6 TRGO selection */
  44.   TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);


  45.   // DAC channel1 Configuration:MAMP1[]=0111、WAVE1[]=10、TSEL1[]=000、TEN1=1、BOFF1=1
  46.   DAC->CR &= 0xFFFFF000;
  47.   DAC->CR |= 0x00000786;

  48.   /* DMA2 channel3 configuration */
  49.   DMA_InitTypeDef            DMA_InitStructure;
  50.   DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40007410;//DAC_DHR8R1_Address;
  51.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&Escalator8bit;
  52.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  53.   DMA_InitStructure.DMA_BufferSize = 6;
  54.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  55.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  56.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  57.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  58.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  59.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  60.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  61.   DMA_Init(DMA2_Channel3, &DMA_InitStructure);
  62.   DMA_Cmd(DMA2_Channel3, ENABLE);

  63.   DAC_Cmd(DAC_Channel_1, ENABLE);

  64.   DAC_DMACmd(DAC_Channel_1, ENABLE);

  65.   TIM_Cmd(TIM6, ENABLE);
  66. }

  67. #endif
  68. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:05:55
  1. /**
  2.   ******************************************************************************
  3.   * @file /DAC_DualModeDMASineWave.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    DAC:双DAC通道转换
  8.   DAC集成了3个供双DAC模式使用的寄存器:DHR8RD、DHR12RD和DHR12LD,
  9.   只需要访问一个寄存器即可完成同时驱动2个DAC通道的操作。
  10.   ******************************************************************************
  11.   *用途:双路波形输出,可做简易示波器
  12.   */
  13.   /*实例应用步骤:
  14.   //1."main.cpp"调用fmain()
  15.   
  16.   //4.Watch中观察
  17.   DAC_DHR12RD
  18.   */

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

  23. /* Private typedef -----------------------------------------------------------*/
  24. /* Private define ------------------------------------------------------------*/
  25. /* Private macro -------------------------------------------------------------*/
  26. /* Private variables ---------------------------------------------------------*/
  27. uc16 Sine12bit[32] =
  28. {
  29.   0x0026, 0x009B, 0x0158, 0x0257, 0x038D, 0x04EF, 0x066F, 0x07FF, 0x098F, 0x0B0F, 0x0C71, 0x0DAA, 0x0EA6, 0x0F63, 0x0FD8, 0x0FFF,
  30.   0x0FD8, 0x0F63, 0x0EA6, 0x0DAA, 0x0C71, 0x0B0F, 0x098F, 0x07FF, 0x066F, 0x04EF, 0x038D, 0x0257, 0x0158, 0x009B, 0x0026, 0x0000
  31. };

  32. u32 DualSine12bit[32];
  33. /* Private functions ---------------------------------------------------------*/

  34. void fmain(void)
  35. {
  36.   RCC_HSEConf(7);//56M

  37.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  38.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM8, ENABLE);
  39.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
  40.   //复位DAC
  41.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
  42.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);


  43.   GPIO_InitTypeDef GPIO_InitStructure;
  44.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;
  45.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  46.   GPIO_Init(GPIOA, &GPIO_InitStructure);


  47.   /* TIM8 Configuration */
  48.   TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
  49.   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  50.   TIM_TimeBaseStructure.TIM_Period = 0x19;         
  51.   TIM_TimeBaseStructure.TIM_Prescaler = 0x0;      
  52.   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   
  53.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  54.   TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
  55.   /* TIM8 TRGO selection */
  56.   TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);

  57.   // DAC channel1,2 Configuration:WAVE1/2[]=00、TSEL1/2[]=001、TEN1/2=1、BOFF1/2=1
  58.   DAC->CR &= 0xFF00FF00;
  59.   DAC->CR |= 0x000E000E;

  60.   /* Fill Sine32bit table */
  61.   for (u8 Idx= 0; Idx<32; Idx++)
  62.   {
  63.     DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);
  64.   }

  65.   /* DMA2 channel4 configuration */
  66.   DMA_InitTypeDef            DMA_InitStructure;
  67.   DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40007420;//DAC_DHR12RD_Address;
  68.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DualSine12bit;
  69.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  70.   DMA_InitStructure.DMA_BufferSize = 32;
  71.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  72.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  73.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  74.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  75.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  76.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  77.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  78.   DMA_Init(DMA2_Channel4, &DMA_InitStructure);
  79.   DMA_Cmd(DMA2_Channel4, ENABLE);

  80.   DAC_Cmd(DAC_Channel_1, ENABLE);
  81.   DAC_Cmd(DAC_Channel_2, ENABLE);

  82.   /* Enable DMA for DAC Channel2 */
  83.   DAC_DMACmd(DAC_Channel_2, ENABLE);//最终DAC->CR = 0x100F000F;

  84.   TIM_Cmd(TIM8, ENABLE);
  85. }

  86. #endif
  87. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
Dylan疾风闪电 回答时间:2016-1-7 15:06:13
  1. /**
  2.   ******************************************************************************
  3.   * @file /DAC_NoiseWave.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-14
  7.   * @brief    DAC:噪声生成
  8.   可以利用线性反馈移位寄存器(Linear Feedback Shift Register LFSR)产生幅度变化的伪噪声。
  9.   设置WAVE[1:0]位为’01’选择DAC噪声生成功能。
  10.   寄存器LFSR的预装入值为0xAAA。
  11.   按照特定算法,在每次触发事件后3个APB1时钟周期之后更新该寄存器的值。
  12.   ******************************************************************************
  13.   *用途:伪噪声生成器
  14.   */
  15.   /*实例应用步骤:
  16.   //1."main.cpp"调用fmain()
  17.   
  18.   //4.Watch中观察
  19.   DAC_DHR12LD
  20.   */

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

  25. /* Private typedef -----------------------------------------------------------*/
  26. /* Private define ------------------------------------------------------------*/
  27. /* Private macro -------------------------------------------------------------*/
  28. /* Private variables ---------------------------------------------------------*/
  29. /* Private functions ---------------------------------------------------------*/

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

  33.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  34.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
  35.   //复位DAC
  36.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
  37.   RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);


  38.   GPIO_InitTypeDef GPIO_InitStructure;
  39.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
  40.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  41.   GPIO_Init(GPIOA, &GPIO_InitStructure);


  42.   // DAC channel1 Configuration:MAMP1[]=1000、WAVE1[]=01、TSEL1[]=111、TEN1=1、BOFF1=0、EN1=0
  43.   DAC->CR &= 0xFFFFF000;
  44.   DAC->CR |= 0x0000087C;  //设置WAVE[1:0]位为’01’选择DAC噪声生成功能。
  45.   DAC_Cmd(DAC_Channel_1, ENABLE);

  46.   DAC_SetChannel1Data(DAC_Align_12b_L, 0x7FF0);/* Set DAC Channel1 DHR12L register */
  47.   
  48.   while(1)
  49.   {
  50.     DAC_SoftwareTriggerCmd(DAC_Channel_1, ENABLE);/* Start DAC Channel1 conversion by software */
  51.   }
  52. }

  53. #endif
  54. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码
12345下一页

所属标签

相似分享

官网相关资源

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