|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
#include "DSP28x_Project.h"
- g# l8 e9 }: r% l# N9 f// Configure the period for each timer5 X9 ?; E& N& b) [' j- ^5 ?
#define EPWM1_TIMER_TBPRD 3750 // Period register 系统始终为150MHZ,下面的程序进行了4分频,即为37.5MHZ,这样得到的是10KHZ
3 _& s9 e5 ?) x2 ~+ F9 {; l7 M#define EPWM1_START_CMPA 1900//设置PWM通道A初始占空比# v% @- J( I' I- ^
#define EPWM1_START_CMPB 1900//设置PWM通道B初始占空比- e( b* L3 F. n0 \
void ChangeDuty(Uint16 Duty)//改变占空比函数/ {/ o/ i1 r& w) b
{
1 V8 _( }( m, ]' P0 _* b" b if(Duty > EPWM1_TIMER_TBPRD) Duty = EPWM1_TIMER_TBPRD;0 Y0 h* |& r# z. T H! l" ?
if(Duty < 0) Duty = 0;
+ w% }; Y+ [, F6 ? EPwm1Regs.CMPA.half.CMPA = Duty; // Set compare A value+ a; v7 P" [ f! A
EPwm1Regs.CMPB = Duty; // Set Compare B value
# Z' ~9 d' q T" u- W/ Y& F: `}0 l* l0 @, j& `
void PWM1_Init()//初始化PWM
$ B, ?& W ^) M! ?0 P* \{- n) a Y* d: p" {) w6 X6 {
/*首先进行的是PWM1引脚的初始化,因为PWM1的引脚为GPIO0和GPIO1,这两个引脚可以是普通的IO口,也可以复用输出PWM,这里选用复用功能*/
; _6 i! m* q3 g& Z7 \ EALLOW;. z/ {2 x" H" P9 @( r
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pull-up on GPIO0 (EPWM1A)
2 n0 {/ U3 I. G) y GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // Enable pull-up on GPIO1 (EPWM1B)
8 l3 d9 O5 q7 u% n' c1 d& {1 K" s GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A复用功能设置,为0代表是普通IO口
. y C3 }) p! ^- c1 y1 ^ GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B: ?0 W: ?# y8 _" m, v' m8 i2 M
EDIS;
2 H$ S$ p# x* l% M* B5 ]0 p EALLOW;
! h$ ~, Y* M6 t- B SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
6 ]2 K2 }2 J% u; T; y' t- ^ EDIS;
# d' M: P+ F: z2 Y" r! U // Setup TBCLK
! ]! z( l, ?( n3 a5 ~ EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD - 1; // 设置周期
+ G$ ~; s( w8 q EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 这个代表的是相位,不明白什么东西
S7 F/ E0 [6 \; m" u& K EPwm1Regs.TBCTR = 0x0000; // Clear counter
4 H& u) e% ?& G+ x // Set Compare values
" A4 r$ @7 Z$ y& G- J EPwm1Regs.CMPA.half.CMPA = EPWM1_START_CMPA; // Set compare A value
1 P+ K/ o; x. \7 @& v* A/ [ K EPwm1Regs.CMPB = EPWM1_START_CMPB; // Set Compare B value' p# } E( j; i& R; O2 V
// Setup counter mode' r7 e/ | C$ p: @
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数模式
! D. y7 u0 x2 y# s EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading2 e1 z6 i7 f7 ~! o8 W4 d
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // 这里是进行2分频
) h# ^4 k" y: |4 L EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; //这里也是2分频
* D* v" Z9 |+ Z, b4 P. j // Setup shadowing6 w# p7 Q) \9 Z- k8 ~7 e+ j
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //采用影子寄存器跟新
" J2 s* Y. n1 j/ s. l EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;# S' U! j+ U9 S
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
* }6 Y: [$ O) T# p EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; L7 |, H- F: ?# d- |5 n
// Set actions7 W, ?# a( J; D7 d$ F" |
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on event A, up count6 k: o( n% q. I& c
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; // Clear PWM1A on event A, down count# [7 {# a) Q, ?( n
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1B on event B, up count- F( l/ o% i% F1 j. s/ l
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count3 U0 j, R; Q, q
EALLOW;
0 x6 n5 ]6 P/ z( D% M' o$ r: P SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced) P0 Z+ d# o7 B# m# b) a; T
EDIS;
. @, f. j/ |. Q, @$ W5 l} I0 z( ^. P: I, H& u, D3 ]0 q3 ?
void All_Init()
" a3 e7 q& f8 _1 E7 F{& c9 }1 D/ z, W6 R
InitSysCtrl();
, g4 v) q. E" [ DINT;
) r% E: T# S; d# f& g InitPieCtrl();
. B$ j: _+ O; l" a IER = 0x0000;7 b) Y' q7 J+ n+ q) T% J; w
IFR = 0x0000;
' Q& w* I; Q2 r* S; N8 z# z9 J7 B InitPieVectTable();
; r U& X2 I: k3 r: }% D, X PWM1_Init();
- q- b ?; W5 X4 U6 z EINT; // Enable Global interrupt INTM
/ r8 z% _1 p7 X- G5 A) Y+ \ ERTM; // Enable Global realtime interrupt DBGM
8 \) J- u/ D7 ^3 t" u}
/ M9 H6 g* @4 SUint16 Duty = 1900;
! P* b- p* [7 E# o! Rvoid main(void)
' ~$ V5 m' o$ a6 J{9 Y4 g- }5 A; R1 e* _, i& f2 ^
All_Init();
+ S' q _7 u, {1 @9 @ while(1)
% ^& r0 B V5 w {/ O2 Z! G( U8 c; K. }1 O
ChangeDuty(Duty);3 G+ i8 Z+ v' _9 j: V b
}
4 l7 z! {! B4 a}3 ~+ F5 x Z& [* @, [% p) H/ t4 S
$ I$ x* R5 c6 Z' E; n& a
产生PWM主要需要三个部件,
4 ?, O5 T& f2 i第一个是周期PRD,通过设定EPwm1Regs.TBPRD的值,来得到周期,我的代码中设定的是3750,系统时钟是150 M hz,经过四分频得到的是37.5Mhz,即1/(37.5M)秒,计数器每个时间间隔加一,加到3750需要的时间是3750 * 1 / (37.5M) = (1 / 10K)秒,即为计数周期,可知频率为10K。& `7 j+ m! u7 M, F
第二个是计数器CTR,计数器根据设定的时钟频率不断累加,我设定计数时钟频率是10K,即每过0.00001s,计数器自动加一。我这里设定的计数模式是增减模式,即计数器加到EPwm1Regs.TBPRD时再自动开始减小,当减到0时,又开始增加。. Z8 J$ F s; w# W$ R
第三个是比较器COMPA,COMPA是我们自己设定的比较值,当这里设定的初始值1900,当计数器计数到1900的时候会产生事件,比如讲输出引脚置为1或者清为0。1 \! ]; ?6 H6 A, [
这里采用了影子(映射)寄存器(EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;),映射提供了一个保持寄存器与硬件同步更新的方法,当使用映射模式时,只能在特定的事件处更新当前工作的寄存器,这就防止了由于软件异步修改寄存器内容而引发的错误。
6 ^% c$ n7 P0 c& `( t. t4 j1 ^% Y* e计算器不断的累加,当计数器的值等于比较值时,就输出为1,当计数器的值等于周期值时,就输出为0.从图中也很容易看出方波的周期和占空比。
& G, U% n5 G3 m3 m$ W/ Q7 ?1 s0 ?1 W% Q% [& h4 K* M
( B5 A$ f2 h6 C
|
|