找回密码
 注册
关于网站域名变更的通知
查看: 501|回复: 4
打印 上一主题 下一主题

F28355 PWM输出配置

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-12-13 14:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
1.PWM输出配置步骤3 X9 n1 u: ?- r9 K: f* ]
EPWM相关库函数在DSP2833x_EPwm.c和DSP2833x_EPwm.h文件中。: J7 X7 V0 a0 I6 R, o, w% E6 w
(1)开启ePWM外设时钟及失能时基模块时钟
2 x' x+ }; M& a! r使用ePWM外设需开启相应时钟,在对ePWM相关寄存器配置时需要先关闭时基模块时钟,待配置好后再开启,可以保证同步。1 q* [" [0 v( V

$ S* u6 s8 Y( R    EALLOW;5 {6 C1 q2 t) D6 R! b
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the ePWM要保证时基同步的话,首先在配置TB/CC寄存器时先把时钟关闭,即所有TBCLK停止,不产生。等全部配置后之后再打开,保证时钟同步
0 g) h; k  \5 b$ r# Z/ E0 b    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // 开启ePWM1外设时钟
* S- Z0 W3 r! B    EDIS;/ s9 s! @, ~7 Y% ]
/ m5 K$ J# O5 |* I/ g0 \1 j
(2)开启ePWM对应GPIO时钟及初始化配置6 q7 ]; l* ]. }/ i' U& O, X
PWM输出通道对应F28335的IO口,所以需要使能对应的端口时钟,并将对应的IO口配置为ePWM输出功能。这里使用GPIO10、GPIO11的ePWM6A和ePWM6B功能,即对这两个IO口初始化,使能上拉和GPIO外设复用功能。
0 O5 r( A2 v+ q3 ?
4 ^5 c6 v6 C7 K$ H    InitEPwm6Gpio();//开启时钟,对应ePWM复用功能的开启( O4 j8 `( e' F8 b- P
13 t% z8 O9 A  P1 \; p* _* \& L- l; e
(3)初始化时基模块,即配置TB相关寄存器值(确定计数方式、周期、相位)( C) p1 U- I* _& ^# L' j; N+ X
通过配置时基模块,可以确定计数器的计数方式,周期频率,是否同步等。这里设置ePWM6计数方式为向上计数,不使用相位同步功能,计数器计数频率为系统时钟频率,计数器初值为0。$ b! q& b: ?/ V3 D! ]0 Y) Q2 T" @7 B

: ^7 |, U4 N6 q7 P3 l2 x// Setup Sync8 b# f/ v4 e+ f
    EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;  // 禁止(即不使用(输出))ePWMxSYNCO信号
+ ?4 n( Q1 f  ~; W    // Allow each timer to be sync'ed
) ]) v; [9 \0 q8 E0 V0 {1 b    EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁止TBCTR加载相位寄存器TBPHS中的值5 o0 N- @9 R* a" B, u
    EPwm6Regs.TBPHS.half.TBPHS = 0;//将相位寄存器中的值清零* J* f" x7 _( g+ V0 g3 y
    EPwm6Regs.TBCTR = 0x0000; // Clear counter时间基准计数寄存器设置为0' M# c: |! q9 ]# g" B3 @% e8 H
    EPwm6Regs.TBPRD = tbprd;//设定周期值3 `1 [# Y+ P1 M+ }
    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    // Count up向上计数模式" O) ^' n" z0 D2 l, ~3 V. \
    EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;//采用系统时钟作为TBCLK
; Z( b$ s* A' d2 t    EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;//同样是配置TBCLK的时钟
: u8 ]* @( O$ g0 m6 Y, p; ]; l+ B6 f' x* _% k
(4)初始化比较模块,配置CC相关寄存器
2 b; v( H, j4 ?" k, W通过配置CC模块,可以确定比较寄存器值的加载方式,比较器值、占空比等。这里设置ePWM6加载方式为计数器为0加载、比较器值为0。
% q1 f3 y0 p1 M( e9 x' h, r5 i& N# e5 X' c1 n
// Setup shadow register load on ZERO, ^$ m. T* ~: z
    EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// 使用影子寄存器% l3 |7 p" g/ o
    EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// 使用影子寄存器) ^! e6 |$ L1 [/ Q+ R" `: C* G/ l
    EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;//CTR等于0时加载+ K+ K3 j% R# l" C2 R$ e: ?$ Z; h
    EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
% C( o: J- T# e, i$ R: u, K" Z; Q$ _) i% ^! |: A
    // Set Compare values7 i9 Z/ u$ y: |# R. t# a" b
    EPwm6Regs.CMPA.half.CMPA = 0;    // Set compare A value3 r1 D. D5 E  K& P  L# N
    EPwm6Regs.CMPB = 0;              // Set Compare B value( ~* Z' T4 M9 Y8 x0 I; m

- ~4 o& k, j# I  S7 T; S(5)初始化动作限定模块,配置AQ相关寄存器值
6 s$ L5 h7 I# w/ }* s- ]通过配置AQ模块可以确定PWM输出波形方式等。这里配置ePWM6输出,当ePWMA计数器计数到0时输出低电平,当ePWMA计数器计数到CMPA时输出高电平;当ePWMB计数器计数到0时输出低电平,当ePWMB计数器计数到CMPA时输出高电平。
- P. q. e- e2 W% v/ s5 a+ Z) ~' x0 M* i% @/ @: p7 y2 F8 b
// Set actions
3 Q! @! E" V- B0 v    EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR;            // Set PWM1A on Zero: I" N7 n! {* C! }& m' u
    EPwm6Regs.AQCTLA.bit.CAU = AQ_SET;          // Clear PWM1A on event A, up count
4 _2 ]& c9 I. y2 y; w    EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR;            // Set PWM1B on Zero
+ o, B1 E# |. ^+ d6 I; s    EPwm6Regs.AQCTLB.bit.CBU = AQ_SET;          // Clear PWM1B on event B, up count
6 z/ O3 @3 _/ b* \
, ]* C- i, T# o  x9 f* v8 u5 i, [# R- {# [/ k* T4 N
(6)初始化事件触发模块,即配置ET相关寄存器值
' L) {% W% H# U当需要事件触发输出控制,就需要对ET相关寄存器配置。这里选择计数器计数到0时,同时使能事件触发中断,每发生一次触发事件就输出PWM。
" u) F% S. x( ~
# z+ e) @6 z% s0 Q& ?. ~    EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event. x0 S0 X& G9 C2 J1 N2 R9 Q% e6 t
    EPwm6Regs.ETSEL.bit.INTEN = 1;  // Enable INT- m( P6 p6 R3 S3 M- t- V
    EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st event每发生一次事件产生中断信号EPWM6_INT0 L; p4 e) U6 W' a* ]
8 P. H+ ?$ F9 d* D0 ]& [  N2 S, s
(7)初始化死区模块、斩波模块,即配置DB、PC相关寄存器值
3 `$ P/ _, g. ]8 p一般不对死区和斩波模块进行配置。# b% i1 N, C3 `. k! l- [7 X! _
(8)使能时基计数器时钟5 ^( u( \6 a8 C: Q' C+ o
各模块寄存器配置好后,最后开启时基计数器时钟,完成这一步,对应IO口便可以输出PWM波9 q2 M5 i  d$ K( T4 W; a' z
, ~9 t3 B5 A- U2 H
EALLOW;
) d- o  G6 t; t2 r0 p6 a/ U  ?    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced  t1 K/ e! h3 R* t
    EDIS;3 C2 s& ^" o! X( m0 w' j% Z

8 m' d. W6 v5 T& q2.通过ePWM6A和ePWM6B两个管脚输出PWM波,分别控制D6和D7指示灯亮度' L: a2 r6 \! q/ Y! H
主函数代码如下所示
! Z: z* _; q( A& @+ C& Z
' ^; S% a  w) W: J! j1 G4 V#include "DSP2833x_Device.h"     // DSP2833x HeadeRFile Include File% i7 v! \$ \: O3 T
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
. o2 N' E: ~$ G0 y, [  y( f7 S$ e
#include "leds.h"
3 P* z# A/ W8 Q#include "time.h"//在定时器中控制灯的闪烁! Q; t; D9 G* O5 S. ~  B# S
#include "epwm.h"//存放PWM的驱动程序- O8 \, F6 u0 ~: _" w; r
void main()
$ j: d( }' q2 U# i" i7 G7 y' u  K& z9 `{6 u, ?/ g+ v6 o4 z& V' A
    int i=0;; E5 e+ p* C0 o3 |' H' H( m# {' d
    unsigned char fx=0;//fx指示了一个方向2 z; j, Z4 [7 @$ s7 f  ^. P+ g
: p5 X8 [5 Y9 s6 u
    InitSysCtrl();8 o4 o9 p5 a. S* e. v4 J1 ?

! @: n5 T4 `$ G  Y+ e+ J; F! [! i    InitPieCtrl();: ^! ^% |( c1 p7 I# C5 U' J
    IER = 0x0000;( l% L. _2 I8 W
    IFR = 0x0000;, }; o6 ^8 D& \# p( `! g& _
    InitPieVectTable();+ g. J: O% M; a% N  q5 Z

2 h7 D7 [7 ^8 M1 F3 b/ ^" i, k1 {+ ?//    LED_Init();
) \6 e/ h3 \. i- j) M    EPWM6_Init(500);//EPWM管脚也即控制了LED,也就是说周期值是500个系统时钟
+ F" v0 e! X. x& n
: n+ O8 g0 Z' `8 X    while(1)
& e: r9 H0 s  b) X" o: R+ S    {- @! c6 `2 |* C0 z' r4 b: V- v
        if(fx==0)
9 p8 u$ P9 Y* F# O: g1 P8 K        {
* r; g. g. F5 V. h* L! F" ^& R            i++;
) N/ Q" |4 A" d4 o; D            if(i==300)% K: X" t2 F  R6 ~
            {* b, z% C/ ?  Z
                fx=1;, C, s3 k& F1 p+ u/ D! \- s8 Q
            }2 |3 }; B6 v, ?( X; g2 m
        }" X+ u& T2 P. H: l  K
        else
3 T+ ]/ k: q4 r/ @6 X        {
1 [: o  A  t1 `            i--;
& X& Q( P+ e, S            if(i==0)2 A* g! h' |4 R9 }% \1 e
            {
, P- _3 [9 R- t" Z4 t. @: b                fx=0;
) q/ }) w3 ?1 J3 m" l2 w3 x% O  z  P            }) E. O- r# t' J! @: {( N/ `8 T
        }* ]: |- q8 M9 c6 p/ r  m" u% m
        EPwm6A_SetCompare(i);  //i值最大可以取499,因为ARR最大值是499.
5 Q. G4 K' H/ M' x+ X& E- J3 }        EPwm6B_SetCompare(300-i);  //i值最大可以取499,因为ARR最大值是499.
4 n( x# ^: [& n7 g        DELAY_US(10*1000);
7 x9 k: J& ?8 s4 ~# m. Z    }7 {( I1 T! s' T# I0 t, l
}0 C+ K- B* o& H, m
1 u( I# ~. i$ H

- D5 m0 l0 L' j* f- o

该用户从未签到

2#
发表于 2021-12-13 14:29 | 只看该作者
初始化要配置相关寄存器值

该用户从未签到

3#
发表于 2021-12-13 14:29 | 只看该作者
通过配置CC模块,可以确定比较寄存器值的加载方式
  • TA的每日心情
    开心
    2023-5-17 15:19
  • 签到天数: 1 天

    [LV.1]初来乍到

    4#
    发表于 2021-12-17 19:41 | 只看该作者
    PWM波用处非常多可以调节呼吸灯' r$ |. [; d3 ~) h% T

    该用户从未签到

    5#
    发表于 2021-12-22 18:36 | 只看该作者
    感觉很厉害
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-6-22 20:34 , Processed in 0.062500 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表