等精度测量法:定时器1对被测信号计数65536个周期作为闸门时间,在这个闸门时间内定时器2对标准信号进行计数。假定在这个闸门时间内标准信号的计数值为M。则有:65536/fc=M/fb通过这个公式就可以算出被测信号:fc=65536*fb/M。 本程序利用定时器3产生30KHZ的被测信号。定时器1对被测信号进行65536个周期计数。 定时器4产生60KHZ的标准信号。定时器2对标准信号在定时器1产生的闸门时间内计数。 主程序如下: /** ****************************************************************************** * @file app.c * @author wangfei * @date 13-April-2012 * @e-mail wfmjj@hotmail.com * @brief Initialize peripherals. *****************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx.h" #include "app.h" #include "bsp.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ extern uint8_t TimeFlag; extern uint32_t n_Counter; uint16_t Counterh,Counterl; uint8_t Data[5]; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*//** * @brief This function handles NMI exception. * @param None * @retval None */ int main(void) { GPIO_ResetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3)); //可以通过观察LED口高电平时间 Bsp_Init(); while(1) { uint8_t i; TIM_ITConfig(TIM1,TIM_IT_Trigger,ENABLE); //允许定时器1的触发中断 GPIO_SetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3)); TIM_Cmd(TIM1,ENABLE); //打开定时器1,当检测到TIM1_CH1通道的上升沿后立即触发中断 while(TimeFlag==0); //等待定时器1溢出中断 TIM1->DIER&=0X0000; //失能定时器1的所有中断 GPIO_ResetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3)); //可以通过观察LED口高电平时间 TimeFlag=0; //定时器1溢出标志置0 Counterh=n_Counter>>16; //得到32位数据中的高16位 Counterl=n_Counter; //得到32位数据中的低16位 Data[0]=Counterh>>8; Data[1]=Counterh; Data[2]=Counterl>>8; Data[3]=Counterl; for(i=0;iCCMR1|=0X0100; //配置定时器1为外部时钟模式1 TIM1->CCER&=0XFF5F; TIM1->SMCR|=0X0067; TIM_ClearFlag(TIM1,(TIM_FLAG_Update|TIM_FLAG_Trigger)); } /** * @brief This function config timer3. * @param None * @retval None */ void Bsp_TIM3_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Open TIM3 Clock TIM_TimeBaseStructure.TIM_Prescaler=3; //clk_cnt prescale TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM3 Count mode TIM_TimeBaseStructure.TIM_Period=699; //Fout_clk=Fclk_cnt/(ARR+1)=21000000/700=30KHZ TIM_TimeBaseStructure.TIM_ClockDivision=0; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: TIM3_Ch1 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc1 as output TIM_OCInitStructure.TIM_Pulse=350; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc1 high level avaliable TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc1 preload /* PWM1 Mode configuration: TIM3_Ch2 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc2 as output TIM_OCInitStructure.TIM_Pulse=200; //config TIM3_CCR2 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc2 high level avaliable TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc2 preload /* PWM1 Mode configuration: TIM3_CH3 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc3 as output TIM_OCInitStructure.TIM_Pulse=100; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc3 high level avaliable TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc3 preload /* PWM1 Mode configuration: TIM3_CH4 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc4 as output TIM_OCInitStructure.TIM_Pulse=500; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc4 high level avaliable TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc4 preload TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); } /** * @brief This function config usart3. * @param None * @retval None */ void Bsp_USART3_Config(void) { USART_InitTypeDef USART_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //turn on usart3 clock USART_InitStructure.USART_BaudRate =115200 ; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART3, &USART_InitStructure); //USART_ITConfig(USART3,USART_IT_RXNE,ENABLE); USART_Cmd(USART3,ENABLE); USART_ClearFlag(USART3, USART_FLAG_TC); //清除发送完成标志位 } /** * @brief This function config nvic. * @param None * @retval None */ void Bsp_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel=TIM1_TRG_COM_TIM11_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief This function config timer2. * @param None * @retval None */ void Bsp_TIM2_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开定时器2的时钟 TIM_DeInit(TIM2); TIM_TimeBaseStructure.TIM_Prescaler=0; TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //定时器2向上计数 TIM_TimeBaseStructure.TIM_Period=0xffff; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM2->ARR|=0XFFFFFFFF; //配置 //定时器2外部时钟模式1的配置 TIM2->CCMR1|=0X0001; TIM2->CCER&=0XFFF5; TIM2->SMCR|=0X0057; TIM_ClearFlag(TIM2,TIM_FLAG_Update); //初始化时必须将溢出中断清0必须在开溢出中断之前。 } /** * @brief This function config timer4. * @param None * @retval None */ void Bsp_TIM4_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //turn on TIM4 clock TIM_TimeBaseStructure.TIM_Prescaler=1; //Fck_cnt=84MHZ/2=42MHZ TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM3 Count mode TIM_TimeBaseStructure.TIM_Period=699; //Fout_clk=Fclk_cnt/(ARR+1)=42000/700=60KHZ TIM_TimeBaseStructure.TIM_ClockDivision=0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: TIM4_Ch1 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc1 as output TIM_OCInitStructure.TIM_Pulse=350; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc1 high level avaliable TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc1 preload /* PWM1 Mode configuration: TIM4_Ch2 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc2 as output TIM_OCInitStructure.TIM_Pulse=500; //config TIM3_CCR2 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc2 high level avaliable TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc2 preload /* PWM1 Mode configuration: TIM4_CH3 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc3 as output TIM_OCInitStructure.TIM_Pulse=100; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc3 high level avaliable TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc3 preload /* PWM1 Mode configuration: TIM4_CH4 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc4 as output TIM_OCInitStructure.TIM_Pulse=600; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc4 high level avaliable TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc4 preload TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM4, ENABLE); }</em> 定时器1触发中断程序如下: void TIM1_TRG_COM_TIM11_IRQHandler(void) { if(TIM_GetITStatus(TIM1,TIM_IT_Trigger)==SET) //检查是否为触发中断 { TIM1->DIER&=0XFFBF; //清除定时器1的触发中断 TIM1->DIER|=0X0001; //使能定时器1的溢出中断 TIM2->CR1|=0X0001; //打开定时器2使其对标准信号开始计数 TIM1->SR&=0XFFBF; //在退出中断之前必须清除其中断标志位 } } 定时器1溢出中断如下: void TIM1_UP_TIM10_IRQHandler(void) { if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //检查定时器1溢出标志位是否置1 { n_Counter=TIM2->CNT; //读出计数器2的值 TIM1->CR1&=0XFFFE; //关闭定时器1 TIM2->CR1&=0XFFFE; //关闭定时器2 TIM2->CNT&=0X0000; //清除计数器2计数寄存器的值 TimeFlag=1; //1s标志位置1 TIM1->SR&=0XFFFE; //退出定时器1溢出中断之前,必须清除定时器1的溢出标志位 } } |
分享下刚刚画好的DXP封装__STM32F407
Cortex-M3 + UCOS-II 嵌入式系统开发入门与应用手册
【ST MCU实战经验】之STM32F4使用外扩SDRAM运行程序的方法
STM32F401RE-Nucleo开发分享'^_^'(前奏)
STM32F401RE-Nucleo开发分享'^_^'(LED、BUTTON)
基于STM32 I2S的音频应用开发介绍
整了一块正点原子战舰 STM32F417 开发板
【ST MCU实战经验】之Keil中使用STM32F4xx硬件浮点单元
【智能音箱】介绍一种高性价比、丰富智能音箱场景应用...
嵌入式WEB服务器及远程测控应用详解(转贴)
回复: STM32F4定时器应用--等精度测频法