查看: 378|回复: 2

[技术] 【赚周年币】技术帖Week1-Day1——Fireduino深入浅出Digital...

[复制链接]

56

主题

1

好友

2580

积分

进士

Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    昨天 17:35
  • 签到天数: 765 天

    连续签到: 5 天

    [LV.10]以坛为家III

    爱板会员勋章 活跃会员勋章 发帖机器勋章 在线达人勋章

    发表于 2016-12-29 16:33:58 |显示全部楼层
    本帖最后由 wambob 于 2016-12-29 18:56 编辑

             Fireduino 的API和Arduino兼容。
            Fireduino 维基上介绍了三个:
    1. pinMode(pin,mode);
    复制代码
    打开wirish_digital.c这个文件,除了和Arduino的兼容文件名称相同外,函数实现不同,还有各自的其它函数。在Arduino中,让led BLINK使用了digitalWrite();
            在学习Cortex-m3的核的MCU时,曾经使用过togglePin()这样的函数来对I/O口输出翻转 ,加上延迟也可以实现led  BLINK。
    Fireduino 使用了digitalWrite()实现了togglePin()。
    1. void togglePin(unsigned char pin)
    2. {
    3.     if  (digitalRead(pin))
    4.                 digitalWrite(pin,0);
    5.         else
    6.                 digitalWrite(pin,1);
    7. }
    复制代码
    看到这也许回想到,能不能在Arduino也添加这样的函数呢?
          先写段码验证下togglePin()吧
    1. void setup() {
    2.   // put your setup code here, to run once:
    3. pinMode(13,OUTPUT);
    4. }

    5. void loop() {
    6.   // put your main code here, to run repeatedly:
    7. togglePin(13);
    8. delay(500);
    9. }
    复制代码
    编译上传。可见绿灯闪了起来。
           再来细看数字脚的源文件。开头三个头文件。
    1. #include "io.h"
    2. #include "ard_gpio.h"
    3. #include "wiring.h"
    复制代码
    其中io.h中枚举了管脚的模式宏定义了两个常量。其它的就是I/O驱动函数了。
       OUTPUT    ------输出模式
       INPUT    ------输入模式
       INPUT_PULLUP    ------上拉输入模式
       INPUT_PULLDOWN    ------下拉输入模式
    1. #define HIGH 0x1
    2. #define LOW  0x0
    复制代码
    第二个头文件只给了一些接口函数、宏定义和中断枚举模式。
    1. #define        BUTTON_DEBOUNCE_DELAY        1
    2. #define        BOARD_BUTTON_PIN                2
    3. #define        PIN_MAX        30
    4. enum int_tri_mode
    5. {
    6.         T_LOW = 0,
    7.         T_HIGH,
    8.         T_RISE,
    9.         T_FALL,
    10. };
    11. extern void ard_pin_mode(unsigned char pin, WiringPinMode mode);
    12. extern uint32_t ard_gpio_read(unsigned char pin);
    13. extern void ard_gpio_write(unsigned char pin, unsigned char val);
    14. extern void ard_gpio_int_enable(uint32_t pin,void (*callback)(void),enum int_tri_mode mode);
    15. extern void ard_gpio_int_disable(uint32_t pin);
    16. extern void interrupts(void);
    17. extern void noInterrupts(void);
    18. unsigned int _get_port(unsigned int  pin);
    19. unsigned int  _get_mask(unsigned int  pin);
    20. unsigned int*  _get_dr(unsigned int  port);
    21. unsigned int*  _get_ind(unsigned int  port);
    22. unsigned int*  _get_ddr(unsigned int  port);
    复制代码
    这个是MCU驱动的接口函数。
    第三个头文件里是延时函数的声明。
         先分析下pinMode();
    1. void pinMode(unsigned char pin, WiringPinMode mode)
    2. {
    3.    ard_pin_mode(pin,mode);
    4. }
    复制代码
    里面是个封装的函数。到这似乎没路了,打开官方的手册
    1.JPG


    2.JPG

    驱动MCU因该是下面几个函数。
    1. unsigned int _get_port(unsigned int pin);
    2. unsigned int _get_mask(unsigned int pin);
    3. unsigned int* _get_dr(unsigned int port);
    4. unsigned int* _get_ind(unsigned int port);
    5. unsigned int* _get_ddr(unsigned int port);
    复制代码
    第一个是获得外部引脚所在的端口;
    第二个是外部引脚在寄存器的的mask位;
    第三个是获得端口的数据输出寄存器地址
    第四个是获得端口的数据输入寄存器地址
    第五个是获得端口的数据方向寄存器的地址
    在Arduino.h中可以看
    1. #define digitalPinToPort(P)        ( _get_port(P))
    2. #define digitalPinToBitMask(P)     ( _get_mask(P) )
    3. #define portOutputRegister(port)   ( _get_dr(port) )
    4. #define portInputRegister(port)   ( _get_ind(port) )
    5. #define portDirectRegister(port)   ( _get_ddr(port) )
    复制代码
    数据寄存器
    3.JPG

    数据方向寄存器
    4.JPG

    下面就验证下,板上有两个灯,用3的LED验证下
    1. unsigned int  Port,Bit;
    2. void setup() {
    3.   // put your setup code here, to run once:
    4. //pinMode(13,OUTPUT);
    5.    Port =_get_port(3);       //3所在的端口
    6.    Bit =_get_mask(3);        //3的mask位
    7.   *_get_ddr(Port) |= Bit;    //设置方向为输出
    8. }

    9. void loop() {
    10.   // put your main code here, to run repeatedly:
    11. //togglePin(13);
    12. *_get_dr(Port) |=Bit;        //写3所在的数据寄存器的位为 1
    13. delay(500);
    14. *_get_dr(Port) &=~Bit;       //写3所在的数据寄存器的位为0
    15. delay(500);
    16. }
    复制代码
    编译上传,OK,蓝灯亮了。和使用接口函数一样的效果。








    已有 2 人评分 收起 理由
    EEboard爱板网 + 1
    loveeeboard + 20

    总评分:  + 21   查看全部评分

    回复

    使用道具 举报

    32

    主题

    13

    好友

    2100

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    开心
    昨天 09:11
  • 签到天数: 237 天

    连续签到: 11 天

    [LV.7]常住居民III

    爱板会员勋章 活跃会员勋章

    发表于 2016-12-30 18:11:45 |显示全部楼层
    介绍的很详细,赞一个。
    回复

    使用道具 举报

    56

    主题

    1

    好友

    2580

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    昨天 17:35
  • 签到天数: 765 天

    连续签到: 5 天

    [LV.10]以坛为家III

    爱板会员勋章 活跃会员勋章 发帖机器勋章 在线达人勋章

    发表于 2016-12-30 19:26:42 |显示全部楼层
    limale 发表于 2016-12-30 18:11
    介绍的很详细,赞一个。

    没有底层源文件,操作不了寄存器
    回复

    使用道具 举报

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

    关闭

    站长推荐上一条 /5 下一条

    手机版|爱板网 |网站地图  

    GMT+8, 2017-8-18 09:13 , Processed in 0.123484 second(s), 13 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部