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

产生两种交替的高频pwm输出

[复制链接]
黑皮男 发布时间:2018-3-27 20:49
本帖最后由 黑皮男 于 2018-3-27 20:57 编辑
! X8 Q3 h* ]" ~$ t$ W. ~, ]8 j6 y: x8 f4 O9 v3 T5 Q0 E
产生两种交替的高频pwm,最佳的组合就是使用主从定时器模式。一个定时器做主,用来产生pwm,另一个从定时器对主定时器进行计数,当产生足够数量的脉冲后,在从定时器的中断中更改主定时器的ARR和CCR的值,来更改定时器的pwm频率。但是当频率很高的时候,两种频率进行切换的时候,中间由于代码的延时,切换处的脉冲信号会有误差,不会和两种频率PWM的周期相同,这个对我的应用是能够满足的。目前测的2M以下的频率计数比较准确。下面是部分代码实现,只做原理说明,代码无法拿来直接用,需要一些其他相关配置,平台是nucleo-f303,主定时器是TIM2,从定时器是TIM15。请见谅,没有准备图
5 e& W5 G/ H6 p$ O0 f' c( ?' J
) B: l* A; N. `, A& s! W主要步骤:5 |0 }  i- P4 E$ V& @" {  M4 C& Q
1、主定时器初始化,设置好初始pwm频率
# Y: a# Z$ `1 s& e2、从定时器初始化,连接到主定时器  F; k. U: v' a+ L
3、启动定时器  ]2 B2 A# H0 Y7 ?5 y6 C1 f% U5 U
4、从定时器计数符合要求脉冲数,产生中断,切换主定时器的pwm频率5 ~. H2 y0 Z7 O! I0 Z

, x( `. E0 Z  t7 g, ?2 @主定时器初始化0 ?; D1 ]+ o7 J3 g  L  a; i8 e
  1.     LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);$ U9 Z4 b) T/ N& O7 h9 p9 c
  2.     LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);( }- U9 n' t8 N! n+ b2 m
  3.     5 M# `. i2 F4 u& H3 n' T1 Q; B' {
  4.     LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE);//主定时器主模式,更新事件产生触发信号到从定时器
    * [6 ?8 ^  ?/ t, a' v
  5.     % ]7 s0 q7 a; B3 F3 K/ x
  6.     LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); ; R) |4 `1 B- u$ h7 k& h
  7.     / W$ z3 R" w6 l% |
  8.     LL_TIM_SetPrescaler(TIM2, SLOW_FREQ_PRESCALER);" n' m& S( i( D8 }" Z
  9.     3 S7 _. G$ H2 g8 ^5 m
  10.     LL_TIM_EnableARRPreload(TIM2);; |7 P" g7 w3 v( U
  11.     3 O, A5 E9 _* p& b4 k; _
  12.     LL_TIM_SetAutoReload(TIM2, SLOW_FREQ_RELOAD);
    9 n& b9 ?2 d3 h- q* y) S
  13. 6 ]' b9 j6 g: S* R& r; T
  14.     LL_TIM_OC_SetMode(TIM2, PWM_CHANNEL, LL_TIM_OCMODE_PWM2);
    - y7 t; f; Z- l- N, ^
  15.     ) h4 |1 p, \( I8 c( g# y" c
  16.     LL_TIM_OC_SetPolarity(TIM2, PWM_CHANNEL, LL_TIM_OCPOLARITY_HIGH);
    ; v/ b5 z1 P( _
  17.     ! z5 E8 f$ ^9 p! E  l2 |2 a
  18.     LL_TIM_OC_SetCompareCH2(TIM2, SLOW_FREQ_PULSE);
    ' S# ^# G0 ^- V
  19.    
    / V5 A0 q% c& Y4 x1 C
  20.     LL_TIM_OC_EnablePreload(TIM2, PWM_CHANNEL);$ R1 Y- a  F1 M
  21.    
    0 F6 n6 |* e9 e1 }, Q' Q; R: [
  22.     LL_TIM_CC_EnableChannel(TIM2, PWM_CHANNEL);, ^) g- P* B3 Q
  23.     ( C6 N4 K( e. B7 T' ^* N" U
  24.     LL_TIM_GenerateEvent_UPDATE(TIM2);
      s' i' ~% {+ H1 W  t" t
  25.     * X2 Q% I+ P+ I: a6 l
  26.     LL_TIM_DisableCounter(TIM2);
复制代码
从定时器初始化
  1.     NVIC_SetPriority(TIM15_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),10, 0));$ g8 q$ @3 B. l8 a
  2.     NVIC_EnableIRQ(TIM15_IRQn);
    ) @% }  V" e4 ~% m4 ?
  3.     //从模式,连接到TIM2
    ! D9 M) z' O0 G3 H! ~0 y3 d4 ~
  4.     LL_TIM_SetClockSource(TIM15,LL_TIM_CLOCKSOURCE_EXT_MODE1);, f5 |0 }! o2 f( N! P' d$ w
  5.     LL_TIM_EnableMasterSlaveMode(TIM15);
    % d5 ~( l8 `2 L9 A$ H, K
  6.     LL_TIM_SetTriggerInput(TIM15, LL_TIM_TS_ITR0);
    3 P2 N# y$ w9 g
  7.     3 t% g; B7 [& R! y2 @
  8.     LL_TIM_SetClockDivision(TIM15, LL_TIM_CLOCKDIVISION_DIV1);
    8 O2 F4 c4 G, X6 v/ u+ i1 t* V, K
  9.     LL_TIM_SetCounterMode(TIM15, LL_TIM_COUNTERMODE_UP);: D& V' B( I% {2 k# @5 o
  10.     LL_TIM_SetPrescaler(TIM15, 0);0 B' `/ X1 a! n; w. ?
  11.     LL_TIM_SetAutoReload(TIM15, SLOW_PULSE_NUM);//第一组脉冲的数量$ v* s/ d6 r1 J' d: z9 r
  12.     LL_TIM_SetOnePulseMode(TIM15, LL_TIM_ONEPULSEMODE_SINGLE);
    4 `- x: ~+ Q+ C' l
  13.     LL_TIM_GenerateEvent_UPDATE(TIM15);
    $ b5 j: ^# ?6 [  R- e: |
  14.     LL_TIM_DisableCounter(TIM15);+ |8 |6 Q" g  J+ \, M2 b, u# P/ U- O
  15.     LL_TIM_ClearFlag_UPDATE(TIM15);; p/ ?  v. h7 G) ?. Q4 C& o* z
  16.     LL_TIM_EnableIT_UPDATE(TIM15);
复制代码
) m/ c1 l7 _% ?

: f8 e. y( i/ p! T, k
! P# v/ X( N( b+ S; K从定时器中断函数
  1. void TIM1_BRK_TIM15_IRQHandler(void)
    # i+ J- s: J8 s6 k) ~
  2. {
    4 ~# G  i% F' U) z3 t
  3.     if(LL_TIM_IsActiveFlag_UPDATE(TIM15))* D+ l) q* C4 {4 C2 K& {4 |4 ^
  4.     {2 v4 o9 t. a4 r
  5.         LL_TIM_ClearFlag_UPDATE(TIM15);
    5 ~  @$ R, t( S& X4 t8 a. o
  6.         LL_TIM_OC_SetMode(TIM2, PWM_CHANNEL, LL_TIM_OCMODE_FORCED_INACTIVE);
    4 v! _& x0 o( p
  7.         LL_TIM_DisableCounter(TIM2);7 c5 y0 r% z5 i
  8.         LL_TIM_SetAutoReload(TIM2, HIGH_FREQ_RELOAD);
    6 ]0 D- j* L3 W3 |9 v
  9.         LL_TIM_OC_SetCompareCH2(TIM2, HIGH_FREQ_PULSE);( I8 {8 T5 Z' n9 U
  10.         LL_TIM_SetCounter(TIM2, 0);' d) q0 r1 H0 p% A$ R, B" U1 B
  11.         LL_TIM_EnableCounter(TIM2);
    ' q( w0 m1 a( \6 V
  12.         LL_TIM_OC_SetMode(TIM2, PWM_CHANNEL, LL_TIM_OCMODE_PWM2);, @' V! E# I! f+ @" T$ _1 B
  13.     }$ f1 R! B! R/ D9 B; X
  14. }
复制代码
/ ^9 |4 S$ r% H4 P* [1 A3 w

7 ^& {/ w& }' O) Y& w" z
) {: ?2 K- Z# v启动定时器
, e/ E/ W! ~( N2 g9 N! y9 l7 f
  1.     LL_TIM_EnableCounter(TIM15);
    , ^$ y1 E% y+ ]0 ^* ?
  2.     LL_TIM_EnableCounter(TIM2);
    ( \6 @7 e! ~- K0 V% p: _$ ?0 l- @: c
  3.     LL_TIM_OC_SetMode(TIM2, PWM_CHANNEL, LL_TIM_OCMODE_PWM2);
复制代码

% w' C* _- }# P4 s
1 o9 i9 s7 H, i5 `( G; R  P
: I3 b+ S% p% s7 m( n+ b- p" l: k" I5 E  L/ e; T( m$ X4 V- X) A+ x

! K7 B& x3 f$ [( y3 u3 v- ?) ~+ a' u) e2 R9 r

" _4 W- A! @) C7 {& L; @
赞 收藏 评论0 发布时间:2018-3-27 20:49

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版