|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1.PWM输出配置步骤
! w" Y$ p5 o& T. nEPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。
& D9 W W$ { ], t& w- W(1)开启ePWM外设时钟及失能时基模块时钟* i! i) I9 d# u& x2 h# h
使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。' K; B" y; J0 ^9 O* b- l( _
. q5 X1 Q8 i) u% w& v
EALLOW;# Z0 t1 y# A) n4 |* h
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步+ S4 p: T* e4 |; a$ w
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 开启ePWM1外设时钟
! N3 Y2 o$ B7 ] EDIS;/ N9 q% L* H; E( J
- I: O* H# M2 d1 c, s(2)开启ePWM对应GPIO时钟及初始化配置% u0 z! j9 k( V* I% `
PWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。
" @/ l0 I& t& @+ x% o7 y) o O2 ?% L0 _
InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启
" F9 q0 W8 h5 d3 \2 p& E' V1
/ j- T! t; Z+ W* X0 d(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)$ d9 T+ z! d9 a9 b
通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。
& K" U2 k B8 ~$ R! M) u5 Q3 v( A% S' T
// Setup Sync8 J4 p3 |0 G4 p6 ^1 Q
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止(即不使用(输出))ePWMxSYNCO信号
! y9 L0 P* [, r/ [ `/ }" W // Allow each timer to be sync'ed6 A6 o6 ?( G; A+ _3 U, Q
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值# W: |+ ~5 h: s8 \$ V
EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零) h$ w* M |1 X" q, w
EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为0. @1 H r' {) @" j w
EPwm6Regs.TBPRD = tbprd;//设定周期值1 `0 K; u( y' U
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up向上计数模式
2 E8 a2 |% A8 ` EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK" ~# i% _5 j" |
EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟* V' u( h- j/ |2 j" H
8 O8 A3 ~8 {$ O( m. S
(4)初始化比较模块,配置CC相关寄存器
( |. f0 @0 x9 o* s通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。
0 L/ [+ H' r, @4 ]) j6 k0 B# _$ i# Q4 G7 [+ D" ` U/ j J
// Setup shadow register load on ZERO1 q; V9 ~/ P$ c. d" x: j, p8 C, a
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器2 L2 \' c$ k5 \$ K2 U
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器
& i# l6 x4 a0 d EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载
6 x/ t& A8 W# f4 K5 s) _/ d3 @8 J EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
9 P# |+ m" Z$ J7 w( I9 R& Y F
! ~4 u0 {& X& g* X // Set Compare values; N% t" H& e* C6 |# K5 D7 z5 P
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value
- C4 Z9 j! I9 b$ v6 l- C( L EPwm6Regs.CMPB = 0; // Set Compare B value
5 Z* g% n( n( l, i
1 \. C6 T% m) r7 e/ T(5)初始化动作限定模块,配置AQ相关寄存器值
4 d1 I8 I0 D3 V, T, Q4 f通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。& [+ b/ S$ w) j& [5 |
. E- Z* s5 j* A) t7 g0 W4 v// Set actions0 ^: |9 R; U' y
EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
3 O2 l* d7 G5 {0 v @; n EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
: o% y- }3 m* ^8 J EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
- X u, E* ?$ p2 C7 [, t7 Y7 I5 C4 r EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count
3 m$ K& }5 Y* _+ X j1 Z
! O6 b0 z4 O5 U5 U( {' @
0 z$ Z7 O3 P& S- z7 F: L/ s3 d(6)初始化事件触发模块,即配置ET相关寄存器值# T+ E/ }1 M1 n" x- ~ v1 a
当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
, L8 E0 {# W- `; J# Y' P8 Q9 X6 F j2 {: J3 N( ?# u" D
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
6 P$ h3 f3 C6 Z y1 w EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT8 l) {7 Y3 M" B( `# b
EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT4 w; N; R- |7 q6 B& t/ ^* i- Y8 D1 o B
! v8 ]/ J9 {5 W; a, J3 r2 l1 W(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值" c/ R- p; ^! c; p9 K# e8 A. x N
一般不对死区和斩波模块进行配置。
! Q, Z0 ^% h/ [0 }4 E0 A- v) }(8)使能时基计数器时钟6 S1 K* d4 S4 o' ?, }7 Y3 g3 Q$ J
各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波, M* r! Z+ H& H
/ M, v/ a+ i+ L) x* PEALLOW;
( G* p( C2 @) B. @8 k5 z; d SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
4 \- e+ }% I; E8 f% h! b/ i EDIS;
- Z7 I F# s! U1 r3 Y; `2 s+ E b6 }: @* Y7 U4 F0 k* C
2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度0 x4 ]! [2 Y) W) O4 U6 V, C
主函数代码如下所示, L# m7 g- S# _8 L
/ T. e; ~0 {8 U ~
#include "DSP2833x_Device.h" // DSP2833x HeadeRFile Include File
; K c1 i4 O5 q1 d+ ^#include "DSP2833x_Examples.h" // DSP2833x Examples Include File9 f0 b Y" n5 q5 }0 \$ R. N, s
: H! f |9 C2 a0 D& ]* ^! [
#include "leds.h"
& ^6 o$ P& k$ p/ j#include "time.h"//在定时器中控制灯的闪烁
' j2 ]. q8 P% ^1 R5 s. _4 `) t#include "epwm.h"//存放PWM的驱动程序- l2 v8 X$ G% G9 b% Y- I+ u
void main()7 k- u+ k; K* ?+ D
{
0 W9 k# K5 Y! K8 R. B5 m int i=0;) d5 V; B6 l: N6 k+ V/ b
unsigned char fx=0;//fx指示了一个方向
+ Q* s% V, B* N/ q9 m- O$ U+ I: o( G: x8 @$ e( ^
InitSysCtrl();
( ]/ y1 g4 ?! X: B; v
, s& l' a$ c4 r) b InitPieCtrl();2 ~2 b0 k. E: a8 k
IER = 0x0000;$ H% }4 [8 Y& C& [
IFR = 0x0000;
( [( p8 K( g' V; w& V T* B InitPieVectTable();
7 z+ N8 p |& |, S0 A3 a& O+ F8 U
// LED_Init();4 ^! C; Y2 m& w
EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟
$ F; w+ W& }$ [8 r
/ P! J) [; C% q" `0 c6 _. e while(1)
- _5 d4 A( r; Z5 D4 m' m W; l {
3 ]7 ^% O5 g( N" D/ F a1 r if(fx==0)% I) d! D1 ]% o
{
- E" z( z4 x6 E. r& D i++;
! g; b5 o- o3 H0 R# M if(i==300)
3 H, ?5 y$ T1 v9 Z; \1 a$ @ {* W$ _3 R( L3 p8 |8 C V5 S6 y3 I/ M
fx=1;
/ h- m$ A2 ^8 q- x$ F9 e: ?* f }; L4 L4 W+ _' B- H6 ]7 q
}
$ A. X' }- E) c; P$ O$ \ else
" D" }* }- \5 J# W- | {
; g1 W% J: \" ]- Q7 z! O i--;
4 T; k( b: C- Y: P5 a- i m if(i==0)# J0 E2 n4 i0 C9 n2 r
{2 S. b# U6 y5 S& d) @
fx=0;
1 ^2 X4 M, t8 P( w }
( z6 P& b3 }6 ?) R$ y }
3 e0 k* d R7 d5 o, y8 h+ c, q7 c EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.
# u6 W3 c' m9 S U& f) T/ p4 W EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499. Q; D; c# D5 I: y- c" V
DELAY_US(10*1000);8 G4 p; r; i/ B8 M5 n: Z0 o
}
4 |( ~7 O' ^4 p* }( f( g6 |}
6 ^; p" d7 Z6 J* O. M7 h6 ?. ^; Q7 P9 u$ ^
) w: L) V: w( L% M |
|