DMA/TIM capture

This is a more free standing example measuring the LSI (TIM5_CH4 internally)

and demonstrating DMA/TIM capture with granularity of APB1 * 2

// STM32F4-Discovery LSI Bench using DMA/TIM - sourcer32@gmail.com
 
// SWV code redacted
 
#include "stm32f4_discovery.h"
 
#include <stdio.h>
#include <string.h>
 
/**************************************************************************/
 
#define DELTA_SAMPLES 16
 
volatile uint32_t DeltaBuffer[DELTA_SAMPLES]; // TIM5 is 32-bit
 
void TimerCapture(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
 
  /* Enable the LSI source, as an available built in asych source */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
 
  /* Allow access to BKP Domain */
  PWR_BackupAccessCmd(ENABLE);
 
  /* Enable the LSI OSC */
  RCC_LSICmd(ENABLE);
 
  /* Wait till LSI is ready */
  while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
 
  /* TIM5 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
 
  /* DMA clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
 
  // TIM5_CH4 DMA1 Stream1 or 3, Channel 6, per RM0090
  DMA_DeInit(DMA1_Stream1);
 
  DMA_StructInit(&DMA_InitStructure);   /* not required - fully qualified below */
 
  DMA_InitStructure.DMA_Channel = DMA_Channel_6;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIM5->CCR4);
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DeltaBuffer[0];
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = DELTA_SAMPLES;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 32-bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA1_Stream1, &DMA_InitStructure);
 
  TIM_DeInit(TIM5); /* not required? */
 
  /* Connect internally the TIM5_CH4 Input Capture to the LSI clock output */
  TIM_RemapConfig(TIM5, TIM5_LSI);
 
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit maximal
  TIM_TimeBaseStructure.TIM_Prescaler = 0; // Highest Rate (DIV4 on APB1, DIV2 on TIMCLK5, 84 MHz?)
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
 
  /* Channel configuration */
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x00;
  TIM_ICInit(TIM5, &TIM_ICInitStructure);
 
  /* Enable the TIM Capture/Compare DMA requests */
//  TIM_SelectCCDMA(TIM5, ENABLE); /* not required - Output Compare, want CCDS=0 (DISABLED) for CC rather than Update? */
 
  TIM_DMACmd(TIM5, TIM_DMA_CC4, ENABLE);
 
  /* TIM enable counter */
  TIM_Cmd(TIM5, ENABLE);
 
  /* Main Output Enable, and Input - TIM1/8 */
  //TIM_CtrlPWMOutputs(TIMx, ENABLE);
}
 
/**************************************************************************/
 
int main(void)
{
  int i;
 
  memset((void *)DeltaBuffer, 0xCD, sizeof(DeltaBuffer)); // Flood buffer to prove it fills
 
  TimerCapture();
 
  /* Clear DMA1_Stream1 Terminal Count */
  DMA_ClearFlag(DMA1_Stream1, DMA_FLAG_TCIF1);
     
  /* Enable DMA1_Stream1 */
  DMA_Cmd(DMA1_Stream1, ENABLE);
 
  /* Wait on DMA1 Stream1 Terminal Count */
  while(DMA_GetFlagStatus(DMA1_Stream1, DMA_FLAG_TCIF1) == RESET);
 
  for(i=1; i<DELTA_SAMPLES; i++)
    printf("#%03d - Abs:%10d Delta:%10d
",i,DeltaBuffer[i],DeltaBuffer[i] - DeltaBuffer[i-1]);
 
  // Delta for 40 KHz measured at 84 MHz is 2100 cycle, or 1050 cycles for half period (both edges)
 
  // Measuring 1300/1315, 32.122 KHz not quite 50/50 duty
     
  while(1); // Do not exit
}
#001 - Abs:      2196 Delta:      1316
#002 - Abs:      3499 Delta:      1303
#003 - Abs:      4816 Delta:      1317
#004 - Abs:      6117 Delta:      1301
#005 - Abs:      7435 Delta:      1318
#006 - Abs:      8736 Delta:      1301
#007 - Abs:     10048 Delta:      1312
#008 - Abs:     11351 Delta:      1303
#009 - Abs:     12667 Delta:      1316
#010 - Abs:     13971 Delta:      1304
#011 - Abs:     15285 Delta:      1314
#012 - Abs:     16588 Delta:      1303
#013 - Abs:     17903 Delta:      1315
#014 - Abs:     19207 Delta:      1304
#015 - Abs:     20522 Delta:      1315
原文地址:https://www.cnblogs.com/shangdawei/p/4749360.html