我正在尝试使用 Code Composer 实现周期为5秒的 PWM。 但是、我有 C 2000 Ware 软件开发套件示例13_up。 我无法更改此示例的周期或频率。 此示例值为:
TBPRD 2000
CMPA 1950
CMPA 50.
CMPB 1950
CMPB 50.
可以帮帮我吗? 我必须使 PWM 具有5秒的周期。
所有代码:
//######################################################################################################################
//
//文件: epwm_ex13_up_aq.c
//
//标题: 操作限定符模块-使用向上计数。
//
//! \addtogroup driver_example_list
//!
ePWM 操作限定符(ePWM_UP_AQ)
//!
//! 此示例将 ePWM1、ePWM2、ePWM3配置为生成
//! 在 EPWMxA 和上进行独立调制时的波形
//! EPWMxB。
//!
//! 比较值 CMPA 和 CMPB 在 ePWM 的 ISR 内进行修改。
//!
//! 在本示例中、TB 计数器处于向上计数模式。
//!
//! 查看 EPWM1A/B (GPIO0和 GPIO1)、EPWM2A/B (GPIO2和 GPIO3)
//! 和 EPWM3A/B (GPIO4和 GPIO5)波形。
//!
//
//######################################################################################################################
//
//$Release Date: $
//版权所有:
//版权所有(C) 2013-2022 Texas Instruments Incorporated - http://www.ti.com/
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
// 重新分发源代码必须保留上述版权
// 注意、此条件列表和以下免责声明。
//
// 二进制形式的重新分发必须复制上述版权
// 注意、中的条件列表和以下免责声明
// 随提供的文档和/或其他材料
// 分布。
//
// 德州仪器公司的名称和的名称都不是
// 其贡献者可用于认可或推广衍生产品
// 未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//$
//######################################################################################################################
//
//包含的文件
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
//
//定义
//
#define EPWM1_TIMER_TBPRD 2000 //周期寄存器
#define EPWM1_MAX_CMPA 1950
#define EPWM1_MIN_CMPA 50
#define EPWM1_MAX_CMPB 1950
#define EPWM1_MIN_CMPB 50.
#define EPWM2_TIMER_TBPRD 2000 //周期寄存器
#define EPWM2_MAX_CMPA 1950
#define EPWM2_MIN_CMPA 50.
#define EPWM2_MAX_CMPB 1950
#define EPWM2_MIN_CMPB 50.
#define EPWM3_TIMER_TBPRD 2000 //周期寄存器
#define EPWM3_MAX_CMPA 950
#define EPWM3_MIN_CMPA 50.
#define EPWM3_MAX_CMPB 1950
#define EPWM3_MIN_CMPB 1050
#define ePWM_CMP_UP 1
#define ePWM_CMP_DOWN 0
//
//全局
//
typedef 结构
{
uint32_t epwmModule;
uint16_t epwmCompADirection;
uint16_t epwmCompBDirection;
uint16_t epwmTimerIntCount;
uint16_t epwmMaxCompA;
uint16_t epwmMinCompA;
uint16_t epwmMaxCompB;
uint16_t epwmMinCompB;
} epwmInfo;
epwmInfo epwm1Info;
epwmInfo epwm2Info;
epwmInfo epwm3Info;
//volatile = kod tarafından herhangi bir işlem yapılmadan herhangi bir zamanda değişebileceğini söyleyen bir niteleyicidir。
volatile uint16_t compAVal、compBVal;
//
// 函数原型
//
void initEPWM1 (void);
void initEPWM2 (void);
void initEPWM3(void);
_interrupt void epwm1ISR (void);
_interrupt void epwm2ISR (void);
_interrupt void epwm3ISR (void);
void updateCompare (epwmInfo*);
//
//主函
//
void main (void)
{
//
//初始化设备时钟和外设
//
device_init();
//
//禁用引脚锁定并启用内部上拉。
//
DEVICE_initGPIO();
//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();
//
//在这种情况下、只需初始化 ePWM1、ePWM2、ePWM3的 GPIO 引脚
//
Board_init();
//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//
INTERRUPT_REGISTER (INT_EPWM1、epwm1ISR);
INTERRUPT_REGISTER (INT_EPWM2、epwm2ISR);
INTERRUPT_REGISTER (INT_EPWM3、epwm3ISR);
//
//禁用同步(也冻结 PWM 的时钟)
//它们将不会运行或对寄存器读取/写入做出响应。
SYSCTL_DisablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
initEPWM1();
initEPWM2();
initEPWM3();
//
//启用到 PWM 的同步和时钟
//
//它们 将运行或响应寄存器读取/写入。
SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
//
//启用此示例所需的中断
//
INTERRUPT_ENABLE (INT_EPWM1);
INTERRUPT_ENABLE (INT_EPWM2);
INTERRUPT_ENABLE (INT_EPWM3);
//
//启用全局中断和更高优先级的实时调试事件:
//
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM
//
//空闲循环。 只需坐下来循环(可选):
//
for (;;)
{
//微控制器 çalışma süresi ne ise bir cycle süresince bekleme yapar。
ASM (" NOP");//NOP =无操作
}
}
//
// epwm1ISR -用于更新比较值的 EPWM1 ISR
//
_interrupt void epwm1ISR (void)
{
//
//更新 CMPA 和 CMPB 值
//
// updateCompare -更新指定 ePWM 的比较值
updateCompare (epwm1Info);
//
//清除此计时器的 INT 标志
//此函数清除 ePWM 中断标志。
ePWM_clearEventTriggerInterruptFlag (myEPWM1_base);
//
//确认此中断以接收来自组3的更多中断
//
//! 指定的中断组被确认并清除相应组内的任何中断标志。
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_Group3);
}
//
// epwm2ISR -用于更新比较值的 EPWM2 ISR
//
_interrupt void epwm2ISR (void)
{
//
//更新 CMPA 和 CMPB 值
//
updateCompare (&epwm2Info);
//
//清除此计时器的 INT 标志
//
ePWM_clearEventTriggerInterruptFlag (myEPWM2_base);
//
//确认此中断以接收来自组3的更多中断
//
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_Group3);
}
//
// epwm3ISR -用于更新比较值的 EPWM3 ISR
//
_interrupt void epwm3ISR (void)
{
//
//更新 CMPA 和 CMPB 值
//
updateCompare (&epwm3Info);
//
//清除此计时器的 INT 标志
//
ePWM_clearEventTriggerInterruptFlag (myEPWM3_base);
//
//确认此中断以接收来自组3的更多中断
//
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_Group3);
}
//
// initEPWM1 -初始化 EPWM1值
//
空 initEPWM1()
{
//
//设置 TBCLK
//
ePWM_setTimeBaseCounterMode (myEPWM1_base、ePWM_COUNTER_MODE_UP);
ePWM_setTimeBasePeriod (myEPWM1_base、EPWM1_TIMER_TBPRD);
ePWM_DisablePhaseShiftLoad (myEPWM1_base);
ePWM_setPhaseShift (myEPWM1_base、0U);
ePWM_setTimeBaseCounter (myEPWM1_base、0U);//此函数设置时基计数器的16位计数器值。
//
//设置 ePWM 时钟预分频器
//
//输出时钟的公式为:
//TBCLK = EPWMCLK/(highSpeedPrescaler *预分频器)
ePWM_setClockPrescaler (myEPWM1_base、
ePWM_CLOCK 分频器_2、
ePWM_HSCLOCK_DEVIDER_2);
//
//将影子寄存器加载设置为零
//
//此函数启用和设置计数器比较影子加载模式。
EPWM_setCounterCompareShadowImage LoadMode (myEPWM1_base、
ePWM_COUNTER_COMPARE_A、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowImage LoadMode (myEPWM1_base、
ePWM_COUNTER_COMPARE_B、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
//
//设置比较值
//
//此函数设置计数器比较寄存器的计数器比较值。
// compCount 的最大值为0xFFFF。 ????????????
ePWM_setCounterCompareValue (myEPWM1_base、ePWM_COUNTER_COMPARE_A、
EPWM1_MIN_CMPA);
ePWM_setCounterCompareValue (myEPWM1_base、ePWM_COUNTER_COMPARE_B、
EPWM1_MIN_CMPB);
//
//设置 ePWM1A 和 ePWM1B 的操作
//
//将 PWM1A 设置为零
ePWM_setActionQualifierAction (myEPWM1_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_zero);
//在事件 A 上清除 PWM1A,向上计数
ePWM_setActionQualifierAction (myEPWM1_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_up_CMPA);
//将 PWM1B 置为零
ePWM_setActionQualifierAction (myEPWM1_base、
ePWM_AQ_OUTPUT _B、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_zero);
//在事件 B 上清除 PWM1B,向上计数
ePWM_setActionQualifierAction (myEPWM1_base、
ePWM_AQ_OUTPUT _B、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_up_CMPB);
//
//中断,我们将在其中更改比较值
//
ePWM_setInterruptSource (myEPWM1_base、ePWM_INT_TBCTR_ZERO);
ePWM_enableInterrupt (myEPWM1_base);
ePWM_setInterruptEventCount (myEPWM1_base、3U);//??????
//
//此示例用于跟踪的信息
CMPA/CMPB 值的方向//
//移动、最小和最大允许值和
//指向正确 ePWM 寄存器的指针
//
//首先增大 CMPA & CMPB
epwm1Info.epwmCompADirection = ePWM_CMP_UP;
epwm1Info.epwmCompBDirection = ePWM_CMP_UP;
//清除中断计数器
epwm1Info.epwmTimerIntCount = 0;
//将 base 设置为 ePWM1
epwm1Info.epwmModule = myEPWM1_base;
//设置最小值/最大 CMPA/CMP 值
epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA;
epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA;
epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB;
epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB;
}
//
// initEPWM2 -初始化 EPWM2值
//
空 initEPWM2()
{
//
//设置 TBCLK
//
ePWM_setTimeBaseCounterMode (myEPWM2_base、ePWM_COUNTER_MODE_UP);
ePWM_setTimeBasePeriod (myEPWM2_base、EPWM2_TIMER_TBPRD);
ePWM_DisablePhaseShiftLoad (myEPWM2_base);
ePWM_setPhaseShift (myEPWM2_base、0U);
ePWM_setTimeBaseCounter (myEPWM2_base、0U);
//
//设置 ePWM 时钟预分频器
//
f (myEPWM2_base、
ePWM_CLOCK 分频器_2、
ePWM_HSCLOCK_DEVIDER_2);
//
//将影子寄存器加载设置为零
//
EPWM_setCounterCompareShadowImage LoadMode (myEPWM2_base、
ePWM_COUNTER_COMPARE_A、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowImage LoadMode (myEPWM2_base、
ePWM_COUNTER_COMPARE_B、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
//
//设置比较值
//
ePWM_setCounterCompareValue (myEPWM2_base、ePWM_COUNTER_COMPARE_A、
EPWM2_MIN_CMPA);
ePWM_setCounterCompareValue (myEPWM2_base、ePWM_COUNTER_COMPARE_B、
EPWM2_MAX_CMPB);
//
//设置 ePWM1A 和 ePWM1B 的操作
//
//清除 PWM2A 导通周期并在事件 A 上设置、递增计数
ePWM_setActionQualifierAction (myEPWM2_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_period);
ePWM_setActionQualifierAction (myEPWM2_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_up_CMPA);
//清除 PWM2B 开启周期并设置事件 B、递增计数
ePWM_setActionQualifierAction (myEPWM2_base、
ePWM_AQ_OUTPUT _B、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_period);
ePWM_setActionQualifierAction (myEPWM2_base、
ePWM_AQ_OUTPUT _B、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_up_CMPB);
//
//中断,我们将在其中更改比较值
//
ePWM_setInterruptSource (myEPWM2_base、ePWM_INT_TBCTR_ZERO);
ePWM_enableInterrupt (myEPWM2_base);
ePWM_setInterruptEventCount (myEPWM2_base、3U);
//
//此示例用于跟踪的信息
CMPA/CMPB 值的方向//
//移动、最小和最大允许值和
//指向正确 ePWM 寄存器的指针
//
//首先增大 CMPA &减小 CMPB
epwm2Info.epwmCompADirection = ePWM_CMP_UP;
epwm2Info.epwmCompBDirection = ePWM_CMP_DOWN;
//清除中断计数器
epwm2Info.epwmTimerIntCount = 0;
//将 base 设置为 ePWM2
epwm2Info.epwmModule = myEPWM2_base;
//设置最小值/最大 CMPA/CMP 值
epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA;
epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA;
epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB;
epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB;
}
//
// initEPWM3 -初始化 EPWM3值
//
空 initEPWM3 (空)
{
//
//设置 TBCLK
//
ePWM_setTimeBaseCounterMode (myEPWM3_base、ePWM_COUNTER_MODE_UP);
ePWM_setTimeBasePeriod (myEPWM3_base、EPWM3_TIMER_TBPRD);
ePWM_DisablePhaseShiftLoad (myEPWM3_base);
ePWM_setPhaseShift (myEPWM3_base、0U);
ePWM_setTimeBaseCounter (myEPWM3_base、0U);
//
//设置 ePWM 时钟预分频器
//
ePWM_setClockPrescaler (myEPWM3_base、
ePWM_CLOCK 分频器_1、
ePWM_HSCLOCK_DEVIDER_1);
//
//将影子寄存器加载设置为零
//
EPWM_setCounterCompareShadowImage LoadMode (myEPWM3_base、
ePWM_COUNTER_COMPARE_A、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowImage LoadMode (myEPWM3_base、
ePWM_COUNTER_COMPARE_B、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
//
//设置比较值
//
ePWM_setCounterCompareValue (myEPWM3_base、ePWM_COUNTER_COMPARE_A、
EPWM3_MIN_CMPA);
ePWM_setCounterCompareValue (myEPWM3_base、ePWM_COUNTER_COMPARE_B、
EPWM3_MAX_CMPB);
//
//设置 ePWM1A 和 ePWM1B 的操作
//
//在事件 B 上设置 PWM3A、在事件 B 上进行上数和清零、进行上数
ePWM_setActionQualifierAction (myEPWM3_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_up_CMPA);
//时基计数器递增等于 COMPA = EPPWM_AQ_OUTPSIT_ON_TIMEBASE_UP_CMPA
ePWM_setActionQualifierAction (myEPWM3_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_up_CMPB);
//时基计数器递增等于 COMPB = ePWM_AQ_OUTPUT ON_TIMEBASE_UP_CMPB
//在计数器=零时切换 EPWM3B
ePWM_setActionQualifierAction (myEPWM3_base、
ePWM_AQ_OUTPUT _B、
ePWM_AQ_OUTPUT 切换、
ePWM_AQ_output_on_timebase_zero);
//
//中断,我们将在其中更改比较值
//
ePWM_setInterruptSource (myEPWM3_base、ePWM_INT_TBCTR_ZERO);
ePWM_enableInterrupt (myEPWM3_base);
ePWM_setInterruptEventCount (myEPWM3_base、3U);
//
//此示例用于跟踪的信息
CMPA/CMPB 值的方向//
//移动、最小和最大允许值和
//指向正确 ePWM 寄存器的指针
//
//首先增大 CMPA &减小 CMPB
epwm3Info.epwmCompADirection = ePWM_CMP_UP;
epwm3Info.epwmCompBDirection = ePWM_CMP_UP;
//从0开始计数
epwm3Info.epwmTimerIntCount = 0;
//将 base 设置为 ePWM1
epwm3Info.epwmModule = myEPWM3_base;
//设置最小值/最大 CMPA/CMP 值
epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA;
epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA;
epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB;
epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB;
}
//
// updateCompare -更新指定 ePWM 的比较值
//
void updateCompare (epwmInfo * ePWM_INFO)
{
//
//每隔10个中断、更改 CMPA/CMPB 值
//
if (ePWM_INFO->epwmTimerIntCount = 10)
{
ePWM_INFO->epwmTimerIntCount = 0;
compAVal = ePWM_getCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_A);
compBVal = ePWM_getCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_B);
//
//如果我们增加 CMPA,请检查是否
//我们达到了最大值。 如果不是、请增大 CMPA
//否则、更改方向并减小 CMPA
//
if (ePWM_INFO->epwmCompADirection =ePWM_CMP_UP)
{
if (compAVal < EPWM_INFO->epwmMaxCompA)
{
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_A、++COMPAVal);
}
其他
{
ePWM_INFO->epwmCompADirection = ePWM_CMP_DOWN;
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_A、--compAVal);
}
}
//
//如果我们降低了 CMPA,请检查是否
//我们达到最小值。 如果不是、请减小 CMPA
//否则,更改方向并增加 CMPA
//
其他
{
if (compAVal == ePWM_INFO->epwmMinCompA)
{
ePWM_INFO->epwmCompADirection = ePWM_CMP_UP;
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_A、++COMPAVal);
}
其他
{
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_A、--compAVal);
}
}
//
//如果我们增加 CMPB,请检查是否
//我们达到了最大值。 如果不是、则增加 CMPB
//否则、更改方向并减小 CMPB
//
if (ePWM_INFO->epwmCompBDirection =ePWM_CMP_UP)
{
if (compBVal < EPWM_INFO->epwmMaxCompB)
{
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_B、+compBVal);
}
其他
{
ePWM_INFO->epwmCompBDirection = ePWM_CMP_DOWN;
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_B、--compBVal);
}
}
//
//如果我们降低 CMPB,请检查是否
//我们达到最小值。 如果不是、减小 CMPB
//否则、更改方向并增加 CMPB
//
其他
{
if (compBVal =ePWM_INFO->epwmMinCompB)
{
ePWM_INFO->epwmCompBDirection = ePWM_CMP_UP;
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_B、+compBVal);
}
其他
{
ePWM_setCounterCompareValue (ePWM_INFO->epwmModule、
ePWM_COUNTER_COMPARE_B、--compBVal);
}
}
}
//
//如果< 10、则递增中断计数
//
其他
{
ePWM_INFO->epwmTimerIntCount++;
}
返回;
}
//
//文件结束
//