基于纳芯微评估板NSSinePad-NS800RT5039 设计项目
该项目使用了NSSinePad-NS800RT5039,实现了UART打印和ePWM输出互补波形的设计,它的主要功能为:通过UART1打印字符串,ePWM1输出两路互补波形到 GPIO0,GPIO1上,并通过十二指神探逻辑分析抓取波形观察。
标签
纳芯微
WeDesign活动
ePWM
Batman9527
更新2025-12-02
37


1. 任务介绍

大家好,我是电子森林的 Batman9527,此次参加 WeDesign7 活动,我选择的是任务5,使用微控制器芯片NS800RT5039 / 评估板NSSinePad-NS800RT5039 设计项目。

 

这次用于活动的时间比较仓促,我只完成基础任务:

1.      调用Uart串口,完成在串口输出 “Hello, NOVOSENSE Wedesign project.” 字符串任务。

2.      调用ePWM外设,实现在对应输出端口,输出一对互补PWM波形,波形频率2MHz,占空比50%。并使用12指神探捕获对应波形截图(未购买12指神探的可以用万用表电压档测量并拍照)。


2. 项目描述

 

使用原厂NSSinePad-NS800RT5039开发板完成2个基础任务,另外使用十二指神探作为逻辑分析仪观察 ePWM 输出的互补波形。


2.1 任务1UART 输出指定字符串

 

使用板载串口,打印 Hello, NOVOSENSE Wedesign project. 字符串。

板载串口使用 GPIO29 作为 UART_TX, GPIO28 作为 UART_RXUART 波特率设置为 921600bps

使用 USB Type-C 数据线连接电脑和开发板,打开电脑串口工具,选择对应的串口,就可以看到开发板打印的字符串。


2.2 任务2,使用 ePWM 输出两个互补波形,并用逻辑分析仪观察

 

这里使用 ePWM1 输出互补波形,其中 ePWMA 通道映射到 GPIO0, ePWMB 通道映射到 GPIO1.

设置目标 PWM 信号的频率为 2MHz ePWMA ePWMB 两个通道占空比都是 50%,但是 ePWMB 通道和 ePWMA 通道是互补波形。

 

在设置好 ePWM1 输出两个互补波形,使用十二指神探逻辑分析连接到 GPIO0, GPIO1 两个引脚,然后观察波形。

十二指神探对应的上位机是 PulseView,添加两个 PWM 协议解析器,分别关联到两个信号,就可以解析出两个信号的频率和占空比。


3. 硬件介绍



NSSinePad-NS800RT5039 是基于 NS800RT5039 实时微控制器设计的旨在帮助用户快 速开展芯片学习、评估等工作的低成本开发板。基于该开发板,用户可以方便使用 NS800RT5039 实时微控制器的所有外设、内存。除实时微控制器芯片外,该开发板还具有 板载CAN 收发器(支持CAN2.0B CAN-FD)、两个 5V 编码器(eQEP)接口芯片及板载 DAP Link 调试/仿真器。 开发板功能区域如图1所示。



NS800RT503x 实时微控制器具有如下特性:

        32 Arm Cortex-M7 高性能内核,最高工作频率 260MHz32KB L1-CacheIEEE 754 双精度 FPU,支持 DSP 指令集,单周期 MAC、单周期乘法、硬件除法、SIMD指令等,支持内存保护MPU

        增强型数学运算加速器 EMATH4路单精度浮点数乘法器,支持 FFT/iFFT/DCT/iDCT 硬件加速,支持矩阵操作,支持 Convolution/Correlation/FIR

        存储,高达512KB的片上存储,支持ECC校验,高达 64KB ITCM 64KB DTCM,支持ECC校验;

        系统外设,216通道DMA,最多67个独立可编程GPIO,最多30路支持数字输入功能的模拟引脚,最多2路支持数字输入、输出功能的模拟引脚;

        通信外设,3I2C,支持SMbus1 CAN2.0B 控制器,1 CAN-FD 控制器,3SPI标准通信接口,3UART标准通信接口,2 LINFlexD 控制器(兼容 UART,支持小数波特率),1个具有XIP功能的QSPI1个支持 SD/MMMC/eMMC 协议的 SD 卡接口;

        增强型控制器外设,最多32 ePWM 通道,包含具有高分辨率功能(124ps分辨率)的16个通道 HRPWM);

        丰富的定时器外设,1个独立看门狗1,一个 NMI 看门狗,2个基础定时器,3个系统定时器,1个低功耗定时器,1个自唤醒定时器;

        信息安全域功能安全模块,2 8/16/32 CRC计算单元,1个高级数据加密模块 HASH-AES1个真随机数发生器,1个故障管理单元;

        可靠性与功能安全认证


4. 方案框图+设计思路


1.      NSSinePad-NS800RT5039 开发板初始化串口,通过串口发送数据,调试器接收到UART数据在通过USB发送给电脑;

2.      NSSinePad-NS800RT5039 开发板初始化 ePWM 两路信号,输出互补波形,通过十二指神探逻辑分析抓取波形,分析波形;


5. 原理图

 

任务1,涉及到UART,原理图如下:

下图中(1)框标注的时 SCI_SEL1 SCI_SEL2 对于COM口的选择。可以看到 U6, U8, U9 共用 SCI_SEL1 SCI_SEL2 信号,通过4组值,分别选择不同的COM口。当前板子默认选择第一种值,即 SCI_SEL1 = 0, SCI_SEL2 = 0.即选择 GPIO28/GPIO29 作为 UART 信号管脚。

下图中(2)框就是两个 SCI_SEL1, SCI_SEL2 信号的拨码开关。对应实物照片如下。




 

任务2,涉及到 ePWM 两路信号,原理图如下:

由于 ePWM1A 映射到 GPIO0, ePWM1B 映射到 GPIO1,所以只需要找到对应管脚即可。


ePWM1A ePWM1B 与十二指神探逻辑分析仪的实物连接如下图所示:


6. 软件流程图+关键代码

 

6.1 任务1,软件流程图

 

6.1.1 main() 函数流程图

1.      调用 prvSetupHardware() 初始化硬件,如LED,按键和UART

2.      创建 task1_uart_print() 任务,每隔1秒钟打印一次字符串;

3.      调用 main_blinky() 任务,每隔1秒钟闪烁LED

4.      调用 vTaskStartScheduler() 启动 FreeRTOS 任务调度器;




6.1.2 prvSetupHardware() 函数流程图

 

1.      调用 Device_init() 初始化系统时钟;

2.      调用 Device_unlockPeriphReg() 使能所有外设时钟;

3.      调用 Board_init() 初始化 LED/按键以及 UART;【本任务的关键】



6.1.3 Board_init() 函数流程图

1.      调用 PinMux_init() 初始化串口、LED、按键等的管脚复用功能;

2.      调用 SerialCOM_init() 初始化串口,即配置 GPIO28 作为 UART1_RX, GPIO29 作为 UART1_TX,并配置串口属性,如波特率、数据位、停止位、奇偶校验等属性;

3.      调用 LED_init() 初始化板载 LED

4.      调用 Switch_init() 初始化板载 按键;



6.1.4 task1_uart_print() 函数流程图

 

每隔1秒钟打印一次字符串



6.2 任务1,关键代码

 

6.2.1 Board_init() 以及子函数代码




/**
* @brief Board Initialization.
* @note Call this function in your application if you wish to do all module
* initialization.
* If you wish to not use some of the initializations, instead of the
* Board_init use the individual Module_inits.
*/
void Board_init (void)
{
PinMux_init();
SerialCOM_init();
LED_init();
Switch_init();
}

/**
* @brief PinMux Initialization.
* @note Call this function in your application if you want all
* PinMux initialization to be done.
*/
void PinMux_init (void)
{
/* Configure GPIO pins for SCI_COM. */
GPIO_setPinConfig(GPIO_29_SCIA_TX);
GPIO_setPinConfig(GPIO_28_SCIA_RX);

/* Configure GPIO pins for LED4 and LED5. */
GPIO_setPinConfig(GPIO_20_GPIO20);
GPIO_setPinConfig(GPIO_22_GPIO22);

/* Configure GPIO pins for S3 and S8. */
GPIO_setPinConfig(GPIO_24_GPIO24);
GPIO_setPinConfig(GPIO_25_GPIO25);

/* Configure GPIO pins for D1 and C1 */
GPIO_setPinConfig(GPIO_16_SD1_D1);
GPIO_setPinConfig(GPIO_17_SD1_C1);
}

/**
* @brief Board Serial Communication Interface Initialization.
* @note Call this function in the application to initialize the SCI serial port
* on the board for outputting debugging information.
*/
void SerialCOM_init(void)
{
/* uart1 rx control */
GPIO_setAnalogMode(BOARD_SERIALCOM_RX_PIN, GPIO_ANALOG_DISABLED);
GPIO_setPadConfig(BOARD_SERIALCOM_RX_PIN, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(BOARD_SERIALCOM_RX_PIN, GPIO_QUAL_SYNC);
GPIO_setQualificationPeriod(BOARD_SERIALCOM_RX_PIN, GPIO_SMP_SYSCLK_DIV_1);
GPIO_setDirectionMode(BOARD_SERIALCOM_RX_PIN, GPIO_DIR_MODE_IN);
/* uart1 tx control */
GPIO_setAnalogMode(BOARD_SERIALCOM_TX_PIN, GPIO_ANALOG_DISABLED);
GPIO_setPadConfig(BOARD_SERIALCOM_TX_PIN, GPIO_PIN_TYPE_STD);
GPIO_setDriveLevel(BOARD_SERIALCOM_TX_PIN, GPIO_DRV_LOW);
GPIO_setPin(BOARD_SERIALCOM_TX_PIN);
GPIO_setDirectionMode(BOARD_SERIALCOM_TX_PIN, GPIO_DIR_MODE_OUT);
/* Reset uart before configure it */
UART_resetModule(BOARD_SERIALCOM);
/* Set baudrate */
UART_setBaud(BOARD_SERIALCOM, BOARD_SERIALCOM_BAUDRATE);
/* Set the number of stop bits */
UART_setStopBitCount(BOARD_SERIALCOM, UART_ONE_STOP_BIT);
/* Set MSB bit reverses the order of the bits */
UART_setMSB(BOARD_SERIALCOM, false);
/* Config tx fifo */
UART_enableTxFifo(BOARD_SERIALCOM);
UART_resetTxFifo(BOARD_SERIALCOM);
UART_setTxFifoWatermark(BOARD_SERIALCOM, UART_FIFO_TX6);

/* Enable transmitter */
UART_enableTxModule(BOARD_SERIALCOM);
/* Enable receiver */
UART_enableRxModule(BOARD_SERIALCOM);
}

/**
* @brief Board LED Initialization.
* @note Call this function in the application to initialize the LED
* on the board.
*/
void LED_init (void)
{
/* led4 initialization */
GPIO_setAnalogMode(BOARD_LED4_PIN, GPIO_ANALOG_DISABLED);
//GPIO_setPadConfig(BOARD_LED4_PIN, GPIO_PIN_TYPE_OD);
GPIO_setDriveLevel(BOARD_LED4_PIN, GPIO_DRV_MAX);
GPIO_setPin(BOARD_LED4_PIN);
GPIO_setDirectionMode(BOARD_LED4_PIN, GPIO_DIR_MODE_OUT);
/* led5 initialization */
GPIO_setAnalogMode(BOARD_LED5_PIN, GPIO_ANALOG_DISABLED);
//GPIO_setPadConfig(BOARD_LED5_PIN, GPIO_PIN_TYPE_OD);
GPIO_setDriveLevel(BOARD_LED5_PIN, GPIO_DRV_MAX);
GPIO_setPin(BOARD_LED5_PIN);
GPIO_setDirectionMode(BOARD_LED5_PIN, GPIO_DIR_MODE_OUT);
}

/**
* @brief Board Switch Initialization.
* @note Call this function in the application to initialize the Switch
* on the board.
*/
void Switch_init (void)
{
/* S3 initialization */
GPIO_setAnalogMode(BOARD_S3_PIN, GPIO_ANALOG_DISABLED);
GPIO_setPadConfig(BOARD_S3_PIN, GPIO_PIN_TYPE_OD);
GPIO_setQualificationPeriod(BOARD_S3_PIN, GPIO_SMP_SYSCLK_DIV_510);
GPIO_setQualificationMode(BOARD_S3_PIN, GPIO_QUAL_6SAMPLE);
GPIO_setDirectionMode(BOARD_S3_PIN, GPIO_DIR_MODE_IN);
/* S8 initialization */
GPIO_setAnalogMode(BOARD_S8_PIN, GPIO_ANALOG_DISABLED);
GPIO_setPadConfig(BOARD_S8_PIN, GPIO_PIN_TYPE_OD);
GPIO_setQualificationPeriod(BOARD_S8_PIN, GPIO_SMP_SYSCLK_DIV_510);
GPIO_setQualificationMode(BOARD_S8_PIN, GPIO_QUAL_6SAMPLE);
GPIO_setDirectionMode(BOARD_S8_PIN, GPIO_DIR_MODE_IN);
}


6.2.2 task1_uart_print() 任务代码


static void task1_uart_print( void *pvParameters )
{
for( ;; ) {
printf("\r\nHello, NOVOSENSE Wedesign project.\r\n");
vTaskDelay( pdMS_TO_TICKS(1000) );
}
}



6.3 任务2,软件流程图

 

main()函数流程图

1.      调用 prvSetupHardware(),设置系统时钟和使能外设,BSP初始化,IOMUX、串口、LED以及按键初始化;

2.      调用 main_task2_epwm(),创建 task2_epwm_entry() 任务,初始化 ePWM1A, ePWM1B 管脚以及PWM频率、占空比,以及时基配置,最后启动 ePWM1

3.      调用 vTaskStartScheduler() 启动 FreeRTOS 任务调度器;


prvSetupHardware() 函数流程图



task2_epwm_entry() 流程图

1.      调用 task_epwm_init(),配置 ePWM 硬件,如IO初始化,ePWM 模块通用设置;

2.      调用 EPWM_configureSignal() 配置 ePWM1A, ePWM1B 信号频率、占空比、信号翻转等参数;

3.      调用 SYSCON_enableTbclkSync() 使能基于时间的时钟同步;

最后在主循环中每隔1秒钟闪烁LED并打印字符串;


task_epwm_init() 函数流程

1.      调用 GPIO_Init() 初始化 ePWM1A, ePWM1B 两个管脚,即把 GPIO0 配置为 ePWM1A 输出引脚, GPIO1 配置为 ePWM1B 输出引脚;

2.      调用 EPWM_init() 配置 ePWM1 时钟分频,配置1A, 1B 信号属性;

3.      调用 sync_init() 使能 SYNCOUT 并设置 EPWM1SYNCOUT 作为 SYNCOUT


6.4 任务2,关键代码

 

task2_epwm_entry() 任务


static void task2_epwm_entry( void *pvParameters )
{
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;

// 配置 ePWM 硬件,如 IO 初始化,ePWM 模块通用配置
task_epwm_init();

// ePWMA, ePWMB 信号配置:频率、占空比等
EPWM_configureSignal(myEPWM1_BASE, &pwmSignal);

// 使能基于时间的时钟同步
SYSCON_UNLOCK;
SYSCON_enableTbclkSync(SYSCON, true);
SYSCON_LOCK;

// 初始化中断模块
Interrupt_initModule();

/* Interrupt vector table initialization. Vector table remapping. */
// Interrupt_initVectorTable();

for( ;; ) {
mainTOGGLE_LED();
printf("\r\nTask2 -- ePWM generates PWM_A, PWM_B with 2MHz, 50%% duty cycle.\r\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}



task_epwm_init() 函数



/**
* @brief peripheral Configurations
*/
void task_epwm_init(void)
{
GPIO_init();

EPWM_init();

sync_init();
}

/**
* @brief GPIO Configurations
*/
void GPIO_init(void)
{
// GPIO_0_EPWM1_A
GPIO_setAnalogMode(myEPWM1_EPWMA_GPIO, GPIO_ANALOG_DISABLED);
GPIO_setPinConfig(myEPWM1_EPWMA_PIN_CONFIG);
GPIO_setPadConfig(myEPWM1_EPWMA_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setQualificationMode(myEPWM1_EPWMA_GPIO, GPIO_QUAL_SYNC);

// GPIO_1_EPWM1_B
GPIO_setAnalogMode(myEPWM1_EPWMB_GPIO, GPIO_ANALOG_DISABLED);
GPIO_setPinConfig(myEPWM1_EPWMB_PIN_CONFIG);
GPIO_setPadConfig(myEPWM1_EPWMB_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setQualificationMode(myEPWM1_EPWMB_GPIO, GPIO_QUAL_SYNC);
}

/**
* @brief EPWM Configurations
*/
void EPWM_init(void)
{
EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_2);
EPWM_setTimeBasePeriod(myEPWM1_BASE, 0);
EPWM_setTimeBaseCounter(myEPWM1_BASE, 0);
EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
EPWM_setPhaseShift(myEPWM1_BASE, 0U);

EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 0);
EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);

EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, 0);
EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);

EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);

EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);

EPWM_setRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);
EPWM_disableRisingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);
EPWM_setFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);
EPWM_disableFallingEdgeDelayCountShadowLoadMode(myEPWM1_BASE);
}

/**
* @brief EPWM SYNC Configurations
*/
void sync_init(void)
{
/* Enable SYNCOUT output and Select EPWM1SYNCOUT as SYNCOUT */
SYSCON_UNLOCK;
SYSCON_setSynCoutSel(SYSCON, 7, 1, SYSCON_SYNCOUTSEL_EPWM1);
SYSCON_LOCK;

/* Enable the TBCTR=ZERO event to set the EPWM1SYNCOUT signal. */
EPWM_enableSyncOutPulseSource(EPWM1, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
}



EPWM_configureSignal() 函数



/*******************************************************************************
* Definitions
******************************************************************************/
#define DEVICE_SYSCLK_FREQ 260000000

/*******************************************************************************
* Variables
******************************************************************************/
EPWM_SignalParams pwmSignal = {
.freqInHz = 2000000, // 目标信号频率 Hz 为单位
.dutyValA = 0.5f, // ePWMA 占空比
.dutyValB = 0.5f, // ePWMB 占空比
.invertSignalB = true, // ePWMB 信号是否翻转
.sysClkInHz = DEVICE_SYSCLK_FREQ, // SYSCLK 信号频率
.tbCtrMode = EPWM_COUNTER_MODE_UP_DOWN, // 时基计数模式
.tbClkDiv = EPWM_CLOCK_DIVIDER_2, // 时基时钟分频
.tbHSClkDiv = EPWM_HSCLOCK_DIVIDER_1 // HSClock 分频
};


void EPWM_configureSignal (EPWM_TypeDef *epwm, const EPWM_SignalParams *signalParams)
{
float tbClkInHz = 0.0F;
uint16_t tbPrdVal = 0U, cmpAVal = 0U, cmpBVal = 0U;

EPWM_setClockPrescaler(epwm, signalParams->tbClkDiv, signalParams->tbHSClkDiv);
EPWM_setTimeBaseCounterMode(epwm, signalParams->tbCtrMode);
tbClkInHz = ((float)signalParams->sysClkInHz / (float)(1U << (uint16_t)signalParams->tbClkDiv));
if (signalParams->tbHSClkDiv <= EPWM_HSCLOCK_DIVIDER_4)
{
tbClkInHz /= (float)(1U << (uint16_t)signalParams->tbHSClkDiv);
}
else
{
tbClkInHz /= (float)(2U * (uint16_t)signalParams->tbHSClkDiv);
}
if (signalParams->tbCtrMode == EPWM_COUNTER_MODE_UP)
{
tbPrdVal = (uint16_t)((tbClkInHz / signalParams->freqInHz) - 1.0f);
cmpAVal = (uint16_t)(signalParams->dutyValA * (float)(tbPrdVal + 1U));
cmpBVal = (uint16_t)(signalParams->dutyValB * (float)(tbPrdVal + 1U));
}
else if (signalParams->tbCtrMode == EPWM_COUNTER_MODE_DOWN)
{
tbPrdVal = (uint16_t)((tbClkInHz / signalParams->freqInHz) - 1.0f);
cmpAVal = (uint16_t)((float)(tbPrdVal + 1U) - (signalParams->dutyValA * (float)(tbPrdVal + 1U)));
cmpBVal = (uint16_t)((float)(tbPrdVal + 1U) - (signalParams->dutyValB * (float)(tbPrdVal + 1U)));
}
else
{
tbPrdVal = (uint16_t)(tbClkInHz / (2.0f * signalParams->freqInHz));
cmpAVal = (uint16_t)(((float)tbPrdVal - ((signalParams->dutyValA * (float)tbPrdVal))) + 0.5f);
cmpBVal = (uint16_t)(((float)tbPrdVal - ((signalParams->dutyValB * (float)tbPrdVal))) + 0.5f);
}
EPWM_setTimeBasePeriod(epwm, tbPrdVal);
EPWM_disablePhaseShiftLoad(epwm);
EPWM_setPhaseShift(epwm, 0U);
EPWM_setTimeBaseCounter(epwm, 0U);
EPWM_setCounterCompareShadowLoadMode(epwm, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowLoadMode(epwm, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareValue(epwm, EPWM_COUNTER_COMPARE_A, cmpAVal);
EPWM_setCounterCompareValue(epwm, EPWM_COUNTER_COMPARE_B, cmpBVal);
if (signalParams->tbCtrMode == EPWM_COUNTER_MODE_UP)
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
if (signalParams->invertSignalB == true)
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
}
else
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
}
}
else if ((signalParams->tbCtrMode == EPWM_COUNTER_MODE_DOWN))
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
if (signalParams->invertSignalB == true)
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
}
else
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
}
}
else
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
if (signalParams->invertSignalB == true)
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
}
else
{
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(epwm, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
}
}
}


7. 实物演示及说明

 

7.1 任务1,串口打印



7.2 任务2ePWM 输出2MHz的互补波形

 

1.      PulseView 软件设置采样率为 60MHz,采样个数为 5M samples

2.      这里使用 D2 通道连接到 ePWM1AD3通道连接到 ePWM1B

3.      并添加了2 PWM 协议解析器,上面的绿色 PWM 协议解析器关联到 D2,下面的紫色 PWm 协议解析器关联到 D3. 特别注意,默认 PWM 协议解析器的 polarity active-high。这里由于 ePWM1B ePWM1A 的互补波形,我故意把 PWM 协议解析器的 polarity 设置为 active-low

4.      两路 PWM 信号的频率都是 2MHz,占空比都是 50%。【实际十二指神探采样数据不是很准,导致某些周期计算有偏差,忽略】



7.3 视频演示

任务一



任务2



8. 心得体会

 

1.      快速上手新的开发环境,使用十二指神探作为逻辑分析采样PWM信号;

2.      学习纳芯微 ePWM 高级功能;

 



附件下载
eetree_wedesign7.zip
https://gitee.com/LinTeX9527/eetree_wedesign7
团队介绍
个人
团队成员
Batman9527
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号