【LAUNCHXL-F280049C】③eCAP、PWM模块测试及电机测速小试牛刀-电子产品世界论坛
接上贴,搞定eCAP、ePWM,就迫不及待地想攻克下一个模块,想来想去,那就CLB可配置逻辑块吧。
毕竟本开发板地CPU型号:TMS320F280049C中的C就特别突出具备CLB可配置逻辑块功能。
C2000系列中的CLB 模块:本质是将FPGA 的一些功能集成到了DSP 当中,其最大的好处是能够对EPWM、ECAP、EQEP 及外部输入部分信号进行逻辑处理,将输出的信号给到EPWM、XBAR 以及别的模块当中。这使得工程师们在利用单片DSP 的情况下,有更大的自由度去实现一些复杂的逻辑,减少外围的逻辑门。

简单说来,就是C2000 MCU +小型FPGA,用这个小型FPGA实现一些需要高速响应的功能,不仅实时性更强,而且不占用CPU。
【说点题外话】
CLB并不是仅有TI一家,另一家MCU巨头Microchip,也在2024年发表了具备CLB功能的MCU(8位):PIC16F13145

由于CLB的运行不依赖于CPU的时钟速度,因此能改善系统的延迟,并提供低功耗解决方案。CLB可用于在CPU休眠模式下做出逻辑决策,从而进一步降低功耗和软件依赖性。PIC16F13145 MCU还包括一个具有内置计算功能的快速10位模数转换器(ADC)、一个8位数模转换器 (DAC)、快速比较器、8位和16位定时器以及串行通信模块(I2C和SPI),从而可以在没有CPU的情况下执行许多系统级任务。该系列将提供从8引脚到20引脚的各种封装。
下面是Microchip的CLB图形化配置界面,非常像小型FPGA有木有?我们待会看下TI的CLB怎么配置。

我们首先新建一个项目,选择官方例程:clb_ex8_external_signal_AND_gate

看程序介绍,我们就明白了程序要完成一个简单的AND与门。

逻辑功能如下图所示:

他的main主程序非常简单,就只有
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB1);initTILE1(myCLBTILE1_BASE);CLB_enableCLB(myCLBTILE1_BASE);
#include "driverlib.h"
#include "device.h"
#include "clb_config.h"
#include "clb.h"
#include "board.h"
void main(void)
{
Device_init();
Device_initGPIO();
Interrupt_initModule();
Interrupt_initVectorTable();
//
// Enabling CLB1
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB1);
Board_init();
initTILE1(myCLBTILE1_BASE);
CLB_enableCLB(myCLBTILE1_BASE);
while(1)
{
asm(" NOP");
}
}其实他的功能就在sysconfig界面中设置完成。
首先IO输入输出在GPIO/INPUT XBAR/OUTXBAR中设置

OUTXBAR中将输出IO与CLB1 OUT产生关联。

CLB模块主要设置INPUT信号

最重要的逻辑功能在Tile Design中实现。
Logic Equation : i0 & i1,就实现了一个简单的AND与门功能。

硬件部分,我们在GPIO0与GPIO1接入电阻上拉的按键。
(为简单起见,使用了一块瑞萨开发板,仅使用VCC GND及按键1——GPIO0、按键2——GPIO1)
按下按键1或者2,AND输出GPIO34=0,由于LED是上拉,此时灯点亮。

编译调试后就可以运行了。

接下来,难度加大一点,输入不用GPIO了,用ePWM(周期2秒),使用简单的非门,驱动LED5.
实现的效果是每秒中闪烁LED5。
在上述例程的基础上,直接修改CLB,CLB input 0 设置EPWM3A。

Tile Design中将逻辑修改为非门:!i0

接下来还有在主程序中设置ePWM,使其输出为周期2秒的方波。
#include "driverlib.h"
#include "device.h"
#include "clb_config.h"
#include "clb.h"
#include "board.h"
#define PWM3_TIMER_MIN 100000000000U
#define PWM3_TIMER_MAX 8000U
#define EPWM_TIMER_UP 1U
#define EPWM_TIMER_DOWN 0U
uint32_t ecap1IntCount;
uint32_t ecap1PassCount;
uint32_t epwm3TimerDirection;
volatile uint32_t cap2Count;
volatile uint32_t cap3Count;
volatile uint32_t cap4Count;
volatile uint16_t epwm3PeriodCount;
//
// Function Prototypes
//
void error(void);
void initECAP(void);
void initEPWM(void);
void main(void)
{
Device_init();
Device_initGPIO();
Interrupt_initModule();
Interrupt_initVectorTable();
GPIO_setPadConfig(4,GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_4_EPWM3_A);
GPIO_setPadConfig(5,GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_5_EPWM3_B);
//
// Enabling CLB1
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB1);
Board_init();
initEPWM();
initTILE1(myCLBTILE1_BASE);
CLB_enableCLB(myCLBTILE1_BASE);
while(1)
{
asm(" NOP");
}
}
//
// initEPWM - Configure ePWM
//
void initEPWM()
{
//
// Disable sync(Freeze clock to PWM as well)
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Configure ePWM
// Counter runs in up-count mode.
// Action qualifier will toggle output on period match
//
EPWM_setTimeBaseCounterMode(EPWM3_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(EPWM3_BASE, PWM3_TIMER_MIN);
EPWM_setPhaseShift(EPWM3_BASE, 0U);
EPWM_setActionQualifierAction(EPWM3_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_TOGGLE,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setClockPrescaler(EPWM3_BASE,
EPWM_CLOCK_DIVIDER_128,
EPWM_HSCLOCK_DIVIDER_14);
epwm3TimerDirection = EPWM_TIMER_UP;
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}这句就是设置周期
EPWM_setTimeBasePeriod(EPWM3_BASE, 100000000000); //CPU主频100MHz
编译运行后,就可以看到LED每秒闪烁了。
用逻辑分析仪测量EPWM3A(GPIO4)引脚,可以看到周期2秒的方波输出。


我要赚赏金
