|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1.PWM输出配置步骤
& N+ c& X- s& K1 R7 h; zEPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。
% M- @6 t6 \4 W! \(1)开启ePWM外设时钟及失能时基模块时钟
y( ]* ]. w, l" H( R使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。# s) w6 q# B9 }* C& q& z9 F i
* l$ p% j% I/ ]; c9 t
EALLOW;" G: f/ d- g% e& _1 `+ H
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步
( n/ O. a& v9 {0 E! [, H SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 开启ePWM1外设时钟) s5 h" q; |; j5 z; ~
EDIS;
, ?( C6 ^# ^( c/ f0 J# e
B G2 N, Z6 g(2)开启ePWM对应GPIO时钟及初始化配置
. W- p1 v! R" J7 D) ^PWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。
, g4 V# y$ _" X. N" Y) O9 x! H! r) S" j2 C
InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启
* b. u: r. S3 n2 p14 q8 t" f: h$ J6 W) z# {" ^+ D
(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)
/ `2 l6 N- y2 x) `$ @- }通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。
; f7 O4 E1 C5 c7 u
$ G* y* R0 p0 F( ^// Setup Sync4 J6 E7 o9 r* ]6 L/ I& W
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止(即不使用(输出))ePWMxSYNCO信号5 ?: q" j. g& t
// Allow each timer to be sync'ed
! n( D+ a V: G1 J1 D% ~" S- _ EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值
1 H4 z. v( t: d EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零# J. v9 v! }1 n9 }8 X( P0 C% l
EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为05 H, O4 x, ?4 H" B
EPwm6Regs.TBPRD = tbprd;//设定周期值: ]% t3 N* w; C8 k% L4 ?7 w
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up向上计数模式6 ]8 n& P* j3 k$ V p
EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK! q6 R, u, J3 i, W1 A5 Y* C( u
EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟0 V% V! f, a. w Y* |; m
( ]# \, x2 q1 H, R( f' I4 M
(4)初始化比较模块,配置CC相关寄存器
' Y l4 h0 |2 c3 B! o0 E0 U通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。
2 j$ O3 s- g7 h+ ~* r* Q6 K; {& s& W; _7 z/ g9 b. K: b
// Setup shadow register load on ZERO
$ n" O% M% m$ E" t1 i' _ EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器9 H3 N+ A7 c" P% f- ~# x' {
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器
/ s7 `* r2 {8 F. H EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载/ C5 W$ v9 l1 Q" Z b8 m
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;, Y- A; S; j, N2 r6 @
. |% [6 O+ h: ^. y$ P0 Y // Set Compare values' z& g4 B% L0 S; i6 n) g/ Y2 u
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value
( d% L4 c. ^; _6 Q) v& M EPwm6Regs.CMPB = 0; // Set Compare B value
! J; I' \- H: t6 C8 Q5 X
; n. x! Y2 X: P4 r9 n$ [8 Q9 J(5)初始化动作限定模块,配置AQ相关寄存器值8 c& `; z9 v, D
通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。
) Z# }3 c% H0 P
; r: X+ C: H s: {// Set actions
# z5 S7 l8 a3 Q4 q! l0 A3 H EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
6 u4 ~ L7 A+ l( |; s9 o EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
& i0 ?0 i) a$ ^& y& C: X, J3 {* T EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
& B/ T, K/ j% C3 e EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count
% {% |; H1 F" l! f# o' S1 P" h$ _ I9 Z3 H. d3 ]; w1 V/ s: A
9 k: x! @1 W$ P: T$ r(6)初始化事件触发模块,即配置ET相关寄存器值
9 m( I: }% x2 W0 B) e. m当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
- C* M1 r4 y# b- q
2 R- a+ R' h7 K. Q EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event, |7 \# h/ w# X# O) j( n" ^
EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT& Y/ z3 C$ u5 z" X; \/ J! P
EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT
: R: z9 W0 z, V! |
& s9 f3 ?1 H8 K# m1 z& T5 x& ?(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
: g( A' i; C t9 z4 Y3 M% {7 X一般不对死区和斩波模块进行配置。6 b- X1 y! B/ ` L
(8)使能时基计数器时钟 E; k1 a0 S( k' [) K$ r
各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波
; ?) g' D! J6 u
5 P3 C: F+ z. i8 F/ xEALLOW;# w. C% [. S& Y7 ?% \8 n
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
2 P$ {0 b7 \, L/ j8 S EDIS;
! f5 {* |& o5 _# d1 z1 N, v, p; G7 p
2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度$ ^# W; a" v3 U$ ?5 E3 o: S, C
主函数代码如下所示- J$ L* C% q0 t+ P' \
& [3 n( m. Z, ^: @' V#include "DSP2833x_Device.h" // DSP2833x HeadeRFile Include File* f, ~, G% M# t. X/ S. W: Z$ J- E
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File' a* r- y9 [- S+ f2 }
8 M/ j0 x* R+ i+ _& |, |
#include "leds.h"
) Q( c3 b2 A* ^#include "time.h"//在定时器中控制灯的闪烁
3 c8 |4 q4 H+ B4 Q+ L#include "epwm.h"//存放PWM的驱动程序3 |" n# |+ w8 T! @( H3 U% \( H
void main()
6 W( T3 O: n6 @7 b$ t0 s{
( ~ x7 W9 r$ R" E6 X K3 y int i=0;
% t6 K$ |' f5 r7 S* U8 { unsigned char fx=0;//fx指示了一个方向. n' `7 K2 i7 T3 K! F0 U. p
9 K4 U% p0 ]+ A* |/ t
InitSysCtrl();
& b3 x( o. l9 J
/ c0 K3 q- ~+ ]4 M4 k) O InitPieCtrl();2 t* y8 \: Z6 i
IER = 0x0000;+ l- V, o. ~0 E2 K
IFR = 0x0000;% E: t8 [1 E2 A+ n n
InitPieVectTable();* ^: ^4 D+ E3 Y3 c' a" f
. P* J) o; `# d2 _; R( a* e
// LED_Init();
2 v7 }8 P0 @6 m EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟
7 W+ \+ A1 B7 L* y5 Q$ B$ E& m5 s0 a5 V) s
while(1)
/ ]0 Z: N9 |8 J# X1 r" F8 m# ? {
8 L" Q& J+ a6 O7 ?( t( I7 l if(fx==0)
. _/ n* B0 L) q) j6 k( ?/ q {
0 r! j# p. d; ^( L) S; `! A i++;
5 y, Q' `- d9 P- N/ Z& J6 k if(i==300)
( E2 U2 W1 Y S# j" W9 k3 W0 E* c$ _ {
# g! P: x+ d2 F4 j fx=1;
8 Z, g) ~3 u2 ^. Q }
7 C+ }# j% \# h* r5 V }
2 }' }$ k5 c+ r8 o else
, X- V0 r$ G3 c1 G: R2 ~7 _ {
- \1 g% c- o+ `' R0 } i--;
/ w1 d { w9 O9 r8 z7 g% Q. Y if(i==0)2 `9 ^3 l8 h: L
{$ L0 I7 x& a% e: w6 b4 ?# R5 f
fx=0;
3 F- t- o8 q' k }
) G" C& J; M! P& T; G% ?; o) u }
! G; d, l' S+ U6 @5 I, e EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.6 R3 |8 ?$ t+ c% v5 p' _
EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499., l9 n% S& T0 ?& j4 L7 ?
DELAY_US(10*1000);6 ]3 w1 U# R! c8 |; B$ u+ l
}) o8 Z( j6 d* ?% t
}& O: {2 w5 {! y- J$ }* g5 T! |
& R9 ?0 Z) y9 f$ F7 h2 P* K9 o) }4 a8 J2 ]2 i
|
|