查看: 2649|回复: 2

试用————GPIO模块

[复制链接]
  • TA的每日心情

    2016-3-28 21:00
  • 签到天数: 117 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2013-10-27 19:52:28 | 显示全部楼层 |阅读模式
    分享到:
    int main(void)
    {
             sysclk_init();
             board_init();
             while (1){
                       gpio_toggle_pin(LED0_GPIO);
                       delay_ms(500);
             }
    }
    找到函数,gpio_toggle_pin(LED0_GPIO);的出处;可以找到如下代码
    #define gpio_toggle_pin(io_id)
             ioport_toggle_pin(io_id)
    然后找到ioport_toggle_pin(io_id)函数。如下
    __always_inline static inline void ioport_toggle_pin(port_pin_t pin)
    {
             arch_ioport_toggle_pin_level(pin);
    }
    再找arch_ioport_toggle_pin_level(pin);函数
    _always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
    {
             PORT_t *base = arch_ioport_pin_to_base(pin);
             base->PINCRL = arch_ioport_pin_to_mask(pin);
    }
    可以看到对结构体成员的PINCRL赋值,可以找到结构体如下
    typedef struct PORT_struct {
             volatile uint8_t PINCRL;         /*I/O Port PIN DATA READ ONLY */
             volatile uint8_t DIR;            /*I/O Port Data Direction Set */
             volatile uint8_t PORTDATA;       /* I/OPort DATA register */
    } PORT_t;
    这个结构体定义了PORT读写的结构体的成员,并对成员PINCRL成员赋值
    先看看PORT_t *base = arch_ioport_pin_to_base(pin);这个函数,这个函数是定义了一个指向PORT_t的指针,找到arch_ioport_pin_to_base(pin)函数
    __always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin)
    {
             return arch_ioport_port_to_base(pin >> 3);
    }
    再找到arch_ioport_port_to_base(pin >> 3)函数
    __always_inline static PORT_t *arch_ioport_port_to_base(uint8_t port)
    {
             return (PORT_t *)((uintptr_t)(IOPORT_BASE_ADDRESS +
                   (port * IOPORT_PORT_OFFSET)));
    }
    很容易的看到,这个指针的地址IOPORT_BASE_ADDRESS +(port * IOPORT_PORT_OFFSET),是端口的基地址加上偏移地址,可以分别找到基地址IOPORT_BASE_ADDRESS  0x20和偏移地址IOPORT_PORT_OFFSET  0x03
    然后看看base->PINCRL = arch_ioport_pin_to_mask(pin);这个函数对结构体PORT_t成员PINCRL赋值,看看arch_ioport_pin_to_mask(pin)这个函数
    __always_inlinestatic ioport_port_mask_t arch_ioport_pin_to_mask
             (ioport_pin_t pin)
    {
             return 1U << (pin & 0x07);
    }这个就是选择用到的PORT口,然后通过base->PINCRL = arch_ioport_pin_to_mask(pin)赋给PINCRL
    总体感觉这个底层库很复杂,原本一个函数就可以搞定的,还要分成3,4个,或者5,6个函数,不知道ATMEL公司的工程师是怎么想的,原本一个8位的单片机就应该很容易入门的,非要搞得这么复杂,要搞定它还是需要大量的时间。大量的宏定义,比如
    typedef uint8_t ioport_mode_t;
    typedef uint8_t ioport_pin_t;
    typedef uint8_t ioport_port_t;
    typedef uint8_t ioport_port_mask_t;
    非要定义这么多干嘛,刚开始就被这个搞晕了,看着就头痛,ATMEL工程师真的智商我是跟不上。本人感觉款单片机虽然是8位的,但不适合新手入门。

    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2024-10-28 10:11
  • 签到天数: 1703 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2013-10-28 09:15:26 | 显示全部楼层
    这些定义都分别在哪个文件里呢?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2016-3-28 21:00
  • 签到天数: 117 天

    连续签到: 1 天

    [LV.6]常住居民II

     楼主| 发表于 2013-10-28 09:35:48 | 显示全部楼层
    nemon 发表于 2013-10-28 09:15
    这些定义都分别在哪个文件里呢?

    在不同的.h和.c可以goto到函数的地方
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 23:14 , Processed in 0.129126 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.