|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1.PWM输出配置步骤9 _4 ?0 z5 n6 \4 h
EPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。
+ w: ?7 D1 n% q+ f/ p3 t(1)开启ePWM外设时钟及失能时基模块时钟
" ^8 G' Q6 i+ x1 q& h1 z. {使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。
. \; O% j/ Y8 Z% c& G: c3 W9 ~
+ Q9 q1 J J, R: e( D5 }, a EALLOW;
. N. F# \1 C c- K n6 R1 m* z SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步5 n% k- H9 g7 h' c
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 开启ePWM1外设时钟* Q, h0 g. f. k
EDIS;
0 J2 l6 p: K/ b1 ]) O& K, a( s& z6 }- D( a
(2)开启ePWM对应GPIO时钟及初始化配置
r% j/ T5 C) FPWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。
7 i7 f( [: ?) W' U9 n$ u! u
; Q" Y( d3 N; [7 {, v" d InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启
5 ]$ W" u* U7 ?( z* @& G) H17 y1 d% `0 {! u) ^1 s
(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)
# Z! a+ T, g0 z8 O Y( x通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。
; I* y9 M# P# e9 S# j. V% ~9 k" y; g) Z) _
// Setup Sync% }6 |( p% P2 E7 i. i, z% A0 b
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止(即不使用(输出))ePWMxSYNCO信号
; m5 t# O5 l h9 J( S: b- A( V. x // Allow each timer to be sync'ed
$ d Z( l6 ~7 X9 g- v EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值
: I. p8 W7 a, Y9 Y. [3 j8 N( k EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零
& {5 z. K; d: O8 F5 ? EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为0
% ^# r6 C# M" u$ w& B0 ]" x1 K EPwm6Regs.TBPRD = tbprd;//设定周期值
8 o1 k) f X# y5 `( `3 [ EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up向上计数模式
) _5 K. {7 X9 k7 q EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK* h% X' Q* w5 u8 R3 ~: n8 y$ _
EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟
; `" r# z( x* G9 I; u) {; t& V8 y# K% P/ |. K+ @8 v* w
(4)初始化比较模块,配置CC相关寄存器
4 ?8 \) x Q" b通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。' o1 U9 X0 w# i2 O: ^ w
+ y: i4 L8 x2 E0 e! E6 ?: \& P// Setup shadow register load on ZERO0 E; m" H. |# k, y9 P) t4 v
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器7 K# _! W3 N% |" A! m
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器' Q7 Q( `' s& Z' p& k+ r
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载$ ~0 ]0 |9 v+ r# }; V
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
& y$ ?$ K2 D/ N6 V' I m
' |+ `. t. F3 {, F! {6 C- o) m // Set Compare values9 B+ [& ~" X) o. X6 ^% C4 [
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value% L2 {9 p0 D) l
EPwm6Regs.CMPB = 0; // Set Compare B value
& k4 y/ l4 p% o$ k) h8 o6 e# @: j, V$ X' L3 c: Y5 k' I2 y
(5)初始化动作限定模块,配置AQ相关寄存器值& C4 L* J- u f, g
通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。' N$ h t* m4 F% O: x$ F* C2 j+ r
. B/ l; `1 w+ e, P3 y; G) \6 [
// Set actions
$ y$ |3 K& M7 ]9 a EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
; v) v8 m, i r9 h3 q EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count" j/ J1 N8 c* Z+ L2 c
EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero, f+ U8 F" I3 m* A) d4 T& W) c( ~
EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count! w1 @6 `( l$ r1 _* a/ U
9 a4 I4 X' D" W4 [. ], d6 P1 m+ M# t; _+ s9 L: e/ J4 P
(6)初始化事件触发模块,即配置ET相关寄存器值, M) i6 B @$ W- ~) p
当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
* g" K, X k( v( l) A; p _. Z0 U" P) G/ j& H+ m
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
3 e( k' n& [1 M S. ]7 O EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT
: Z9 G, N9 e7 r EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT/ Y% O: m$ i- R/ F) l
- F; l: ]- q4 y! t' `8 X1 j, T
(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
1 g( A& F6 |5 X8 C, K( x: c一般不对死区和斩波模块进行配置。
% Q5 q5 ?& L. z3 s% f(8)使能时基计数器时钟5 X" n5 p6 B8 [) B% O$ r, }
各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波
8 T/ I- |" f' Q c E! H" u0 A) V) }9 {$ U- I: c- E
EALLOW;
; r1 G6 |+ F+ g9 M2 h6 l SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced! G3 Z h( X' n
EDIS;
) p% J L6 i4 a, G; a& ^+ j* t' ^4 x9 x, t7 V; N3 L
2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度1 i7 C; t! v4 y) u3 {( U
主函数代码如下所示& S4 B0 \8 f' u+ O
: z& A% V7 X3 m+ ]6 T$ \" ^: H1 w6 K6 z#include "DSP2833x_Device.h" // DSP2833x HeadeRFile Include File
" b8 ]2 u8 z4 ]9 x#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
: C' ]+ K1 q4 Z( |5 H$ [4 R% ~0 e/ L8 ^0 ^9 ?. [
#include "leds.h"
@+ n4 C# \7 g#include "time.h"//在定时器中控制灯的闪烁
+ I7 I) l. n I! G#include "epwm.h"//存放PWM的驱动程序. z5 ^, ]6 Y5 N7 M
void main()
/ \% V, R8 Z0 S* }9 @9 | M{" N A; M/ U9 @
int i=0;) Z. i8 ]( l. }% S, ~+ }. r1 B- {
unsigned char fx=0;//fx指示了一个方向
2 M, \ L7 v7 {: q0 l: A: r, t* u/ {- U, e O: `: @" ?( {
InitSysCtrl();; e$ W" y; u& l" Y! ~3 ~) q5 Q4 ]
! w/ X5 j2 E% t7 [4 X; C7 C InitPieCtrl();
+ P! @' T6 _# t; O& k IER = 0x0000;
" L; }' r% ^8 p IFR = 0x0000;9 }* `* ?/ h) C$ _1 I' G9 l
InitPieVectTable();
x! Z' V) t% K, [. D
+ B O' H: b! z: N/ e) U// LED_Init();3 {# y( u0 ?/ C3 U& r/ H1 K0 s
EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟( K6 g# F7 H7 d9 N( y" a o
& ~8 i3 ~2 w% h4 u" c9 _# @/ b. b while(1)! Y* I$ s( U% _7 Y
{* K% M# A# e R+ ^
if(fx==0)+ {7 M( ^, M# G# x# H
{- D& O3 F! F$ D& e6 Z* Q
i++;
7 }" @0 q+ ^- Z+ Z" X/ H if(i==300)9 }' [' G' k7 R( D
{
/ C/ }$ e/ F% m4 I! S% f- E5 @ fx=1;
4 d+ s* t# _1 h8 m! ?. u }
! l# R9 t! g2 [ }7 {- ]' N" k- R' m- n( ~( |. a
else
* n! O' _$ p$ a" h5 E( m {! R. Z. H; n9 |; g/ l- H+ {) r
i--;6 H. Q8 f. j/ H, r
if(i==0)% |8 ?% h. m: i6 T @& V
{; Y2 Z7 S; O/ L) u! D& e
fx=0;) |, Y7 g2 H/ i* y n O
}
# I' R# V5 M/ ~' M/ k$ a) X* g }
( B3 j$ z3 z3 ]% } EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.
6 j7 G) s y! i" V EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499.
; C- v7 n$ d' Q$ m, \ DELAY_US(10*1000);$ x- l. l1 a4 N. W% g
}
" p4 \$ [9 M% Q# N- P& ~* B1 I5 S}
{4 o. g2 |6 p' i X) J) n6 \: F% U1 o0 v1 A1 G
# `. [1 J" d2 M8 D- X
|
|