英飞凌推出的基于ARM Cotex-M平台的XMC系列MCU,可以适用于各种应用领域,如电机控制、人机交互等。 了解到用户在使用XMC系列时会遇到一些困难,今天我们的AE就部分常见问题做了解惑答疑。
英飞凌推出的基于ARM Cotex-M平台的XMC系列MCU,可以适用于各种应用领域,如电机控制、人机交互等。
了解到用户在使用XMC系列时会遇到一些困难,今天我们的AE就部分常见问题做了解惑答疑。
问题一:XMC系列MCU与其它ARM Cortex-M平台的MCU有何区别?支持哪些实时操作系统?
XMC系列MCU采用标准的Cotex-M内核,平台的转换很容易,主要是需要了解与学习XMC的特色外设单元的使用方法。
XMC4000系列MCU支持市面上主流的实时操作系统,如FreeRTOS, μC/OSII, μC/OSIII, ThreadX, embOS等。目前市场上使用最多且市场占有率最高的是FreeRTOS。
问题二:XMC4000的ADC与DSD有什么不同?
ADC适合快速动态变化的模拟信号,DSD适合连续周期性宽幅度变化的模拟信号。DSD搭配前端的Delta-Sigma调制器对数据流信号进行滤波解调,可应用在各种逆变器的“热”电流,电压检测,电机旋转变压器载波信号的产生和解调。
//Synchronization Config.
XMC_VADC_GROUP_SetSyncSlave(VADC_G1, 0U, 1U);
XMC_VADC_GROUP_SetSyncSlave(VADC_G2, 0U, 2U);
XMC_VADC_GROUP_SetSyncSlave(VADC_G3, 0U, 3U);
XMC_VADC_GROUP_CheckSlaveReadiness(VADC_G1,1U);
XMC_VADC_GROUP_CheckSlaveReadiness(VADC_G2,2U);
XMC_VADC_GROUP_CheckSlaveReadiness(VADC_G3,3U);
XMC_VADC_GROUP_SetSyncMaster(VADC_G0);
触发信号接入主模块,当主ADC模块接收到触发信号时将同时触发主从共4个模块同时进行ADC采样。XMC4800可以提供最高12bit转换精度。
在实际开发中,都会碰到需要修改代码或者变量位置的情况。以DAVE IDE使用为例,根据用户的需求,一般分为以下几种情况:
void __attribute__((section (".ram_code"))) CalSumInRAM(void)
{
…
}
.text :
{
…
*(EXCLUDE_FILE( *test.o) .text.* .gnu.linkonce.t.*);
…
} > FLASH
.ram_code : AT(DataLoadAddr + __data_size)
{
__ram_code_start = .;
/* functions with __attribute__ ((section (".ram_code")))*/
*(.ram_code)
/* list the object files running from PSRAM here*/
*test.o(*text.*);
. = ALIGN(4);
__ram_code_end = .;
} > SRAM
2)需要把变量放在RAM中指定位置时,需要首先在ld文件中定义一块数据存放区。然后使用__attribute__关键字,对变量进行声明,如此就可以将变量放到这个区域中。例如将一个名为number的变量放到0x20001000地址,首先在ld文件中定义一块从0x20001000开始的数据区,命名为myDataBlock。
.myDataBlock 0x20001000:
{
*(.myDataSection)
}> SRAM
而后在源文件中对变量使用__attribute__关键字进行声明即可。
uint8_t __attribute__ ((section (".myDataSection"))) number;
3)和上一种情况类似,如何将常量放在Flash中的指定位置。例如将一个名为myconst的常量放到Flash的0x10010000地址,首先在ld文件中定义一块从0x10010000开始的数据区,名称为myConstBlock。
.myConstBlock 0x10010000:
{
*(.myConstSection)
}> FLASH
然后在源文件中对常量使用__attribute__关键字进行声明即可。
const uint8_t __attribute__ ((section (".myConstSection")))
myconst[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
4)需要把代码放在Flash中的指定位置时,同样在ld文件中定义一块自己的代码段,同样在源文件中用__attribute__关键字对函数进行声明即可。例如把一个函数放在0x10016000开始的地址。
.myCodeBlock 0x10016000:
{
KEEP(*(.myCodeSection))
}> FLASH
在源文件中使用__attribute__关键字把CalSumInFlash()函数进行声明。
void __attribute__ ((section (".myCodeSection"))) CalSumInFlash(void)
{
…
}
MEMORY
{
FLASH(RX) : ORIGIN = 0x10001000, LENGTH = 0x20000
/* Add a new Flash area */
FLASH_1(RX) : ORIGIN = 0x10020000, LENGTH = 0x10000
SRAM(!RX) : ORIGIN = 0x20000000, LENGTH = 0x4000
}
/* List files which are located in Flash_1 area */
.romCode :
{
*test2.o (.text .text*);
} > FLASH_1
方法二:首先要将这个文件从text段中exclude出来,然后定义一个代码段,再把文件放置到这个段中。需要注意这个0x10020000地址段不能与其它代码重叠。
.text :
{
…
*(EXCLUDE_FILE( *test2.o) .text.* .gnu.linkonce.t.*);
…
} > FLASH
.romCode 0x10020000:
{
*test2.o (.text .text*);
} > FLASH
问题六:代码在调试时不能go main,重新上电后更无法下载程序?
通常情况下,代码编写、编译、调试都不会出现问题,一般问题可以通过检查仿真器与电源是否正确连接来解决。但是,往往用户有一些特殊想法时就出现了不同寻常的状况。例如一位使用XMC4800的用户在调整程序结构时,将ld文件中text段修改到Flash的其它位置,而后发现代码无法go main,板卡重新上电后更是无法下载程序。
text段是用于存放程序代码的区域,而XMC MCU在启动时会从Flash的首地址运行。当text不在Flash首地址时,整个MCU无法正确初始化,同时会造成仿真使用的SWD接口没有正确初始化,这样就造成了当前程序无法go main,后续程序无法下载的情况。
如何解决这个问题呢?我们需要将text段放回到Flash的首地址区域并重新编译代码,同时将Flash中的代码全部擦除来解决这个问题。由于没有了SWD接口,只能使用串口进行擦除。使用英飞凌原厂提供的烧写工具MemTool可以通过串口擦除Flash。
具体操作如下:
1)确认XMC4800预留UART烧写引脚,具体引脚是P1.4 (U0C0_DX0B)和P1.5 (U0C0_DOUT0),这两个引脚位置是固定的。只有使用这两个引脚才可以使用Memtool进行串口擦除Flash。
2)将XMC4800的Boot模式配置成ASC_BSL模式。XMC4800的Boot模式是由两个外部引脚TCK和TMS决定的。如果TCK和TMS这两个引脚悬空,则芯片上电后处在Normal 模式(即TCK 和TMS引脚在芯片内部是弱下拉和弱上拉的)。而UART烧写所需模式是ASC_BSL模式,因此在上电前需要把TMS下拉即可。
3)运行MemTool工具,配置芯片信息。
- 选择Target -> Change
- 在弹出窗口选择New
- 选择 “Use a default target configuration”,选择目标芯片,点Finish。并保存cfg文件,最后点击OK按钮
- 此时已经可以看到XMC4800各个sector的地址与容量。在MemTool下方可以看到软件没有与目标板连接
- 点“Target->Setup…”,选择COM口
- 点击软件下方的Connect按钮,连接之后,MemTool显示已经连接
- 点击右侧的Erase…按钮,弹出Sector选择对话框,我们这里选择Erase whole FLASH Module,并点击Start按钮。等待擦除完成后,修改XMC4800的Boot模式配置成Normal模式并重新上电,此时MCU又可以进行烧写仿真了