打印

请教 测量占空比:STM32FPWM输入模式+DMA的问题

[复制链接]
4118|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
32446975|  楼主 | 2011-1-18 12:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
说明:MCU:STM32F100系列.使用TIMER3的CH1输入,PWM输入模式.使用CC1触发一次DMA传送,一次DMA传送中传送TIMx_CCR1,TIMx_CCR2中的值到指定的内存中.DMA为单次模式,指定完成一定数量的数据传送.

问题:
1.STM32F101或103系列TIMx_CCR1,TIMx_CCR2是16位寄存器;STM32F100系列TIMx_CCR1,TIMx_CCR2是32位寄存器,其中低16位是TIMx_CCR1,TIMx_CCR2用,高16位另有用途(CCR1[31:16] (depending on timers)).使用DMA传送TIMx_CCR1,TIMx_CCR2中值时,是否会把高16位也传送了?
2.用STM32F100的PWM输入模式+DMA测量MXD2020输出的PWM信号的占空比,这个方法是否可行?
3.例程在使用是中断方式时,是通过程序判断舍去了TIMx_CCR1,TIMx_CCR2复位时值都为0的数据.我使用的是CC1触发一次DMA传送,会不会把都为0的一次值,也传送了?
4.在函数void Timer_Configuration(void)中的TIM_DMAConfig(TIM3, TIM_DMABase_CCR1, TIM_DMABurstLength_8Bytes);中的参数TIM_DMABurstLength_8Bytes,(DMA在连续模式下的传送长度,即:定义传输的字节数目:),我这个长度是否正确?因为问题1.我试了参数TIM_DMABurstLength_16Bytes,但最终仿真查看SendBuff数组中结果不是想要的结果.

现在是:调整各设置参数,SendBuff数组中要么是CC1,要么是CC2,或者有好多0.

/**
  ******************************************************************************
  * 修改:硬件基于stm32vldiscovery超值体验板, CPU=STM32F100RB
  * 上电缺省值,主要为:使用外部HSE,HSE时钟PLL后24M作为系统时钟,AHB为24M,
  * APB2,APB1为24M.AHB外设:FLITFEN“Flah时钟”,SRAMEN“SRAM时钟”.
  * 创建时间:20110111
  * 最后修改:20110111
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup Examples
  * @{
  */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* 在Option中宏定义下面2个 */
/* 在stm32f10x.h中包含 #include "stm32f10x_conf.h" */
//#define USE_STDPERIPH_DRIVER
/* 在stm32f10x.h中 */
//#define STM32F10X_MD_VL
#define USART1_DR_Base  (USART1_BASE + 0x04)
#define Timer3_CC1_DR_Base  (TIM3_BASE + 0x34)
#define Timer3_CC2_DR_Base  (TIM3_BASE + 0x38)
#define USART1_TX_PIN  GPIO_Pin_9
#define USART1_RX_PIN  GPIO_Pin_10
#define USART1_GPIO_PORT  GPIOA
#define USART1_BaudRate  (19200)
/* Private macro -------------------------------------------------------------*/
#define SENDBUFF_SIZE   20
vu16 SendBuff[SENDBUFF_SIZE];
vu8 RecvBuff[10];
vu8 recv_ptr;
/* Private variables ---------------------------------------------------------*/
//static __IO uint32_t TimingDelay;
TIM_ICInitTypeDef  TIM_ICInitStructure;
/* Private function prototypes -----------------------------------------------*/
//void Delay(__IO uint32_t nTime);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void Timer_Configuration(void);
void USART1_DMA_Configuration(void);
void Timer3_PWM_Input_DMA_Configuration(void);
void DMA_Configuration(void);
void USART1_Configuration(void);
void Delay(void);
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     
  
  //__disable_interrupt;       /*!< global Interrupt disable */
  //__disable_irq;
  __disable_fault_irq();
  
  /* System Clocks Configuration */
  RCC_Configuration();
  /* NVIC configuration */
  NVIC_Configuration();
  Timer_Configuration();
  
  /* Configure the GPIO ports */
  GPIO_Configuration();
   DMA_Configuration();
    USART1_Configuration();
  
  
  
  /* Initialize Leds LD3 and LD4 mounted on STM32VLDISCOVERY board */  
  STM32vldiscovery_LEDInit(LED3);
  STM32vldiscovery_LEDInit(LED4);
  /* Turn on LD3 and LD4 */
  STM32vldiscovery_LEDOn(LED3);
  STM32vldiscovery_LEDOn(LED4);
  //__enable_interrupt;        /*!< global Interrupt enable */
  //__enable_irq;
  __enable_fault_irq();
  
  while (1)
  {
    /* 非循环DMA模式,每次使用前进行配置 */
    /* Timer3-PWM_Input_DMA读取配置 */
    Timer3_PWM_Input_DMA_Configuration();  
   
     /* Enable the DMA_CC1 Request */
     TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE);
     /* Enable the DMA_CC2 Request */
     //TIM_DMACmd(TIM3, TIM_DMA_CC2, ENABLE);
    //开始一次DMA传输!
    DMA_Cmd(DMA1_Channel6, ENABLE);
   
    //等待DMA传输完成,此时我们来做另外一些事,点灯
    //实际应用中,传输数据期间,可以执行另外的任务
    while(DMA_GetFlagStatus(DMA1_FLAG_TC6) == RESET)
    {
        //LED_1_REV;      //LED翻转
        STM32vldiscovery_LEDToggle(LED3);
        Delay();        //浪费时间
    }
   
  }
}


void Timer_Configuration(void)
{
TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
TIM_ICInitTypeDef      TIM_ICInitStructure;

/* TIM3 Peripheral Configuration --------------------------------------------*/
  /* Time Base configuration */  
  
  TIM_DeInit(TIM3);
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;  //ARR的值
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //采样分频
  
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  
  //定时器使用内部时钟即CK_INT,AHB为24M,APB1为24M,CK_INT为24M.
  //时钟分频系数24,所以定时器时钟为1M
  TIM_PrescalerConfig(TIM3,24,TIM_PSCReloadMode_Immediate);
  TIM_ARRPreloadConfig(TIM3, ENABLE);//使能ARR预装载缓冲器
   
  /* TIM3 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH1 pin (PA.6),
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value
     The TIM3 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */
  /* TIM_CCER_CC1E CC1E:输入/捕获1输出使能
     该位决定了计数器的值是否能捕获入TIMx_CCR1寄存器。 */
  /* CC1E,CC2E使能 */
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
  /* TIMx->CCER CC1P位 0:不反相:捕获发生在IC1的上升沿;
     TIMx->CCER CC2P位 1:  反相:捕获发生在IC1的下降沿;*/
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  /* TIMx->CCMR1 CC1S[1:0]:位 01 CC1通道被配置为输入,IC1映射在TI1上;
     TIMx->CCMR1 CC2S[1:0]:位 01 CC2通道被配置为输入,IC2映射在TI1上;  */
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  /* TIM_ICPSC_DIV1==0 无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获; */
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  /* TI1输入的采样频率及数字滤波器长度。数字滤波器由一个事件计数器组成,它记
  录到N个事件后会产生一个输出的跳变: (0010)2:N=4 */
  TIM_ICInitStructure.TIM_ICFilter = 2;
  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
  /* Select the TIM3 Input Trigger: TI1FP1 */
  /* TS[2:0]:触发选择 101:滤波后的定时器输入1(TI1FP1)  */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
  /* Select the slave Mode: Reset Mode */
  /* 100:复位模式 – 选中的触发输入(TRGI)的上升沿重新初始化计数器,
     并且产生一个更新寄存器的信号。 */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
  /* Enable the Master/Slave Mode */
  /* TIMx_SMCR MSM位:主/从模式  1:触发输入(TRGI)上的事件被延迟了,
    以允许在当前定时器(通过TRGO)与它的从定时器间的完美同步。这对
    要求把几个定时器同步到一个单一的外部事件时是非常有用的。 */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);
  
  /* DBL[4:0]: DMA连续传送长度 (DMA burst length)
     这些位定义了DMA在连续模式下的传送长度,即:定义传输的字节数目:  
     TIMx->DCR Configures the TIMx DMA interface. */
  TIM_DMAConfig(TIM3, TIM_DMABase_CCR1, TIM_DMABurstLength_8Bytes);
  
  
  /* DMA/中断使能寄存器(TIMx_DIER)  */
  //TIM_ITConfig(TIM3, TIM_IT_Trigger, ENABLE);//使能触发中断
  /* Enable the CC2 Interrupt Request */
  //TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
  //TDE:允许触发DMA请求 (Trigger DMA request enable)
  TIM_DMACmd(TIM3, TIM_DMA_Trigger, ENABLE);
  
  
  /* TIMx_CR2 CCDS:捕获/比较的DMA选择 1:当发生更新事件时,送出CCx的DMA请求。  */
  /* 不用此句好像没影响 */
  //TIM_SelectCCDMA(TIM3, ENABLE);
  
  /* 事件产生寄存器(TIMx_EGR) UG:产生更新事件 (Update generation)
     1:重新初始化计数器,并产生一个更新事件。*/
  /* 有没有此句,好像没有影响 */
  //TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
  
  /* 使用tim2实现1s定时 */
  /* 初始化代码 */
#if 1  /* 注释掉某一部分,预编译处理 */
   TIM2->PSC |=24000; //设置预分频,实现1ms
#else
   TIM2->PSC |=8000; //设置预分频,实现1ms
#endif   
   TIM2->ARR = 1000;  //1s产生一次中断
   TIM2->DIER |=0X1;  //允许tim2更新中断
   //NVIC->ISER[0] |= (u32)(1<<TIM2_IRQChannel); //开tim2中断
   /* NVIC->ISER[0] @file     core_cm3.h
      TIM2_IRQn @file    stm32f10x.h */
   //NVIC->ISER[0] |= (u32)(1<<TIM2_IRQn); //开tim2中断
   TIM2->CR1 |=0X1;//启动tim2

}




/*******************************************************************************
* Function Name  : Timer3-PWM_Input_DMA_Configuration
* Description    : Timer3-PWM_Input_DMA读取配置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Timer3_PWM_Input_DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
   
    //Timer3-PWM_Input的CC1,CC2的DMA读取设置:
    //设置DMA源:内存地址&CC1,CC2数据寄存器地址
    //方向:外设-->内存
    //每次传输位:8bit
    //传输大小DMA_BufferSize=SENDBUFF_SIZE
    //地址自增模式:外设地址不增,内存地址自增1
    //DMA模式:一次传输,非循环
    //优先级:中
    DMA_DeInit(DMA1_Channel6);
    DMA_InitStructure.DMA_PeripheralBaseAddr = Timer3_CC1_DR_Base;
    //DMA_InitStructure.DMA_PeripheralBaseAddr = Timer3_CC2_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* 0:从外设读  */
    DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    /* 实验验证不能使用外设自增,否则会读到TIMx_DCR中的值 */
    //DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    //DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel6, &DMA_InitStructure);   
}
void DMA_Configuration(void)
{
  /* USART1_DMA发送配置 */
  USART1_DMA_Configuration();
  /* Timer3-PWM_Input_DMA读取配置 */
    Timer3_PWM_Input_DMA_Configuration();  
}
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:STM32,STM8,51,PIC,AVR。QQ:281342118

5

主题

69

帖子

2

粉丝