• 五.NXP恩智浦官方SDK使用


    恩智浦针对I.MX6ULL编写了一个SDK包,这个包类似STM32的标准库或者HAL库,这个SDK包含了Windows和Linux两种版本。下载链接可以点击下载,链接失效了还可以从这下:

    https://pan.baidu.com/s/1L4OgqBiejZJFOmOxTVjtBw

    提取码:slhm
    我是用的Ubuntu20.04。修改完权限以后用./执行run文件即可,安装路径为主目录下。

    定义数据类型

    SDK包里会有很多数据类型,我们要先定义数据类型。

    移植文件

    SDK安装完成后,我们主要用到文件是

    • fsl_common.h——公共库文件
    • fsl_iomuxc.h
    • MCIMX6Y2.h

    这几个文件的路径是在我们安装的SDK文件夹下。要对这三个文件做一些修改,过程不再赘述,把文件放在最后。这样就可以使用了。这里着重讲一个函数,先看下原来对GPIO进行初始化的方法

    /*初始化LED*/
    void led_init(void)
    {   
        // 复用、电气属性寄存器初始化
        IOMUX_SW_MUX->GPIO1_IO03 = 0x5;
        IOMUX_SW_PAD->GPIO1_IO03 = 0x10B0;
        // GPIO1方向寄存器,
        GPIO1->GDIR = 0x8;
    }

    是通过指针直接对寄存器赋值,而NXP提供的方法是定义了个宏

    void led_init(void)
    {   
        // 复用、电气属性寄存器初始化
        IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
        IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10B0);
        // GPIO1方向寄存器,
        GPIO1->GDIR = 0x8;

    和原来的方法不一样,下面着重讲一下这两个函数,后面用到的概率比较大。

    SetPinMux

    我们先看下库文件对函数的定义

    /*!
     * @brief Sets the IOMUXC pin mux mode.
     * @note The first five parameters can be filled with the pin function ID macros.
     *
     * This is an example to set the ENET1_RX_DATA0 Pad as FLEXCAN1_TX:
     * @code
     * IOMUXC_SetPinMux(IOMUXC_ENET1_RX_DATA0_FLEXCAN1_TX, 0);
     * @endcode
     *
     * This is an example to set the GPIO1_IO02 Pad as I2C1_SCL:
     * @code
     * IOMUXC_SetPinMux(IOMUXC_GPIO1_IO02_I2C1_SCL, 0);
     * @endcode
     *
     * @param muxRegister  The pin mux register.
     * @param muxMode      The pin mux mode.
     * @param inputRegister The select input register.
     * @param inputDaisy   The input daisy.
     * @param configRegister  The config register.
     * @param inputOnfield   Software input on field.
     */
    static inline void IOMUXC_SetPinMux(uint32_t muxRegister,
                                        uint32_t muxMode,
                                        uint32_t inputRegister,
                                        uint32_t inputDaisy,
                                        uint32_t configRegister,
                                        uint32_t inputOnfield)
    {
        *((volatile uint32_t *)muxRegister) =
            IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);
    
        if (inputRegister)
        {
            *((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy);
        }
    }

    注释很清楚,该函数是对IO引脚做复用设置的。函数形参有6个,看下传的参数IOMUXC_GPIO01_IO03_GFPIO1_IO03这个值。

    #define IOMUXC_GPIO1_IO03_GPIO1_IO03                         0x020E0068U, 0x5U, 0x00000000U, 0x0U, 0x020E02F4U
    IOMUXC_GPIO1_IO03_GPIO1_IO03  是一个被声明的宏,对应了5个参数,加上我们传的0刚好对应函数的6个形参。整个对应关系是这样的
    muxRegister         0x020E0068U
    muxMode             0x5U
    inputRegister       0x00000000U
    inputDaisy          0x0U
    configRegister      0x020E02F4U
    input Onfield       0

    有三个寄存器,其中两个地址已经在宏里定义好了,查手册可以发现,muxRegister是复用设置,设置的值就是muxMode,和原先设置的值是一样的

    所以下面的函数我们都不用看

     *((volatile uint32_t *)muxRegister) =
            IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);

    我们都知道他是将复用的模式设置给复用寄存器的。后面或了个inputOnfield是因为复用模式muxMode只是后3个bit,第4位还有个sion位,设置个0把他关闭掉。

     configRegister是电气属性设置

     这个参数在函数中实际是没有使用的。 原因下面会说到

    IOMUXC_SetPinConfig

    先看下函数的源代码

    /*!
     * @brief Sets the IOMUXC pin configuration.
     * @note The previous five parameters can be filled with the pin function ID macros.
     *
     * This is an example to set pin configuration for IOMUXC_GPIO1_IO02_I2C1_SCL:
     * @code
     * IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO02_I2C1_SCL, IOMUXC_SW_PAD_CTL_PAD_PUE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(2U));
     * @endcode
     *
     * @param muxRegister  The pin mux register.
     * @param muxMode      The pin mux mode.
     * @param inputRegister The select input register.
     * @param inputDaisy   The input daisy.
     * @param configRegister  The config register.
     * @param configValue   The pin config value.
     */
    static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,
                                           uint32_t muxMode,
                                           uint32_t inputRegister,
                                           uint32_t inputDaisy,
                                           uint32_t configRegister,
                                           uint32_t configValue)
    {
        if (configRegister)
        {
            *((volatile uint32_t *)configRegister) = configValue;
        }
    }

    我们会发现,函数的形参和前面讲复用配置的参数是一样的,并且我们传参的第一个宏也和前面一样。所以两个函数用到一个定义的宏。唯一的区别就是传入的第二个值(函数第6个形参)是0x10B0,看下函数里调用的方法,也是个传参,就是把configValue的值传递给configRegister寄存器里。和我们前面几张那个配置电气性能的赋值语句效果是一样的。

    这两个方法要熟练掌握,后面我们做裸机驱动的时候回经常用到。用的多了就熟练了。

  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/15744482.html
Copyright © 2020-2023  润新知