FASTSHIFT 发表于 2017-12-15 19:34:13

如何在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

FASTSHIFT 发表于 2019-2-17 22:23:39

xo37 发表于 2019-1-20 21:08
嗯,不过,第三方的兼容性要是提高就很牛了……

像有些库为了最大化利用AVR性能,会直接操作寄存器,例如IRremote,SoftwareSerial,Arduboy等,这些库比较难实现跨平台

yhy630 发表于 2017-12-15 20:29:19

学习了,强

001 发表于 2017-12-16 11:17:27

:victory:不错,不错

老胖熊 发表于 2017-12-16 17:36:56

不错,这样又多了一种玩法。

maxims 发表于 2017-12-19 18:18:54

这么移植的意义何在?

FASTSHIFT 发表于 2017-12-19 22:54:32

本帖最后由 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

maxims 发表于 2017-12-20 21:48:20

FASTSHIFT 发表于 2017-12-19 22:54
1.既可以兼容传统的库,又可以使用Arduino的库(比如Arduino的Print库,可以挂在USART、TFT、OLED等需 ...

这么说,懂了。
那么有个不情之请,有没有可能优化一下arduino的底层资料。
比如,优化它编译之后,不是查表控制IO口,这个表占用比较多的flash存储空间,也导致io翻转速度不够什么的。
或者把比如STC、STM8之类的移植过Arduino IDE环境?

FASTSHIFT 发表于 2017-12-21 13:30:55

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

FASTSHIFT 发表于 2017-12-21 13:37:07

maxims 发表于 2017-12-20 21:48
这么说,懂了。
那么有个不情之请,有没有可能优化一下arduino的底层资料。
比如,优化它编译之后,不 ...

STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K

maxims 发表于 2017-12-24 18:41:31

FASTSHIFT 发表于 2017-12-21 13:30
这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP = {
    {&gpioa, &timer2, &adc1,0, ...

谢谢····
我研究下STM8去

maxims 发表于 2017-12-24 18:42:28

FASTSHIFT 发表于 2017-12-21 13:37
STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K

主要是STM32的Arduino好像对库的支持不够好

王力斯 发表于 2017-12-25 08:57:33

这个( ఠൠఠ )ノ×,STM32又多了一种实用的新玩法

maxims 发表于 2017-12-25 16:04:33

FASTSHIFT 发表于 2017-12-21 13:30
这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP = {
    {&gpioa, &timer2, &adc1,0, ...

STM8那个,你测试过没有?
我试用了一下,研究了一下,感觉就blink这个能用,按键读取好像偶尔可以。其他自带的demo比如iic、minissd1306,这些都不能编译

Hackerpro 发表于 2017-12-25 20:12:33

大大的赞一个


FASTSHIFT 发表于 2017-12-27 16:41:33

maxims 发表于 2017-12-24 18:42
主要是STM32的Arduino好像对库的支持不够好

其实想深入玩,我认为就不能太依赖别人写好的库,毕竟每个库都不能完全做到百分百兼容所有单片机,有时候还得打开库的源码进行修改,分析实现过程。
我觉得STM32duino能做到这种程度已经非常不错了,从它的源码可以看出这个开发团队对STM32的底层以及Arduino的底层十分熟悉。
页: [1] 2
查看完整版本: 如何在Keil MDK5环境使用Arduino函数以及第三方库(适用STM32)