EDA365电子论坛网

标题: DSP28335-ePWM [打印本页]

作者: guanshen    时间: 2021-9-22 13:41
标题: DSP28335-ePWM
#include "DSP28x_Project.h"
7 l* H* ~3 d4 q% y" d& }. f6 X// Configure the period for each timer; v( F0 \; F* C% O+ ~$ B9 X
#define EPWM1_TIMER_TBPRD  3750  // Period register 系统始终为150MHZ,下面的程序进行了4分频,即为37.5MHZ,这样得到的是10KHZ3 R0 f8 {0 A- J$ R& b
#define EPWM1_START_CMPA     1900//设置PWM通道A初始占空比
+ c" l( [( o( N* s8 w#define EPWM1_START_CMPB     1900//设置PWM通道B初始占空比
; g4 j5 z  J4 B9 V: l: g7 o7 O& \: |3 hvoid ChangeDuty(Uint16 Duty)//改变占空比函数
: b0 f: E( [6 d( L' }{8 S6 g/ a, S; s; u6 Z2 z8 C
    if(Duty > EPWM1_TIMER_TBPRD) Duty = EPWM1_TIMER_TBPRD;. t3 S. t( Y. P# ^) u+ s4 m
    if(Duty < 0) Duty = 0;& |9 g$ G7 Q2 D2 N( u0 e) U
    EPwm1Regs.CMPA.half.CMPA = Duty;     // Set compare A value* v- [4 k8 V- e: j3 I9 |* E' \
    EPwm1Regs.CMPB = Duty;               // Set Compare B value
7 g5 |: x+ T7 ^; q  G) z}
* }& p5 F: \' M. z1 S1 d# I( n) lvoid PWM1_Init()//初始化PWM7 v" L6 p; l2 T( g! a4 c- O
{5 k% `8 m% f) a8 m6 R$ n  c
/*首先进行的是PWM1引脚的初始化,因为PWM1的引脚为GPIO0和GPIO1,这两个引脚可以是普通的IO口,也可以复用输出PWM,这里选用复用功能*/
' z5 \+ C7 U. [; E  v3 [$ N    EALLOW;+ D% t, O, u% }6 ^- c7 r
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    // Enable pull-up on GPIO0 (EPWM1A)
% L. [6 s  t* k. }    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;    // Enable pull-up on GPIO1 (EPWM1B)
& E( l/ f6 K4 }! L9 k    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A复用功能设置,为0代表是普通IO口% \1 {2 }: m; d" p( \  i
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B0 E& y! ^3 @3 {. b9 i0 N
    EDIS;+ Z# V- P! f; ?5 w0 M1 G
    EALLOW;
: J  z  l" N0 b: [9 n1 _% i    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks; K0 n3 I4 h% b+ g
    EDIS;2 h2 i2 l/ f3 q, w2 c% F$ ~5 q5 w
    // Setup TBCLK# F5 R- V& z) Y3 ?& z$ d8 r
    EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD - 1;           // 设置周期
( K$ `3 u4 B; o    EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // 这个代表的是相位,不明白什么东西
% b$ @7 L- M# S; M  c! C    EPwm1Regs.TBCTR = 0x0000;                      // Clear counter
2 D, v, \5 S% ^# G    // Set Compare values8 |- |4 c1 r+ n' ~* Z" s) v$ V3 `
    EPwm1Regs.CMPA.half.CMPA = EPWM1_START_CMPA;     // Set compare A value) v: j" d+ w) l/ A7 b/ d
    EPwm1Regs.CMPB = EPWM1_START_CMPB;               // Set Compare B value. t& g' b* F1 a
    // Setup counter mode
1 q; G: F; o: P/ a    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数模式
3 |/ k) z# L6 H' y! b    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
5 ^" j0 Q4 a$ B2 t- m8 V9 e    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;       // 这里是进行2分频4 ^% J9 r; S( A) Q4 @+ h
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2;          //这里也是2分频# ~3 T& X6 d+ E
    // Setup shadowing0 a+ K( f# u! M
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;   //采用影子寄存器跟新
; G3 B% D6 g0 h  p& Z6 @( i    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
/ @5 Y2 o5 P/ ~) {0 Z( {$ q    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero
9 c5 Y1 X1 Z" g, E4 g0 V    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
# V# R1 E6 h' z( `0 d' a. o    // Set actions
  }7 @* i: m" w2 h' {4 q+ B    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Set PWM1A on event A, up count  p$ D8 f& p# J
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;           // Clear PWM1A on event A, down count* ^4 ?( C8 l- Y% R8 w$ K0 n& x( }3 e7 q
    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;             // Set PWM1B on event B, up count
& R& y+ u* m4 f    EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;           // Clear PWM1B on event B, down count$ I: Z2 }& C+ V
    EALLOW;
6 x6 j! }! Q/ ^5 p$ ~" d, a7 [    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced; d9 I+ }; \1 Y3 F
    EDIS;
- y2 z; H3 M; c# V- ~' v5 E5 q7 ~}* x! N; [* b; v: ~6 |, I6 _
void All_Init()
  {; h) }; @8 s+ N! a8 V/ |0 b5 N+ e{3 b1 T& ?1 ?- f# N
    InitSysCtrl();& \+ u' ~: C! w  Y/ E/ x* T7 s% ]6 r
    DINT;
, ^2 A  y3 S, W2 l( W    InitPieCtrl();
7 u$ a- j1 a0 v6 J" u& n4 y" f  V    IER = 0x0000;
6 G# M% b" Y5 A5 R* S    IFR = 0x0000;- f5 U# ^- p5 X* x3 b9 d
    InitPieVectTable();
6 u0 }2 U) U* _    PWM1_Init();
& ]8 h0 W: @7 r    EINT;   // Enable Global interrupt INTM
7 y7 _' x* Y* n+ s* \6 ]    ERTM;   // Enable Global realtime interrupt DBGM
' s+ |4 l; d) {: W6 L9 A) v}
. J( {4 I0 c; v8 dUint16 Duty = 1900;9 l* x2 W5 n2 a4 v1 j+ ^
void main(void)/ R5 K% D( i! o$ F( q4 d$ [  @  i
{
3 v( @& [7 c! m2 }: U$ L: Z8 P    All_Init();
4 `$ t7 t# D* K: M! e; g' Q    while(1), r5 v; _) C' }; ]6 i
    {
- ~* m- a" q" j2 r4 u% t        ChangeDuty(Duty);
/ o4 R) X; q" K0 ?: s- m    }
2 M4 M) E$ f, C}
( G5 d% {; s2 |2 h) q) S! ^* F4 U7 @# e3 d3 v% _
产生PWM主要需要三个部件,
9 G% q5 X; U4 |6 z& w0 T& j2 T第一个是周期PRD,通过设定EPwm1Regs.TBPRD的值,来得到周期,我的代码中设定的是3750,系统时钟是150 M hz,经过四分频得到的是37.5Mhz,即1/(37.5M)秒,计数器每个时间间隔加一,加到3750需要的时间是3750 * 1 / (37.5M) = (1 / 10K)秒,即为计数周期,可知频率为10K。/ l) l# x% u0 b6 w
第二个是计数器CTR,计数器根据设定的时钟频率不断累加,我设定计数时钟频率是10K,即每过0.00001s,计数器自动加一。我这里设定的计数模式是增减模式,即计数器加到EPwm1Regs.TBPRD时再自动开始减小,当减到0时,又开始增加。/ A0 w" i+ C: g1 N: ]- ~
第三个是比较器COMPA,COMPA是我们自己设定的比较值,当这里设定的初始值1900,当计数器计数到1900的时候会产生事件,比如讲输出引脚置为1或者清为0。
4 F! L7 u$ f; M6 u8 Y* q这里采用了影子(映射)寄存器(EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;),映射提供了一个保持寄存器与硬件同步更新的方法,当使用映射模式时,只能在特定的事件处更新当前工作的寄存器,这就防止了由于软件异步修改寄存器内容而引发的错误。
' y) P# g" _$ ?+ r+ U" P计算器不断的累加,当计数器的值等于比较值时,就输出为1,当计数器的值等于周期值时,就输出为0.从图中也很容易看出方波的周期和占空比。. K+ e% B9 k, S: ^

) D5 I6 [; w' D# M5 p) x' w4 `$ Q! k7 V/ }

作者: jspij1    时间: 2021-9-22 15:52
首先进行的是PWM1引脚的初始化,因为PWM1的引脚为GPIO0和GPIO1,这两个引脚可以是普通的IO口,也可以复用输出PWM




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2