步骤一:创建自己的头文件和源文件
名字必须由【英文字母/数字/英文符号】组成,后缀(.c)是必须的
结果
步骤2:在自己的源文件中编写(空白的)函数
//文件类型:源文件
//文件名:InitEPWM_MY.c
//在源文件中,编写具体的函数代码
//在头文件中,声明相应的需要用到的函数
#include "F28x_Project.h"
#include "F2837xS_device.h"
#include "math.h"
//函数功能:初始化EPWM
void InitEPWM_MY()
{
//此处编写具体执行的代码
}
//文件类型:头文件
//文件名:MY_headers.h
//在源文件中,编写具体的函数代码
//在头文件中,声明相应的需要用到的函数
//函数功能:初始化EPWM
void InitEPWM_MY(void);
步骤3:设置【properties】
3.1:打开【properties】
3.2:【properties】中添加【头文件】
3.3:build
步骤4:main
4.1在main文件,最前面,添加代码:
#include "MY_headers.h"//声明需要用到这个头文件
4.2在main函数中,添加一行代码:
InitEPWM_MY();
即可调用【InitEPWM_MY()】函数,当然,现在里面是空的
备注:按住Ctrl键,鼠标左键点击某函数,即可跳转
#include "F28x_Project.h"
#include "F2837xS_device.h"
#include "math.h"
#include "MY_headers.h"//此处新增
int EPWM6_CMP=1562;
int EPWM7_CMP=1562;
int EPWM8_CMP=1562;
void main(void)
{
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
//该指令为解决调用DELAY_US()函数会进入死循环中断的BUG;
InitSysCtrl();//初始化控制系统。
//1)关闭看门狗。2)初始化PLL,确定系统主时钟。3)初始化外设时钟。
DINT;//汇编指令:关闭中断
InitPieCtrl();//初始化pie控制寄存器
EALLOW;//汇编指令:受保护的寄存器可写入
IER = 0x0000;//关闭CPU中断并清除所有CPU中断信号
IFR = 0x0000;
EDIS;//汇编指令:受保护的寄存器禁止写入
InitPieVectTable();//初始化PIE
InitGpio(); //初始化GPIO
//以下寄存器配置
GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 0);//启用【第一个CPU】的【33号GPIO】的【第一个功能】
GPIO_SetupPinMux(34, GPIO_MUX_CPU1, 0);//
GPIO_SetupPinOptions(33, GPIO_OUTPUT, GPIO_OPENDRAIN);//把【GPIO33】设置为【输出模式】+【开漏模式】
GPIO_SetupPinOptions(34, GPIO_OUTPUT, GPIO_PUSHPULL);//把【GPIO34】设置为【输出模式】+【推挽模式】
GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(17, GPIO_OUTPUT, GPIO_PUSHPULL);
GPIO_WritePin(17, 0);//PWM_EN
/*
#define GPIO_PUSHPULL 0 推挽模式
#define GPIO_PULLUP (1 << 0) 上拉模式
#define GPIO_INVERT (1 << 1) 翻转模式
#define GPIO_OPENDRAIN (1 << 2) 开漏模式
#define GPIO_PULLUP|GPIO_ASYNC 上拉模式(不要让输入悬空)和异步模式
*/
InitEPWM_MY();//此处新增
for(;;)
{
DELAY_US(500000);//延时
GPIO_WritePin(33, 1);//输出高电平,灭
GPIO_WritePin(34, 1);//
DELAY_US(500000);//延时
GPIO_WritePin(33, 0);//输出低电平,亮
GPIO_WritePin(34, 0);//
}
}
步骤5:编写【InitEPWM_MY()】函数
强烈建议参考TI官方例程
例如:
【C:\ti\controlSUITE\device_support\F2837xS\v210\F2837xS_examples_Cpu1\epwm_updown_aq】
位置:【C:\ti\controlSUITE\device_support\F2837xS\】另有多个文件夹【F2837xS_examples_Cpu1】,内含超多不同模块的例程
//文件类型:源文件
//文件名:InitEPWM_MY.c
//在源文件中,编写具体的函数代码
//在头文件中,声明相应的需要用到的函数
#include "F28x_Project.h"
#include "F2837xS_device.h"
#include "math.h"
extern int EPWM6_CMP;//决定epwm周期内的占空比
extern int EPWM7_CMP;
extern int EPWM8_CMP;
//
// Defines
//
#define EPwm6_TIMER_TBPRD 1563 // Period register
//决定epwm6发生波形的周期,在UP模式下,总周期=TBPRD,
//在UPDOWM模式下,周期=TBPRD*2-1
#define EPwm7_TIMER_TBPRD 1563 // Period register
#define EPwm8_TIMER_TBPRD 1563 // Period register
void InitEPwm6Example(void);//初始化,由于本函数(InitEPwm6Example)写在最后,在文件前端预先声明
void InitEPwm7Example(void);
void InitEPwm8Example(void);
//函数功能:初始化EPWM
void InitEPWM_MY()
{
EPWM6_CMP=500;
EPWM7_CMP=1000;
EPWM8_CMP=1500;
CpuSysRegs.PCLKCR2.bit.EPWM6=1;
CpuSysRegs.PCLKCR2.bit.EPWM7=1;
CpuSysRegs.PCLKCR2.bit.EPWM8=1;
InitEPwm6Gpio();//官方函数:启用epwm6
InitEPwm7Gpio();
InitEPwm8Gpio();
//
// For this example, only initialize the ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm6Example();//需自己修改,具体参数配置
InitEPwm7Example();
InitEPwm8Example();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;//开启时基计数器时钟
EDIS;
}
void InitEPwm6Example()
{
//
// Setup TBCLK
//
EPwm6Regs.TBPRD = EPwm6_TIMER_TBPRD; // Set timer period 801 TBCLKs=设置周期值=1k=20μs
EPwm6Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0=相移值 置零
EPwm6Regs.TBCTR = 0x0000; // Clear counter=计数器的值 置零
//
// Set Compare values==设置计数比较器
//
EPwm6Regs.CMPA.bit.CMPA = EPWM6_CMP;
// Set compare A value=设置CMPA比较寄存器A的值,当计数器的值==CMPA时,发生动作
//
// Setup counter mode==计数模式
//
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
// Count up and down==计数模式==UPDOWN
// EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
// EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading// 禁止相移值装载到计数器
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT==与SYSCLKOUT的时钟比率==高速时钟预分频为1 TBCLK=100MHz
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟预分频为1,
//epwm运行频率==TBCLK=SYSCKOUT/(HSPCLKDIV*CLKDIV)=100MHz/(1*1)=100MHz.
//ePWM频率计算方法
//在updown模式下:F(ePWM)=TBCLK/(2*TBPRD-1)=100,000,000/(2*1563-1)==32,000Hz
//在up模式下:F(ePWM)=TBCLK/(TBPRD)=100,000,000/(1563)==64,000Hz
//
// Setup shadowing== 影子模式==设置装载模式功能
//
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
// Set actions==设置动作功能==在【时刻点】进行【动作】//重要!
//
/*
* 时刻点优先级:不同计数模式(UP/DOWM/UPDOWN)下,
* 同时发生两个时刻点事件,优先度有差异,例如CBD>CAD
*
* 寄存器【EPwm6Regs.AQCTLA.bit.】中,有以下几个位,
* 分别代表着对应的时刻点:
CAD,比较点。CTR==CMPA的时刻&&处于向下计数阶段。
CAU,比较点。CTR==CMPA的时刻&&处于向上计数阶段。
CBD,比较点。CTR==CMPB的时刻&&处于向上计数阶段。
CBU,比较点。CTR==CMPB的时刻&&处于向上计数阶段。
PRD==周期结束点
ZRO==零点
*
* 把某位的值写为【0/1/2/3】,意为在这个时刻点,
* epwm输出的电平【无动作/置低电平/置高电平/翻转】
动作:
AQ_NO_ACTION 0x0==无动作
AQ_CLEAR 0x1==置低电平
AQ_SET 0x2==置高电平
AQ_TOGGLE 0x3==翻转
*
*/
EPwm6Regs.AQCTLA.bit.ZRO = 1; //零点==下拉
EPwm6Regs.AQCTLA.bit.CAU = 2; //CTR==CMPA的时刻&&处于向上计数阶段,上拉。
EPwm6Regs.AQCTLA.bit.CAD = 1; //CTR==CMPA的时刻&&处于向下计数阶段,下拉
EPwm6Regs.AQCTLA.bit.PRD = 0; //终点==无动作
//以下设置死区模块
//死区参数//以下“上升沿“、”下降沿”描述,只针对CTR==CMPA的动作产生的电平转换,不包括CTR==0产生的动作。
#define DB_IN_A 0 //上下均输入A
#define DB_IN_A_UP_B_DOWN 2 //上升沿输入A,下降沿输入B
#define DB_IN_B_UP_A_DOWN 1 //上升沿输入B,下降沿输入A
#define DB_IN_B 3 //上下均输入B
#define DB_SEL_0 0 //不翻转
#define DB_SEL_A_F 1 //A翻转
#define DB_SEL_B_F 2 //B翻转
#define DB_SEL_A_B_F 3 //AB都翻转
#define DB_OUT_0 0 //上下沿都不延时
#define DB_Y_DOWN 1 //下降沿延时
#define DB_Y_UP 2 //上升沿延时
#define DB_Y_UP_DOWN 3 //上下沿都延时
//设置死区模块==建议用示波器查看各寄存器被改成各值,会有什么效果
EPwm6Regs.DBCTL.bit.IN_MODE = DB_IN_A ; //上下均输入A
EPwm6Regs.DBCTL.bit.POLSEL = DB_SEL_B_F; //EPWMB,翻转
EPwm6Regs.DBCTL.bit.OUT_MODE = DB_Y_UP_DOWN; // 双边沿,都延时
EPwm6Regs.DBRED.bit.DBRED = 100; //上升沿延时100个时钟周期=1us
EPwm6Regs.DBFED.bit.DBFED = 100; //下升沿延时100个时钟周期=1us
}
void InitEPwm7Example()
{
EPwm7Regs.TBPRD = EPwm7_TIMER_TBPRD;
EPwm7Regs.TBPHS.bit.TBPHS = 0x0000;
EPwm7Regs.TBCTR = 0x0000;
EPwm7Regs.CMPA.bit.CMPA = EPWM7_CMP;
EPwm7Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm7Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm7Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm7Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm7Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm7Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm7Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm7Regs.AQCTLA.bit.ZRO = 1; //零点==下拉
EPwm7Regs.AQCTLA.bit.CAU = 2; //向上计数时, CMPA点
EPwm7Regs.AQCTLA.bit.CAD = 1; //向下计数时,CMPA点
EPwm7Regs.AQCTLA.bit.PRD = 0; //终点
EPwm7Regs.DBCTL.bit.IN_MODE = DB_IN_A ;
EPwm7Regs.DBCTL.bit.POLSEL = DB_SEL_B_F;
EPwm7Regs.DBCTL.bit.OUT_MODE = DB_Y_UP_DOWN;
EPwm7Regs.DBRED.bit.DBRED = 100;
EPwm7Regs.DBFED.bit.DBFED = 100;
}
void InitEPwm8Example()
{
EPwm8Regs.TBPRD = EPwm8_TIMER_TBPRD;
EPwm8Regs.TBPHS.bit.TBPHS = 0x0000;
EPwm8Regs.TBCTR = 0x0000;
EPwm8Regs.CMPA.bit.CMPA = EPWM8_CMP;
EPwm8Regs.CMPB.bit.CMPB = EPWM8_CMP;
EPwm8Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm8Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm8Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm8Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm8Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm8Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm8Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm8Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm8Regs.AQCTLA.bit.ZRO = 1; //零点==下拉
EPwm8Regs.AQCTLA.bit.CAU = 2; //向上计数时, CMPA点
EPwm8Regs.AQCTLA.bit.CAD = 1; //向下计数时,CMPA点
EPwm8Regs.AQCTLA.bit.PRD = 0; //终点
EPwm8Regs.DBCTL.bit.IN_MODE = DB_IN_A ;
EPwm8Regs.DBCTL.bit.POLSEL = DB_SEL_B_F;
EPwm8Regs.DBCTL.bit.OUT_MODE = DB_Y_UP_DOWN;
EPwm8Regs.DBRED.bit.DBRED = 100;
EPwm8Regs.DBFED.bit.DBFED = 100;
}