|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1.PWM输出配置步骤
% G& L. z% i# U! r! S) EEPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。& J7 y! J$ x. G& L/ t+ @! _& N
(1)开启ePWM外设时钟及失能时基模块时钟
2 h# w$ a- |9 t# k" X: p, e' O/ S使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。
- ]% c# c0 @, ?- Q. [2 Z, p9 ^0 K+ d9 g# e. |
EALLOW;% N. a" B. f B3 G, t
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步
" M5 M1 s- O* p7 R" | SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 开启ePWM1外设时钟
, X0 W. r) k s$ s EDIS;
- ^/ F3 l+ u% t [! f/ `: Z/ J* A! Y
(2)开启ePWM对应GPIO时钟及初始化配置( b- `5 z& I, y. e7 @0 t
PWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。, R5 V2 N% @- o! w) h+ g
. o0 m. }9 N2 q# f6 x( y3 {4 P% K InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启) R' h3 j) n9 L1 B
11 W, _7 k$ T$ A; k; ^# Q1 R4 p
(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)9 T. a* K$ ^& f5 g
通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。7 [8 a- Y* b: O$ r5 q
2 X2 `) s* M% V: p* `7 P// Setup Sync
. u( e: [/ E3 q& L' f EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止(即不使用(输出))ePWMxSYNCO信号) {8 N! X6 u8 v
// Allow each timer to be sync'ed
, Q+ o8 Q5 h7 Y* n EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值
" h8 P6 z; z& R* z EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零
, n. L# m1 d7 A! Q1 M' M$ a' R EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为0" p( J _% D- W( c; x8 o
EPwm6Regs.TBPRD = tbprd;//设定周期值' V# O$ S$ \! s7 ?3 q
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up向上计数模式; n5 a6 }5 N& s g" I" h$ F
EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK
' B" w) Q+ \6 C; l9 I# i5 I# l" P EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟& e. O6 X$ j3 t
' m- m; i- d$ @! N
(4)初始化比较模块,配置CC相关寄存器
0 O( ^+ g1 t5 ?3 e; k0 D通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。
4 _: ~0 h" t- p, Y9 g3 [6 S1 H! a7 I2 W4 X; x( g' m
// Setup shadow register load on ZERO: `$ b* U. n4 X
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器
6 @9 }% ^) K4 R/ A( l5 r' e EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器
2 [ B7 i5 W4 T3 z5 \+ e& T EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载
) `9 q# ?3 n* H4 U0 I5 _ EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
; z v4 m( f/ Y1 _( D: E f) X- i7 X. a. l# U
// Set Compare values# W, t6 }+ }1 f8 }( R
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value
* `" P" z4 A# ?) G9 Y EPwm6Regs.CMPB = 0; // Set Compare B value
5 e$ x7 A! F0 `$ v; c8 k6 Z& I
; E, w+ g3 u2 i. P$ O(5)初始化动作限定模块,配置AQ相关寄存器值
- v% W1 Q% Q8 n* p( }0 T通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。
) b4 x$ z" |0 A' V7 v+ K+ y1 u2 R6 ]- a! L6 T. m$ @# m* I
// Set actions
! e# N, I! P. G EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
9 x! M: I; o& L( G5 y EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
4 _/ ]3 n: L5 K% V EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
; o* [! S' |& Z; H; @* H& O EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count% [/ c1 V. h: r2 F& J" g# I; h
* M/ z% [. G5 }7 R4 W, a
% S5 S) s M5 n- r0 i2 }2 Z(6)初始化事件触发模块,即配置ET相关寄存器值
# B6 [& g7 e" n当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。2 q9 D. F, d1 r0 \" @8 w
/ `9 K# h7 h" E, U& h6 z EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event* \. L1 a* T0 h j
EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT
* n) U) l' g9 X( V7 O EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT0 d. c* {/ }6 }9 H- ^, |
6 p$ [- I% `- W* A( F6 j; F+ M, ^! {
(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
- n4 S3 X) h6 f; S2 O一般不对死区和斩波模块进行配置。0 d! `) k2 b& Z. u0 R5 e0 f5 a& x
(8)使能时基计数器时钟
6 T- d/ t+ A# Z1 V各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波
% l1 ]3 D* |# U* Q# n4 N& @# g0 R6 M$ _
EALLOW;: u* ]- N6 y' y5 _) S) R9 R
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced* \: M/ i3 b9 F! \
EDIS;, o" @0 w: e6 b6 w$ [8 z! e) c
; I! J4 H1 X4 w: v2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度
8 ]! ~6 d6 S) u+ B# L主函数代码如下所示
& {/ v, S+ b4 n" w; y7 ~0 q6 Y6 o' }, L1 {" }
#include "DSP2833x_Device.h" // DSP2833x HeadeRFile Include File6 D# k" h& O m* w; H4 E. m$ N
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
9 B& _# T% O3 }- o& U$ H q. A+ ?/ ~6 X) X
#include "leds.h"6 Z. ], G4 }* B+ D9 A0 e
#include "time.h"//在定时器中控制灯的闪烁: U9 p2 e( I. N& E8 U
#include "epwm.h"//存放PWM的驱动程序; U( c3 i1 A( A& {3 l, |
void main()
: @) n! `+ N( X4 G, A+ M0 x2 ?+ Y- n{
- }; i8 t, }3 |) I int i=0;
( _. @7 p1 S2 f( f6 X2 c unsigned char fx=0;//fx指示了一个方向8 T% O( \. e E" d
- ]4 I4 ^; `) f8 P( i% T+ c InitSysCtrl();+ X( [6 n5 ]( H& G
( Q6 m; r. d! X$ j, v: w6 l
InitPieCtrl();& b; ?+ k9 t% g. s( \' ~# b0 Z
IER = 0x0000;
) n/ H4 I2 ^6 V% w% x$ i3 q9 ?6 f IFR = 0x0000;1 Q7 y7 i( k2 U S( N# k
InitPieVectTable();& |7 q8 |% @! E) o0 z' z
0 S9 w7 d1 R6 z0 Z// LED_Init();
: G8 S! b0 E7 I1 z5 Y EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟! J3 p4 h4 W. V4 U, A7 t3 z
2 i) `, c3 e+ O2 W) Q) ` while(1)7 q0 X1 g( V2 D8 t$ _ r# N2 ]
{
) k& d6 t, E9 K if(fx==0)
+ ^5 }. g0 i: A: t { y" ?+ P# @8 f3 B m3 @. x
i++;; Y% ?' e- T( d @+ T
if(i==300)
4 Y5 [1 Y6 J0 N9 S {
; a4 n' ]9 I( b4 U fx=1;" N( a) a' ]2 y& M" W1 ?( j* C
}0 ~5 h* A- @, V7 Z" Y; W
} k" f) I4 z: w) H3 v" e @/ q. N
else
0 I; S* J) q: J$ j1 l3 } {- N3 h7 u) p3 s) ]# `) D+ N( S
i--;
9 r. t) ?0 |% k+ e if(i==0)
. @8 ?, f# [% R" f3 Y3 J1 c) c {5 o$ \+ |. `% v4 B1 \
fx=0;
, B0 N$ U# G8 h; |: z H }
! Y: A3 I: l) G) g( {2 Q$ M) S h }) z# r! x+ z; L! n# `% z" U/ h
EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.
# V; e2 b- O" I7 i: e3 c EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499.# A' z: L7 V7 h6 A" `, y9 o+ h Q' a
DELAY_US(10*1000);0 R) C$ C. y" W# d3 {
}
5 x+ n$ ?3 p% l% H}
( I0 o2 n6 F: Z
( R% J: o6 Y: U) Y% L& s; c, K8 S) J
|
|