如何在Keil MDK5环境使用Arduino函数以及第三方库(适用STM32)
本帖最后由 FASTSHIFT 于 2019-2-18 11:27 编辑众所周知,STM32系列作为当前热门的微控制器,具有速度快、高性价比、外设丰富、资料众多等优点。
目前STM32主流的开发方式有寄存器开发,标准库开发,还有ST主推的HAL库开发,开发环境有IAR、Keil、Eclipse等,优缺点就不多说了,我相信适合自己的就是最好的。
但是我相信刚刚接触STM32的初学者,面对各种抽象复杂的寄存器、陌生的函数名,几乎是一脸懵逼的状态。这时一个外国团队为STM32在Arduino IDE上提供了很好的支持,这极大地简化了STM32的学习成本,这就是大家所熟知的stm32duino (链接:https://github.com/stm32duino)。
在接触了stm32duino之后,我开始好奇为什么架构完全不同的MCU可以使用几乎完全相同的代码,设想着能不能在Keil环境也能实现一样的效果(当然,主要的原因还是实在没法忍受Arduino IDE蜗牛般的编译速度:L,所以寻找一种取代方法 )。
经过一年多的优化,50+次的版本迭代,终于
几乎在Keil上复刻了Arduino的编程体验,既有Arduino简单易用的API(pinMode、Serial、String...),兼容强大的第三方库(Adafruit_xxx、SD文件系统...),又能使用Keil的在线调试,设置程序断点,查看实时内存等功能,岂不美滋滋:lol 。
目前支持的MCU有:STM32F0xx、STM32F10x、STM32F3xx、STM32F4xx系列,未来可能还会支持其他ARM核的单片机,说明都放在下面的链接。
项目地址:https://github.com/FASTSHIFT/Arduino-For-Keil
分享一个实测视频,STM32F407调用Arduino库播放SD卡视频
(工程源码以及视频生成器上位机:https://github.com/FASTSHIFT/BvPlayer)
https://v.youku.com/v_show/id_XNDA2Nzg3NzU4MA==.html?spm=a2hzp.8244740.0.0
xo37 发表于 2019-1-20 21:08
嗯,不过,第三方的兼容性要是提高就很牛了……
像有些库为了最大化利用AVR性能,会直接操作寄存器,例如IRremote,SoftwareSerial,Arduboy等,这些库比较难实现跨平台 学习了,强 :victory:不错,不错 不错,这样又多了一种玩法。 这么移植的意义何在?
本帖最后由 FASTSHIFT 于 2017-12-19 22:55 编辑
maxims 发表于 2017-12-19 18:18
这么移植的意义何在?
1.既可以兼容传统的库,又可以使用Arduino的库(比如Arduino的Print库,可以挂在USART、TFT、OLED等需要字符串打印的地方,高效方便)。
2.用C++编程比传统的C编程更有优越性,比如同类对象可以“共用”过程,提升代码复用率。
3.Keil拥有强大的调试工具,Arduino IDE没有。
4.STM32duino的底层是重新写的,不方便直接调用寄存器,也不方便裁剪。
5.既然可以移植STM32,其他ARM核的片子也不成问题。
优点暂时想了这么多:lol FASTSHIFT 发表于 2017-12-19 22:54
1.既可以兼容传统的库,又可以使用Arduino的库(比如Arduino的Print库,可以挂在USART、TFT、OLED等需 ...
这么说,懂了。
那么有个不情之请,有没有可能优化一下arduino的底层资料。
比如,优化它编译之后,不是查表控制IO口,这个表占用比较多的flash存储空间,也导致io翻转速度不够什么的。
或者把比如STC、STM8之类的移植过Arduino IDE环境? maxims 发表于 2017-12-20 21:48
这么说,懂了。
那么有个不情之请,有没有可能优化一下arduino的底层资料。
比如,优化它编译之后,不 ...
这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP = {
{&gpioa, &timer2, &adc1,0, 1, 0}, /* PA0 */
{&gpioa, &timer2, &adc1,1, 2, 1}, /* PA1 */
{&gpioa, &timer2, &adc1,2, 3, 2}, /* PA2 */
{&gpioa, &timer2, &adc1,3, 4, 3}, /* PA3 */
{&gpioa, NULL, &adc1,4, 0, 4}, /* PA4 */
{&gpioa, NULL, &adc1,5, 0, 5}, /* PA5 */
{&gpioa, &timer3, &adc1,6, 1, 6}, /* PA6 */
{&gpioa, &timer3, &adc1,7, 2, 7}, /* PA7 */
{&gpioa, &timer1, NULL,8, 1, ADCx}, /* PA8 */
{&gpioa, &timer1, NULL,9, 2, ADCx}, /* PA9 */
{&gpioa, &timer1, NULL, 10, 3, ADCx}, /* PA10 */
{&gpioa, &timer1, NULL, 11, 4, ADCx}, /* PA11 */
{&gpioa, NULL, NULL, 12, 0, ADCx}, /* PA12 */
{&gpioa, NULL, NULL, 13, 0, ADCx}, /* PA13 */
{&gpioa, NULL, NULL, 14, 0, ADCx}, /* PA14 */
{&gpioa, NULL, NULL, 15, 0, ADCx}, /* PA15 */
{&gpiob, &timer3, &adc1,0, 3, 8}, /* PB0 */
{&gpiob, &timer3, &adc1,1, 4, 9}, /* PB1 */
{&gpiob, NULL, NULL,2, 0, ADCx}, /* PB2 */
{&gpiob, NULL, NULL,3, 0, ADCx}, /* PB3 */
{&gpiob, NULL, NULL,4, 0, ADCx}, /* PB4 */
{&gpiob, NULL, NULL,5, 0, ADCx}, /* PB5 */
{&gpiob, &timer4, NULL,6, 1, ADCx}, /* PB6 */
{&gpiob, &timer4, NULL,7, 2, ADCx}, /* PB7 */
{&gpiob, &timer4, NULL,8, 3, ADCx}, /* PB8 */
{&gpiob, &timer4, NULL,9, 4, ADCx}, /* PB9 */
{&gpiob, NULL, NULL, 10, 0, ADCx}, /* PB10 */
{&gpiob, NULL, NULL, 11, 0, ADCx}, /* PB11 */
{&gpiob, NULL, NULL, 12, 0, ADCx}, /* PB12 */
{&gpiob, NULL, NULL, 13, 0, ADCx}, /* PB13 */
{&gpiob, NULL, NULL, 14, 0, ADCx}, /* PB14 */
{&gpiob, NULL, NULL, 15, 0, ADCx}, /* PB15 */
{&gpioc, NULL, NULL, 13, 0, ADCx}, /* PC13 */
{&gpioc, NULL, NULL, 14, 0, ADCx}, /* PC14 */
{&gpioc, NULL, NULL, 15, 0, ADCx}, /* PC15 */
};
其实就是个小数组,它储存的是每个GPIO地址以及作用,和32的flash大小相比也不算很占空间,改动的可能性不大,毕竟牵一发而动全身。
它有一套很像标准外设库的东西,如果追求IO翻转速度的话可以直接调用,例如下面这个是digitalWrite函数:
void digitalWrite(uint8 pin, uint8 val) {
if (pin >= BOARD_NR_GPIO_PINS) {
return;
}
gpio_write_bit(PIN_MAP.gpio_device, PIN_MAP.gpio_bit, val);
}
可以看到一个gpio_write_bit函数,直接操作寄存器了,下面是它的原型:
static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) {
val = !val; /* "set" bits are lower than "reset" bits*/
dev->regs->BSRR = (1U << pin) << (16 * val);
}
如果想让PB12输出一个高电平,一般写法:
digitalWrite(PB12,HIGH);
高效一点的:
gpio_write_bit(&gpiob,12,1);
再高效一点:
(&gpiob)->regs->BSRR = (1U << 12) << (16 * 0);
51单片机听说跑C++效率很低,移植的可能性应该不大,不过听说有一个51duino,可以搜搜看。
STM8单片机还真有人搞过,这是链接:https://github.com/tenbaht/sduino maxims 发表于 2017-12-20 21:48
这么说,懂了。
那么有个不情之请,有没有可能优化一下arduino的底层资料。
比如,优化它编译之后,不 ...
STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K FASTSHIFT 发表于 2017-12-21 13:30
这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP = {
{&gpioa, &timer2, &adc1,0, ...
谢谢····
我研究下STM8去 FASTSHIFT 发表于 2017-12-21 13:37
STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K
主要是STM32的Arduino好像对库的支持不够好 这个( ఠൠఠ )ノ×,STM32又多了一种实用的新玩法 FASTSHIFT 发表于 2017-12-21 13:30
这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP = {
{&gpioa, &timer2, &adc1,0, ...
STM8那个,你测试过没有?
我试用了一下,研究了一下,感觉就blink这个能用,按键读取好像偶尔可以。其他自带的demo比如iic、minissd1306,这些都不能编译 大大的赞一个
maxims 发表于 2017-12-24 18:42
主要是STM32的Arduino好像对库的支持不够好
其实想深入玩,我认为就不能太依赖别人写好的库,毕竟每个库都不能完全做到百分百兼容所有单片机,有时候还得打开库的源码进行修改,分析实现过程。
我觉得STM32duino能做到这种程度已经非常不错了,从它的源码可以看出这个开发团队对STM32的底层以及Arduino的底层十分熟悉。
页:
[1]
2