【国民技术N32WB031_STB开发板评测】 GPIO翻转性能测试
[复制链接]
N32WB03x的GPIO翻转性能测试
前言
某些情况下,需要使用GPIO来模拟一些外设,虽然这会占用较多的MCU。为了弄清mcu的GPIO翻转速度上限,还是有必要测试一下的。
官方GPIO翻转工程
在这个目录下,有官方的GPIO翻转最高速度的工程
N32WB03x_V1.3.0\5-Software Development Kit\N32WB03x_SDK_V1.3\projects\n32wb03x_EVAL\peripheral\GPIO\IOToggle_MaxFrequency
用keil打开这个工程,可以看到main.c程序
int main(void)
{
/* -1- Enable GPIOx Clock (to be able to program the configuration registers) */
RCC_EnableAPB2PeriphClk(GPIOx_CLK, ENABLE);
/* -2- Configure GPIOx_PIN in output push-pull mode */
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIOx_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
/* -3- Toggle GPIOx_PIN in an infinite loop */
while (1)
{
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
}
}
然后编译烧录后,使用示波器测试,翻转速度在8Mhz左右。为了进一步测试上限,尝试将函数放到RAM里执行。
MCU的程序在Flash里和RAM里有什么区别?
由于MCU的资源都比较小,常见产品的Flash也是支持XIP的,也就是MCU可以直接在Flash里取指令并直接执行。所以并不像PC那样,必须将程序加载到RAM里才可以运行。同时因为很多MCU的速度远高于Flash的速度,为了提高执行效率,工程师们一般使用三种办法(如果有其他的办法,麻烦大家帮忙补充一下)。
- 增加ICache,在核心与Flash之间增加指令缓冲,加快执行速度。
- 使用部分SRAM作为零缓冲区,在mcu启动时自动将Flash的大部分加载到零缓冲区(缓冲区和Flash的数据同步由硬件自行完成,无需用户干预)。
- 将一部分函数在mcu启动时从Flash加载到RAM里,在RAM里执行这些函数。
如何在keil中指定部分函数加载到RAM里
- 点击 Options for Target..图标,然后在弹出的选项卡里选择Linker选项卡
- 取消勾选左上角的Use Memory Layout from Target Dialog,然后点击下边sct文件旁边的edit按钮(见图片), 然后点击OK关闭选项卡
- 修改.sct文件,自定义一个section(这里我们使用RAMCODE),放在RW_IRAM1段
- 将#pragma arm section code = "RAMCODE"放在main函数前,#pragma arm section放在main函数后。
.sct的最终内容如下
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x01000000 0x00040000 { ; load region size_region
ER_IROM1 0x01000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x0000C000 { ; RW data
*.o(RAMCODE)
.ANY (+RW +ZI)
}
}
main函数修改后最终内容如下
#pragma arm section code = "RAMCODE"
int main(void)
{
/* -1- Enable GPIOx Clock (to be able to program the configuration registers) */
RCC_EnableAPB2PeriphClk(GPIOx_CLK, ENABLE);
/* -2- Configure GPIOx_PIN in output push-pull mode */
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIOx_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
/* -3- Toggle GPIOx_PIN in an infinite loop */
while (1)
{
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
GPIOA->POD = 1;
GPIOA->POD = 0;
}
}
#pragma arm section
编译烧录后,可以看到速度增加到9.25MHz,应该就是这个MCU的GPIO极限翻转速度了,详见截图。
|