极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 6027|回复: 16

成功在Keil MDK5环境移植Arduino库,给STM32编程

[复制链接]
发表于 2017-12-15 19:34:13 | 显示全部楼层 |阅读模式
本帖最后由 FASTSHIFT 于 2017-12-15 19:35 编辑

    发现Keil5也可以使用C++编程,而Arduino的库又是C++写的,所以就试了一下能不能把Arduino的库移植到Keil给STM32用,没想到还真可以。

编程对比图

编程对比图

编程对比图

KM$N~QKPL)LJV]40_WS4]7T.png
测试DS3231库

RYH3EQL`6K$IC[K(OX4JTLJ.png
底层实现

工程下载:https://github.com/FASTSHIFT/Arduino-For-Keil


回复

使用道具 举报

发表于 2017-12-16 17:36:56 | 显示全部楼层
不错,这样又多了一种玩法。
回复 支持 反对

使用道具 举报

发表于 2017-12-19 18:18:54 | 显示全部楼层
这么移植的意义何在?

回复 支持 反对

使用道具 举报

 楼主| 发表于 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核的片子也不成问题。

优点暂时想了这么多
回复 支持 反对

使用道具 举报

发表于 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环境?
回复 支持 反对

使用道具 举报

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

这个PIN_MAP我翻了一下,
extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
    {&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[pin].gpio_device, PIN_MAP[pin].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
回复 支持 反对

使用道具 举报

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

STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K
回复 支持 反对

使用道具 举报

发表于 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去
回复 支持 反对

使用道具 举报

发表于 2017-12-24 18:42:28 | 显示全部楼层
FASTSHIFT 发表于 2017-12-21 13:37
STM32duino的优化其实挺不错的,它的digitalWrite的速度还比我写的快200K

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

使用道具 举报

发表于 2017-12-25 08:57:33 | 显示全部楼层
这个( &#3104;&#3424;&#3104; )&#65417;×,STM32又多了一种实用的新玩法
回复 支持 反对

使用道具 举报

发表于 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,这些都不能编译
回复 支持 反对

使用道具 举报

发表于 2017-12-25 20:12:33 | 显示全部楼层
大大的赞一个


回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-27 16:41:33 | 显示全部楼层
maxims 发表于 2017-12-24 18:42
主要是STM32的Arduino好像对库的支持不够好

其实想深入玩,我认为就不能太依赖别人写好的库,毕竟每个库都不能完全做到百分百兼容所有单片机,有时候还得打开库的源码进行修改,分析实现过程。
我觉得STM32duino能做到这种程度已经非常不错了,从它的源码可以看出这个开发团队对STM32的底层以及Arduino的底层十分熟悉。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2018-12-16 16:22 , Processed in 0.166296 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表