MCUXpresso

相信大家对MCUXpresso IDE并不陌生,没少和这款IDE打交道来进行工程的构建、调试等,不过,小编在这里要问大家一个问题,你们平时是不是都是调试自带的SDK例程,没有单独调试过其他工具链所构建的应用镜像呢?反正小编,的确不曾这样干过,那么MCUXpresso到底行不行呢?请大家跟着小编来一窥究竟。

不熟悉MCUXpresso的朋友更应该试试。

在正式开始之前,我们需要对我们的MCUXPresso进行一点小小的更新,需要安装一个小插件,依次点击Help-》Eclipse Marketplace,搜索Eclipse Embedded C/C++,点击安装。如下图所示:

“用MCUXpresso调试其它工具链生成的项目"

那么为啥这个小插件能这么神奇呢?我们先来看段英文原版介绍:Eclipse Embedded CDT is an open source project that includes a family of Eclipse plug-ins and tools for multi-platform embedded cross (Arm and RISC-V) development, based on GNU toolchains. the Eclipse Embedded CDT plug-ins allow to create, build, debug and in general to manage Arm & RISC-V projects (executables and static/shared libraries, in both 32 and 64-bit versions) with the Eclipse framework (currently tested up to Eclipse 4.18, 2020-12). The plug-ins run on Windows, macOS and GNU/Linux.
首先,我知道MCUXpresso是基于Eclipse CDT开发的(不用问我怎么知道的),从上面这段画我们就知道了这个小插件是专门用于Eclipse CDT平台,来调试多平台嵌入式设备的。

可能有朋友会问了,真有这么神奇吗?让我们眼见为实,当安装完这个插件后,我们的MCUXpresso会发生一些小变化,尤其是在Debug Configuration选项框,先来看看原始的样子:

“用MCUXpresso调试其它工具链生成的项目"

安装那个插件后,这是最新的样子,会多出一些选项:

“用MCUXpresso调试其它工具链生成的项目"

现在就来敲黑板划重点了,为啥非要安装这个插件呢?我们的MCUXPresso本身就支持调试嵌入式代码啊,为啥还要多此一举呢?

这里我们以使用SEGGER J-Link进行调试为例,结合具体操作步骤进行说明。

首先是导入我们的镜像文件,这里以hello_world.axf镜像文件为例:

1)点击File->Import,在弹出的页面选择C/C++ Executable, 之后点击Next:

“用MCUXpresso调试其它工具链生成的项目"

2) 选择我们想要调试的镜像文件,这里的Select binary parser按照默认选择Elf Parser即可,点击Next:

“用MCUXpresso调试其它工具链生成的项目"

3)工程配置,生成调试配置文件,这里要注意一定要选择GDB SEGGERJ-Link Debugging,细心的朋友肯定已经看出来了,这个就是我们安装完Eclipse Embedded CDT插件之后更新出来的新选项,也是调试成功的关键。最后点击Finish即可完成工程创建。

“用MCUXpresso调试其它工具链生成的项目"

而如果这里按照以前的习惯选择了GDB SEGGER Interface Debugging的话,会弹出下面这个提示,导致调试失败。

“用MCUXpresso调试其它工具链生成的项目"

这里小编先大胆的猜测一下,我们用上述方式所导入创建的工程并不是MCUXpresso默认的工程形式,而是默认的Eclipse工程,这样的话,就会出现配置不兼容问题,导致调试失败。而也正是因为这一点,小编在开头才让大家去安装我们的Eclipse Embedded CDT插件。

通过以上步骤,我们的工程就创建完成了,距离调试还差最后一步,那就是我们的Debug Configuration,依次点击Run->Debug Configurations,弹出对话框如图所示,我们需要做的是填入我们的设备名称,并添加我们的调试工具路径,例如这里我们使用arm-none-eabi-gdb进行调试,这里就需要添加其可执行文件的完整路径:

“用MCUXpresso调试其它工具链生成的项目"

配置好后,直接点击Debug即可开始调试我们的代码,开心ing:

“用MCUXpresso调试其它工具链生成的项目"

经过小编的实地考察,最终为我们的MCUXpresso正名,通过安装扩展插件,它是可以单独进行镜像的调试的。

不过,需要注意的是,我们要保证完整的源码树路径在我们的本机中,不然,可能看不到熟悉的C代码,只能在汇编中徜徉了。

来源:恩智浦MCU加油站
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 11

引言

华芯微特公司SWM系列单片机提供的TIMER个数和功能有些微差别,为了让您更加简单的使用这一功能,下面小编将以SWM190为例,我们今天详细讲解一下TIMER的输入捕获功能。

TIMER输入捕获

一、TIMER定时器之输入捕获功能

我们今天详细讲解一下TIMER的输入捕获功能。

SWM190提供了一个用于捕捉外部脉宽的模块,可记录外部单个脉冲宽度,可通过读取相应寄存器获得脉冲高低电平的宽度。

每一个TIMER都可以配置中断。使能中断后,脉冲捕获完成会触发中断操作,如果不操作使能位,则持续记录电平宽度,直至使能位关闭。

二、SWM190 TIMER脉冲捕获功能配置库函数

下面我们以脉冲捕获为例,使用加强型定时器,使用TIMR0的Input Capture功能测量输入PWM的占空比。在此例程中,我们将使用PWM产生PWM波来产生测试信号供Input Capture功能测量;使用B6作为TIMER0的输入捕获IO口,并将测量的高电平脉冲和低电平脉冲通过串口打印。

我们之前有讲到PORT的配置方法,在这里就不在做赘述,将B6引脚通过PORT_Init设置为TIMER的输入功能引脚(PORTB_PIN6_TIMR0_IN)。

在SWM190固件库中对TIMER的配置进行了说明,下面将根据库函数对SWM190的TIMER配置,首先来看一下TIMR_Init函数的原型void TIMR_Init(TIMR_TypeDef * TIMRx, uint32_t mode, uint32_t prediv, uint32_t period, uint32_t int_en)。这个函数的实现是在SWM190_timr.c文件中,若要使用该函数在相应的应用程序的前面包含SWM190_ timr.h头文件。

函数的第一个参数为TIMR_TypeDe,它是一个结构体类型,该类型在SWM190.h中被定义。具体参数为指定TIMER模块,有效值包括TIMR0,TIMR1,TIMR2,TIMR3,BTIMR0,BTIMR1,BTIMR2,BTIMR3;

第二个参数为uint32_t mode,为TIMER模式配置,有效值包括TIMR_MODE_TIMER(定时器)、TIMR_MODE_COUNTER(计数器上升沿)、TIMR_MODE_OC(输出比较)、TIMR_MODE_IC(输入捕获);其中基础定时器只支持TIMR_MODE_TIMER(定时器);

第三个参数为uint32_t prediv,为TIMER分频配置,其中加强型定时器无分频只能为1;基本定时器可取值1-256;

第四个参数为uint32_t period,为计数周期,其中加强型定时器为32bit,基础定时器为24bit。

第五个参数为uint32_t int_en,为中断使能。

我们的函数配置为:

TIMR_Init(TIMR0, TIMR_MODE_IC, 1, 0xFFFFFFFF, 0);

在TIMR_Init函数中,使用TIMER0;模式选择输入捕获;不分频;计数周期为0xFFFFFFFF;不使能中断(此中断在TIMR_IC_Init函数中使能)。

我们接下来看TIMR_IC_Init(TIMR_TypeDef * TIMRx, uint32_t captureH_int_en, uint32_t captureL_int_en)函数。

函数的第一个参数为TIMR_TypeDe,它是一个结构体类型,该类型在SWM190.h中被定义。具体参数为指定TIMER模块,有效值包括TIMR0,TIMR1,TIMR2,TIMR3;

第二个参数为captureH_int_en,为测量高电平长度完成中断使能;

第三个参数为captureL_int_en,为测量低电平长度完成中断使能;

我们的函数配置为:

TIMR_IC_Init(TIMR0, 1, 1);

TIMR_IC_Init函数中配置为使用TIMER0;高电平捕获完成中断使能;低电平捕获完成中断使能;

值得一提的是,在TIMR_IC_Init库函数中,默认如果使能了高/低电平捕获完成中断使能,则就使能对应TIMER的中断。

我们使用加强型定时器0实现timer获取B1引脚上的PWM波形的高低电平,当捕获完成则进入TIMER中断,在中断中读取高电平脉冲和低电平脉冲宽度,并通过串口打印数据。

具体配置函数如下图所示:

“MCU之TIMER输入捕获"

接下来我们看下中断服务子函数,在加强型定时器的中断服务函数中,实现每完成一次高/低电平捕获,则通过串口打印脉冲的高/低电平宽度。

“MCU之TIMER输入捕获"

三、实验现象

下载好程序后,将B1脚和B6脚物理连接,并通过串口线将单片机与电脑连接,可在电脑端通过串口助手得到B1脚的PWM波形的高/低电平宽度。

来源:华芯微特32位MCU
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 34

在进行MCU开发时,根据实际需要,将数据、函数与文件存入指定位置,对合理使用存储器的十分重要。经常有客户问如何将某一数据、函数或文件存入指定的地址空间,结合客户的问题,本文主要对此进行讲解。

构建工程后,代码与数据的默认存放位置

以LPC54628中helloworld例程为例,开发环境:MCUXpresso IDE。

构建工程(Build)后,内存分配如以下console窗口所示:

“使用MCUXpresso

其中.text,.data,.bss,.dec与Flash,RAM的关系如下所示:

“使用MCUXpresso

自定义Flash与RAM分区

为了将某一数据、函数或文件存入指定的地址空间,我们先要自定义分区。

打开工程属性设置界面,在MCU settings选项中分区出MY_FLASH与MY_RAM两个区用于测试,可以自定义这两个区的大小,如下所示:

“使用MCUXpresso

配置完Flash与RAM之后,点击Apply and Close后会在工程栏看到我们分区出来的Flash2和RAM2,如下所示:

“使用MCUXpresso

数据存入指定位置

1) 变量与常量默认存放位置

我们先查看变量和数组的默认位置。例如:

初始化过的变量:uint16_t value1 = 1;

未初始化的数组:char data_buffer1[1024];

常量数组: const char data_buffer2[1024] = "hello nxp";

使用MCUXpressoIDE自带的Image Info窗口来查看数组存放位置:

“使用MCUXpresso

可读写变量和数组默认存放在名为“SRAM_UPPER”的RAM(0x20000000-0x20014000)中,const类型的数组存放在名为“PROGRAM_FLASH”的Flash(0x0-0x40000)中。

2)将指定的变量与常量存入指定位置

将数组存入自定义的Flash与RAM中,需要调用C语言中的

__attribute__ ((section(#type#bank)))

例如 将数据放入Flash2的 .text中

__attribute__ ((section("text_Flash2"".$Flash2"))) + 数据声明

官方已封装并定义到cr_section_macros.h中,__DATA(RAM2)将可读写数组放入RAM2的.data段,__RODATA(Flash2)指将只读数组放入Flash2的 .rodata段,即:

__DATA(RAM2) char data_buffer3[1024];

__RODATA(Flash2) const chardata_buffer4[1024] = "hello nxp";

注意使用时要先包含头文件

#include "cr_section_macros.h".

“使用MCUXpresso

全局变量和数组存放在名为“MY_RAM”的自定义RAM2(0x20014000-0x20028000)中,只读的const类型数组存放在名为“MY_FLASH”的自定义Flash2(0x40000-0x80000)中。

函数存入指定位置

1)function默认放置位置

代码默认会放置在名为“PROGRAM_FLASH”的Flash(0x0-0x40000)中,定义函数

int hello1(void)

{

        return 1;

}

2)function存入指定位置

将函数存入指定Flash,需要调用C语言中的这个定义:

__attribute__ ((section(#type#bank)))

如函数存入Flash2中,可以写作:

__attribute__ ((section("text_Flash2"".$Flash2")))+函数声明

同样官方进行了封装,使用__TEXT(Flash2)+函数声明即可。

更改代码放置位置的方法如下所示,将代码存入名为“MY_FLASH”的自定义Flash(0x40000-0x80000)中,定义函数:

__TEXT(Flash2) int hello2(void)
{
        return 2;
}

“使用MCUXpresso

指定文件存放到指定位置

当存在大量函数需要存入指定Flash时,使用__TEXT(Flash)的方法设置每一个函数就略显笨拙。
如需要某个C源文件中的所有函数放入指定Flash区域,只需将编译完成的.o文件放入指定Flash即可。
我们新分区出名为“MY_FLASH_O”的Flash3,在source文件夹下新建hello.c,编译生成hello.o,并配置Linker Script将hello.o放入新分区出的Flash中,如下:

“使用MCUXpresso

“使用MCUXpresso

“使用MCUXpresso

本文涉及到的演示代码,可以在NXP社区下载

来源:恩智浦MCU加油站
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 16
订阅 RSS - MCUXpresso