|
等精度测量法:定时器1对被测信号计数65536个周期作为闸门时间,在这个闸门时间内定时器2对标准信号进行计数。假定在这个闸门时间内标准信号的计数值为M。则有:65536/fc=M/fb通过这个公式就可以算出被测信号:fc=65536*fb/M。# X7 J' _0 }' o6 n; T& f/ R/ x A 本程序利用定时器3产生30KHZ的被测信号。定时器1对被测信号进行65536个周期计数。 定时器4产生60KHZ的标准信号。定时器2对标准信号在定时器1产生的闸门时间内计数。 主程序如下:6 g0 A; p; [4 H# y /** ****************************************************************************** * @file app.c % z& c& n% K s F7 J * @author wangfei! z, d& P. v: ?1 B1 ] * @date 13-April-20125 e$ C: E0 e% x' r- w, [ * @e-mail wfmjj@hotmail.com * @brief Initialize peripherals.) Z- P% l% r$ j *****************************************************************************/5 w4 w K) X6 V, K. t' H$ O /* Includes ------------------------------------------------------------------*/$ F. Z$ P5 q: E( O# i #include "stm32f4xx.h"& B' v' b" [* y9 G( X/ D #include "app.h" #include "bsp.h"$ z. t/ |& c1 a /* Private typedef -----------------------------------------------------------*/4 ~! A$ r' U) I- L& F1 y. X /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ extern uint8_t TimeFlag; extern uint32_t n_Counter;" x4 }6 b K/ j% \ uint16_t Counterh,Counterl;6 k/ a/ H" T& ^' m uint8_t Data[5]; /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*//** * @brief This function handles NMI exception.& h+ [: E+ a3 S) U4 }! l5 P * @param None5 {. v8 ~3 p( w5 ] * @retval None$ B: I0 c4 I' e: N */ int main(void)8 ?* _( S7 U, V! I { GPIO_ResetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3)); //可以通过观察LED口高电平时间1 h* \6 |- ]8 Y, i/ _' w Bsp_Init();9 W, L! y7 H2 w _: s3 y while(1)# {+ m, K: v+ O( f* N: k/ K { uint8_t i;9 k w( ?. m. C: L, _ TIM_ITConfig(TIM1,TIM_IT_Trigger,ENABLE); //允许定时器1的触发中断 GPIO_SetBits(GPIOE,(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3));) H2 r) S9 |( W& N% A TIM_Cmd(TIM1,ENABLE); //打开定时器1,当检测到TIM1_CH1通道的上升沿后立即触发中断# O* {# @* `: O$ C. l. R while(TimeFlag==0); //等待定时器1溢出中断 TIM1->DIER&=0X0000; //失能定时器1的所有中断. d' k* D+ \+ C# Y* R: O1 f0 B, y 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;2 {7 `( L6 o: H1 @; S* W( k Data[1]=Counterh; Data[2]=Counterl>>8; Data[3]=Counterl; <span style="color: rgb(34, 34, 34); font-family: sans-serif; font-size: 18px; line-height: 27px; background-color: rgb(238, 238, 238); "> for(i=0;iCCMR1|=0X0100; //配置定时器1为外部时钟模式18 K6 v& v2 Q( v/ o( c9 Z TIM1->CCER&=0XFF5F;9 O3 u% h2 I$ u7 W6 M% A: D TIM1->SMCR|=0X0067; TIM_ClearFlag(TIM1,(TIM_FLAG_Update|TIM_FLAG_Trigger));9 ]! O7 a% o$ S+ z% q! I% \ }- A u* F1 @3 i! M, X /**2 N: G) Y# G( i% z * @brief This function config timer3. * @param None* x1 p4 A( A, J8 A% A2 g3 x * @retval None */ void Bsp_TIM3_Config(void) {: E! R5 P& A4 p9 x/ U5 [ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure;5 |3 O6 q! d% j+ l$ y RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //Open TIM3 Clock + z# F+ Y0 \& k' L2 N% l0 n 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; 8 E, q$ t% X( a' e# r! X# | TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);) y4 w v. f& F7 g8 F /* 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% |9 J* K, G/ F( q TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc1 high level avaliable4 d3 K4 L% W. K' M' d% J( t TIM_OC1Init(TIM3, &TIM_OCInitStructure); - g, ?3 L. d1 y$ z g3 h/ X/ W TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc1 preload 9 @# C1 Q3 w/ p/ E) A 9 U; l; q% r7 L /* 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); ! N% e1 U7 j( x; }) o1 j7 G TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc2 preload ) r) w& f W! Q0 R% q. F /* PWM1 Mode configuration: TIM3_CH3 */ TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode: ]9 W/ o. } |1 O" m( m; U TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc3 as output , t* O7 ~# x6 V% f; V& a TIM_OCInitStructure.TIM_Pulse=100; //config TIM3_CCR1 vaule TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc3 high level avaliable8 A* d H; }% A8 C TIM_OC3Init(TIM3, &TIM_OCInitStructure);' _5 A, L4 N6 d TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc3 preload /* PWM1 Mode configuration: TIM3_CH4 */" j2 Q9 r" M* B% L& K 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); / k C4 {2 ^: q% @ U: N8 L8 { TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); // turn on oc4 preload TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */. R9 T2 n1 _. y3 ^6 M* H TIM_Cmd(TIM3, ENABLE); } W2 C4 W7 e0 p- ] d3 S7 e ' G, E# a' n, V6 Y" `) Q! ^ |
【福利三:雨露均沾·逢7狂欢】之四:用一个定时器同步另外两个定时器输出PWM
【逢7发帖赢大礼】STM32开发之WIFI实时时钟
【逢7发帖赢大礼】STM32开发之指纹识别!
【逢7发帖赢大礼】STM32开发之环境空气质量监测
【逢7发帖赢大礼】STM32开发之人体实时运动信息监测!
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
【逢7发帖赢大礼】全网最简单的Arduino_STM32开发环境搭建教程!
STM32F4中文用户手册
STM32F400、STM32F402 Cortex-M4超值单片机
SPI 高温读错最后一位?STM32F42xx 官方根治方案
微信公众号
手机版
* @brief This function config usart3.9 D5 n) {& _; K! B1 R- c
* @param None
* @retval None4 x! q* ?$ g ?5 @4 n& Y
*/$ A( k/ G1 ?! e7 H) c
void Bsp_USART3_Config(void)4 a1 J8 G$ Q% s! C& {4 J4 Z& @
{" ^5 j" H2 s) {
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //turn on usart3 clock
4 I7 c: i) n7 Q& ^& _; x
USART_InitStructure.USART_BaudRate =115200 ; //波特率设置' s* V7 q4 Y: S5 q5 M# R; _
USART_InitStructure.USART_WordLength = USART_WordLength_8b;" r/ g4 l3 c$ D3 P1 ^2 k# j
USART_InitStructure.USART_StopBits = USART_StopBits_1;3 v% B) F( R4 U, @5 n- z* R
USART_InitStructure.USART_Parity = USART_Parity_No;! A! P1 l1 ^% }* ]
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;: A+ ]( n: x- D) j% x* R! H, {: }
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; . w6 P5 T" j6 N# C1 j
USART_Init(USART3, &USART_InitStructure);4 Q4 M. w) q4 a) w1 g7 K
3 A4 `1 ?% @2 _" [7 a& H
//USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
USART_Cmd(USART3,ENABLE);
USART_ClearFlag(USART3, USART_FLAG_TC); //清除发送完成标志位8 H0 N. V `4 l- z. g! Z
}, B7 ]9 @0 ~ E( e2 x3 G e! b2 w
/**. [ Q# o8 c& l, P6 D$ r1 F$ H
* @brief This function config nvic.+ P7 A- [7 o/ ?7 ?' r; h4 N
* @param None8 T# Y8 C y6 w- l
* @retval None! h4 E% Q& b* \. h
*/
void Bsp_NVIC_Config(void)
{9 p$ D& Z: A! E5 s6 a
NVIC_InitTypeDef NVIC_InitStructure;1 l& l9 E! }; X) r/ a" U/ {( y
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
! W% u0 }: [, B1 {
NVIC_InitStructure.NVIC_IRQChannel=TIM1_TRG_COM_TIM11_IRQn;9 V' q+ H4 y8 A3 H
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; _4 h3 Y% U+ m. N( W0 P
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;, z$ K" {- n) N+ E2 X% x8 x
NVIC_Init(&NVIC_InitStructure);" Z5 z' T% F0 i/ {$ ~
& O, R9 a, B, X! S/ V+ [
NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn;& r# w9 w# B, J9 m2 }& f, A
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ]3 ?, c. f0 G5 e+ M( H4 s' Y" n
NVIC_Init(&NVIC_InitStructure); T3 [" Q% f7 h7 I; u
}
/**- X3 o z1 ^" D6 @/ O2 c
* @brief This function config timer2.! s6 r5 x- N# M8 h0 P
* @param None* I3 d1 l. S" r3 N' H0 @5 o
* @retval None
*/
void Bsp_TIM2_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;" o( [; ?& ?& }2 F
* v2 [7 @( a! U( Q# S6 u1 |5 M& J4 R+ Q
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开定时器2的时钟
TIM_DeInit(TIM2);
+ h( r6 s/ d3 l2 `! u/ o
TIM_TimeBaseStructure.TIM_Prescaler=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //定时器2向上计数9 u3 P) r% l* ?" F8 L
TIM_TimeBaseStructure.TIM_Period=0xffff;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;# ]. O7 D# [ `" H
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM2->ARR|=0XFFFFFFFF; //配置; ? V* C7 A- @3 J- I
//定时器2外部时钟模式1的配置
TIM2->CCMR1|=0X0001;
TIM2->CCER&=0XFFF5;
TIM2->SMCR|=0X0057;
TIM_ClearFlag(TIM2,TIM_FLAG_Update); //初始化时必须将溢出中断清0必须在开溢出中断之前。4 Y1 V/ b, ^# q) ~
}0 d. k3 W( x9 j
/**
* @brief This function config timer4.
* @param None
* @retval None
*/
void Bsp_TIM4_Config(void)+ e( a5 D0 ?0 @. r
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;0 b) [! o$ r1 `# t& z8 `
TIM_OCInitTypeDef TIM_OCInitStructure;1 A6 @) t3 i8 }4 W9 Y
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //turn on TIM4 clock TIM_TimeBaseStructure.TIM_Prescaler=1; //Fck_cnt=84MHZ/2=42MHZ, K1 K( W! e0 ~
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM3 Count mode
TIM_TimeBaseStructure.TIM_Period=699; //Fout_clk=Fclk_cnt/(ARR+1)=42000/700=60KHZ( D$ V2 f e+ B# g8 u. ^2 n
TIM_TimeBaseStructure.TIM_ClockDivision=0;
6 J" o( [) t/ s; N6 D
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
4 @# U+ t: N8 B0 q; ^: v
/* PWM1 Mode configuration: TIM4_Ch1 */
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode; L: v% Y( b3 u. X8 w D
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc1 as output ) `4 u T0 B! a2 Q1 F* D" C4 \* f K
TIM_OCInitStructure.TIM_Pulse=350; //config TIM3_CCR1 vaule
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc1 high level avaliable+ d3 `8 z9 j" ?
TIM_OC1Init(TIM4, &TIM_OCInitStructure);1 p/ [3 A+ P# i3 r! ^ b7 D
8 z/ k' V1 d3 ^ H3 f' E) y: n
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc1 preload
/* PWM1 Mode configuration: TIM4_Ch2 */) V- C" q2 i( u: T
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode) t- e* [8 M) j# P
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc2 as output . E; k% f5 G, Y) N' O' ?# G' j
TIM_OCInitStructure.TIM_Pulse=500; //config TIM3_CCR2 vaule: q: R6 H' [5 N
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc2 high level avaliable
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
7 e% ~7 t, b- ?1 u! v
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc2 preload " h9 W3 S: V4 y' m: \/ x
/* 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 vaule5 T! @8 P9 b. D, Q* s; R
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc3 high level avaliable; E3 I# y( h a8 U
TIM_OC3Init(TIM4, &TIM_OCInitStructure);: ]9 e( A# d7 t% Z( r2 d
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc3 preload
/* PWM1 Mode configuration: TIM4_CH4 */- a9 ]2 N/ L( F+ b( B4 h0 L3 I* _
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //select PWM1 mode. s& G- z6 V8 J- l) l* ^
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //config oc4 as output
TIM_OCInitStructure.TIM_Pulse=600; //config TIM3_CCR1 vaule8 \5 T0 }4 i0 @$ P; ]$ B0 v& m$ V" b8 X
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //config oc4 high level avaliable4 G3 p2 n9 W% S, \: \* o0 ^
TIM_OC4Init(TIM4, &TIM_OCInitStructure);) Z( c6 y# @6 v
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // turn on oc4 preload
TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM3 enable counter *// k/ o* t7 X' [; \( G- y F
TIM_Cmd(TIM4, ENABLE);
}; O% X9 e1 D! J2 M! R0 l
定时器1触发中断程序如下:
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Trigger)==SET) //检查是否为触发中断
{
TIM1->DIER&=0XFFBF; //清除定时器1的触发中断# F1 |) U& c- E- D+ m
TIM1->DIER|=0X0001; //使能定时器1的溢出中断
TIM2->CR1|=0X0001; //打开定时器2使其对标准信号开始计数, d5 A1 D" W, i$ y4 I
TIM1->SR&=0XFFBF; //在退出中断之前必须清除其中断标志位4 Z# U7 ?/ ~, \! q+ S
}
}5 O( k7 R" C) g0 K* M% g- c
定时器1溢出中断如下:
void TIM1_UP_TIM10_IRQHandler(void)" J" d$ t" @; P3 R3 A( A) \$ i1 c
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET) //检查定时器1溢出标志位是否置1" A+ l+ w. F* F5 l5 ` U! g
{
n_Counter=TIM2->CNT; //读出计数器2的值' I2 V5 a2 Y/ I2 |, T
TIM1->CR1&=0XFFFE; //关闭定时器1
TIM2->CR1&=0XFFFE; //关闭定时器2
TIM2->CNT&=0X0000; //清除计数器2计数寄存器的值
TimeFlag=1; //1s标志位置1! i8 [, g, @1 n
TIM1->SR&=0XFFFE; //退出定时器1溢出中断之前,必须清除定时器1的溢出标志位
}
}0 H' ~% o% O& M: Z# L$ I( L9 O
</i>
1 s: ?' ?- ^. ^& z$ N: H