|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1.PWM输出配置步骤4 A1 E) D# g9 l( o3 M: m7 G
EPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。
! ^3 G2 o+ G9 q& Z. C(1)开启ePWM外设时钟及失能时基模块时钟) T5 [' ]% t3 @8 L) w& C( I
使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。
^ ^* j T9 b$ Q$ H; _2 S0 t
: {: W( }3 ?+ K7 l$ r EALLOW;
" V: \8 d) S. e( {+ R/ k, G SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步8 ?# d L9 c+ H% V
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 开启ePWM1外设时钟
! E* B+ ^) d. _1 ^/ Z3 k4 P EDIS;6 O0 H U1 R% b) b6 B
6 k( g( v- R2 x5 P6 {
(2)开启ePWM对应GPIO时钟及初始化配置
9 L- i, ^/ h& S) W& B. O: NPWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。7 o4 ~8 }: [1 L& A' p- z* |, \* B
1 `1 r# \ p2 r
InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启; [0 a, p9 L2 k+ `
19 [. b; [6 r+ W0 S
(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)
$ ?$ z% O+ f' d6 A: O" f8 V通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。
$ P1 I- G, O6 H
0 z* F5 S: Z, _) ?, h. y2 a: U* g// Setup Sync
: s3 X+ ?0 ?) b' z8 b. ~; k2 t EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止(即不使用(输出))ePWMxSYNCO信号- J+ Z) O) I4 ~! r
// Allow each timer to be sync'ed4 K) `5 \ M) F5 v7 A* g
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值3 x# e, o7 K- X( Q& c/ @# S
EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零
5 |( E4 d- N: {: Y( b1 z EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为0
& t1 a, C# P3 u) I EPwm6Regs.TBPRD = tbprd;//设定周期值: a' r4 P8 ]2 E( i$ O. ^
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up向上计数模式; K% i5 k+ }1 Z% p; o
EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK4 j9 y) R. C: o( L
EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟; }$ y3 [' L9 d* L
( _7 f" l r0 \! y& S+ N(4)初始化比较模块,配置CC相关寄存器
6 C' ?6 y3 X7 Z, R# y+ `6 N/ f, Q通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。
9 Q6 U2 A+ T$ J, @% v* P
$ S3 R6 M1 o; p$ G// Setup shadow register load on ZERO/ c) K& t' T- j! q1 l4 `: h
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器
% g- k! X5 `( A- q5 N2 [ EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器
. L! `* v! n; I7 w8 A6 G EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载9 X- w, x" L& D1 s
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;3 Z/ ^% p% W+ `: q+ K
2 d A) f' g2 L4 G3 D6 G
// Set Compare values7 H) |' h- Y/ D+ b: \( z& ^
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value
6 B% s$ y0 _1 V. }/ `5 |3 ~ EPwm6Regs.CMPB = 0; // Set Compare B value6 _- `/ e: w: x% s1 ~$ D4 [
$ j r0 m4 t- @( R7 J
(5)初始化动作限定模块,配置AQ相关寄存器值
) ~+ }4 L3 o) R! ?& N0 w通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。
: @# `0 F9 Z7 ~4 A: q; s0 j$ z% D' d2 z1 Z/ W
// Set actions
9 g; ` @5 Q. {0 J0 _- a EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
/ M; P6 S' b& b, w( ^ EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
" i% E1 M' A, }; b9 r EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
# B/ R( f3 D' Z3 j EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count
- f. Q4 r* f- L1 M s: ?3 g# |: ]8 _
2 j) N' h+ u, t: b( ~ |(6)初始化事件触发模块,即配置ET相关寄存器值+ h! T. F0 i |# ^0 b7 G) p; i
当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
3 S9 K# {$ ?+ N8 N8 Q
* N5 W! j3 G. d6 B5 v0 [' R; [ EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
2 O/ b6 W/ p1 d; R% e/ M EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT! e" q5 Q) m& E7 n2 K# H3 ^' l
EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT
0 C8 ], ^5 i" T4 d, _
7 ]7 f1 d( ~ R' }" I$ M A(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
1 D, \8 m; O5 k一般不对死区和斩波模块进行配置。
5 D/ K/ d, l/ b! B. {5 b(8)使能时基计数器时钟3 k: \$ q$ Q2 {6 V( N3 Y% C
各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波
3 n2 l/ V3 M3 w0 o
6 }! E0 v/ T) Z9 B% d t# d: yEALLOW;3 J7 |' }1 Q! R' N
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
" V2 |! U! q! p: h7 B1 s' K% `0 l EDIS;
4 P$ I% o, x1 u& ^6 A8 e- {9 k! @/ t, D8 n- a( L/ t9 s |
2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度0 {8 N7 a+ p3 k$ F! X
主函数代码如下所示9 n# V; G6 @" R% m6 W
7 D9 [: y3 b" Q* s$ _% V, c3 G#include "DSP2833x_Device.h" // DSP2833x HeadeRFile Include File
C8 ~ k5 _! t. H3 S#include "DSP2833x_Examples.h" // DSP2833x Examples Include File9 ]! V9 j' T: _- }
5 p& O5 M2 a2 z4 X#include "leds.h"
/ _! N9 ]5 P. ]1 l, q3 {#include "time.h"//在定时器中控制灯的闪烁
) J7 q! n( I8 F7 `4 O* D7 t" ]#include "epwm.h"//存放PWM的驱动程序- u; i0 G: p& y; }( l
void main()6 [. d- M A& b7 S8 u8 |
{
8 P9 K- \4 r3 Y9 U int i=0;
2 ~: k5 A; C1 P0 {+ d! K+ P unsigned char fx=0;//fx指示了一个方向4 o6 p' e* `1 w
/ N' I1 P, Y d' u. V0 J InitSysCtrl();
/ f5 O) N+ q1 x2 i9 O
% h# S+ P( C( L InitPieCtrl();" B( A. U. I% F. O5 t3 R$ N
IER = 0x0000;4 n# x/ C1 F' a/ ^8 n
IFR = 0x0000;
0 \7 \2 D2 }' f; w8 v InitPieVectTable();4 U8 X9 s- Y: x# [
! V/ v/ _ ?/ d; a8 I4 Q
// LED_Init();
- d9 i5 I, Y! V4 [. ?+ L EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟
! A6 k$ T8 K- N1 w1 p4 P9 L2 j0 M: {0 D" S5 G
while(1)/ p0 h {' U+ `% E1 O, H4 q. ]
{9 Z; U# i2 N- d( N& N
if(fx==0)/ s. v* K- o4 g1 l( m% f
{
& n6 `1 O5 b# V, H& n i++;
- D( [1 V) Q& ]1 E: g$ e+ @' M8 h if(i==300)
8 C9 w5 ~% ~3 h* t9 t8 D2 p0 E {
3 D' O. v: S7 [+ B" T/ t fx=1;5 E/ ?) Z5 h T4 e) k7 J4 g
}
O Z- P- G- T3 H/ f }
3 ]' \8 _2 Q1 e5 m* f else* w5 a6 W* @9 L7 j% q! j1 S4 a
{+ |9 ?4 C' n1 [
i--;
- d: G3 w. a1 I3 I" N1 Q9 o if(i==0). G7 E; [* {& h' ]
{- P6 d3 {" Q! X B6 l6 @( e
fx=0;
# @. P( i0 G' U+ c9 p, B q7 x }6 u! x, H1 z+ v3 L6 `) G( W/ ]
}
$ P7 c# v$ p. z# U0 _9 Y3 S1 ^. M EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.5 f0 s& F/ I: V9 F& c3 S9 T4 y
EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499.' U* R7 b( j% [ R
DELAY_US(10*1000);
9 p! w0 F) h0 a9 W }7 v- L2 ?) Q# X' Y2 m$ Y
}
2 }4 C" G/ m* r4 b
! H% \- @! \# J. s2 v
# _7 s( X) i. H |
|