基于NS800RT5039开发板输出一对互补 2MHZ的PWM
该项目使用了NS800RT5039开发板,实现了输出一对互补 2MHZ的PWM的设计,它的主要功能为:通过NS800RT5039的外设EPEM输出一对互补 2MHZ,50%占空比的PWM波形,并通过串口实现了字符串输出。
标签
嵌入式系统
开发板
zght
更新2025-12-02
16

一、项目介绍

本项目旨在用使用原厂提供的NSSinePad-NS800RT5039完成基本外设epwm,gpio以及串口的使用,使用串口输出 “Hello, NOVOSENSE Wedesign project.”字符串,通过epwm外设实现在对应输出端口,输出一对互补PWM波形,波形频率2MHz,占空比50%。并通过逻辑分析仪和串口助手查看实际现象。

二、项目设计思路

2.1 功能需求

  • 使用原厂提供的NSSinePad-NS800RT5039开发板搭建自己的工程;
  • 使用GPIO外设功能,点亮板子的LED灯;
  • 使用串口外设功能,通过串口输出“Hello, NOVOSENSE Wedesign project.”字符串;
  • 使用EPWM外设,输出一对互补PWM波形,波形频率2MHz,占空比50%

2.2 设计框图

image.png

  1. NSSinePad-NS800RT5039开发板:实现GPIO,UART,EPWM控制;
  2. keil:代码编辑,程序下载;
  3. 串口调试助手:开发板串口调试,显示NSSinePad-NS800RT5039开发板输出的字符串,调试信息;
  4. DSView:抓取NSSinePad-NS800RT5039开发板EPWM外设的互补输出,查看占空比和频率

2.3 硬件介绍

  • NSSinePad-NS800RT5039开发板:NS800RT5039:是纳芯微的一款中端算力实时控制MCU,采用运行在200~260MHz的Cortex M7内核,配合自研的eMath浮点数学运算加速核,可以实现迅速的环路控制和高效的实时控制运算。高速高精度的ADC、100ps的高精度PWM、专用的PWM事件管理器跟高速比较器的快速联动可以保障每个高速环路的精准控制。
  • DSViewDSView是梦源科技为其DSLogic系列逻辑分析仪及DSCope系列示波器开发的配套软件。它将逻辑分析仪、示波器和数据记录仪功能集成于一体,支持多通道数字信号的捕获、测量及深度协议分析,能够自动解码并直观显示I2C、SPI、UART等多种常用通信协议的数据内容。该软件兼容从入门到专业的多种硬件型号,并支持Windows、Linux和macOS主流操作系统,其友好的用户界面和完整的中文支持,使其成为电子工程师在电路调试、嵌入式系统开发和信号分析领域中不可或缺的实用工具。由于手上有这个就没买十二指神探逻辑分析仪。

2.4 关键代码展示与说明

2.4.1 GPIO输出

开发板板载了LED等,可以用于GPIO的输出测试,在代码开发前,先对原厂提供的SDK进行调整,不习惯,路径又深的一匹,打开个工程都报错。调整过程就在描述,一下是调整好的样子。

image.png

同时将工程放到D盘,新建了一个本地SVN,方便代码的版本管理, 改动。方便追溯问题。

image.png

板载的2颗LED灯连接到GPIO20和GPIO22,如下所示:

image.png

代码中初始化对应的GPIO,然后在while循环中间隔1s循环闪烁。

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);
}
主循环:
while(1)
{

GPIO_clearPin(BOARD_LED4_PIN);
GPIO_setPin(BOARD_LED5_PIN);

Delay_ms(1000);

GPIO_setPin(BOARD_LED4_PIN);
GPIO_clearPin(BOARD_LED5_PIN);

Delay_ms(1000);
}

2.4.1 UART输出

串口调试连接的是GPIO29和GPIO28,同时通过板载DAPlink虚拟串口连接至电脑,硬件电路连接如下所示:

image.png

调试的时候只需要一根USB线就能实现代码下载,串口调试,挺方便,但不能自复位,需要手动复位一下。相关代码:

    /* 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);

字符打印输出:

    printf("Hello, NOVOSENSE Wedesign project.\r\n");

2.4.1 EPWM输出

本次EPWM外设输出选用的EPWM1,使用1A,1B输出2MHZ的互补PWM波,对应GPIO0和GPIO1,硬件电路如下:

image.png

EPWM1初始化代码:


/**
* @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, 0);
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);

}


输出一对互补PWM波形,波形频率2MHz,占空比50%相关配置:

#define DEVICE_SYSCLK_FREQ          260000000

EPWM_SignalParams pwmSignal =
{2000000, 0.5f, 0.5f, true, DEVICE_SYSCLK_FREQ,
EPWM_COUNTER_MODE_UP_DOWN, EPWM_CLOCK_DIVIDER_2,
EPWM_HSCLOCK_DIVIDER_1};

int main(void)
{
Device_init();
Device_unlockPeriphReg();
SYSCON_UNLOCK;
SYSCON_enableTbclkSync(SYSCON, false);
SYSCON_LOCK;
Board_init();
peripheral_init();

EPWM_configureSignal(myEPWM1_BASE, &pwmSignal);

SYSCON_UNLOCK;
SYSCON_enableTbclkSync(SYSCON, true);
SYSCON_LOCK;

Interrupt_initModule();
Interrupt_initVectorTable();

三、搜集素材的思路

本次使用的主要是原厂NSSinePad-NS800RT5039开发板,资料主要是参考原厂的资源,通过百度网盘提供的压缩包,参考里面的数据手册,用户手册,出厂SDK,硬件手册,开发板原理图以及相关说明文档。同时也在网上找了下先关资料,但都没找到,也没说明。也可以参考TI的资料,芯片对标TI。

四、成果展示

4.1 实物照片

整体的实物连接,电脑通过一根USB线连接至开发板,通过逻辑分析仪连接至开发板EPWM 1A和1B的输出引脚。

4.2 串口字符串输出

串口字符串输出“Hello, NOVOSENSE Wedesign project.并通过串口上位机显示。

image.png

4.3 EPWM互补输出

EPWM互补输出使用的是DSview的逻辑分析仪,上位机软件师DSview,查看互补输出波形:

image.png

五、总结

1.遇到的问题

1.新建工程的时候EPWM配置正确,但输出的EPWM只有78K,实际配置了2M,实际没有使能外部晶振。需要添加以下字符串。

NS800RT5XXX SYSCLK_SOURCE_USE_HXTL SYSCLK_USE_PLL PLLCLK_SOURCE_USE_HTXL

image.png

2.心得体会

本次自己完成了新工程的创建,实现了GPIO,UART,EPWM外设的使用,发现了芯片的良好性能,由于时间关系以及其他任务关系没有对芯片进行拓展开发。有点可惜,大赛的奖励还是很诱人的。感谢硬禾学堂推出的《WeDesign》活动!此次活动带给我许多宝贵实践经验和机会,我们下期活动再见!下期争取做个好的项目,拿个好的奖励,多多拓展自己的知识技能。







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