【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秒的方波输出。