查看: 9668|回复: 1

RT1052——4.GPIO与外部中断

[复制链接]
  • TA的每日心情
    慵懒
    2025-5-7 08:45
  • 签到天数: 279 天

    连续签到: 1 天

    [LV.8]以坛为家I

    114

    主题

    1314

    帖子

    29

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    11056

    热心会员

    最后登录
    2025-8-17
    发表于 2018-10-27 19:10:07 | 显示全部楼层 |阅读模式
    今天看了看RT1052的GPIO,感觉这玩意比STM32复杂多了,今天我们来尝试了解一下它先从LED点灯开始。

    QQ截图20181027140320.png

    QQ截图20181027140302.png


    可以看出飞凌底板上的LED是连接的GPIO1_IO02脚。 首先放出例程的配置方式(删除了注释)

      IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09,  0U);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09,  0x10B0u);                              

    其中
    #define IOMUXC_GPIO_AD_B0_09_GPIO1_IO09
    0x401F80E0U, 0x5U, 0, 0, 0x401F82D0U

    这红色的字体就是这次配置的关键了。首先看IOMUXC_SetPinMux函数
    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) = inputDaisy;
        }
    }

    #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK      (0x7U)
    #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT     (0U)
    #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(x)        (((uint32_t)(((uint32_t)(x)) << IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT)) & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK)
    #define IOMUXC_SW_MUX_CTL_PAD_SION_MASK          (0x10U)
    #define IOMUXC_SW_MUX_CTL_PAD_SION_SHIFT         (4U)
    #define IOMUXC_SW_MUX_CTL_PAD_SION(x)            (((uint32_t)(((uint32_t)(x)) << IOMUXC_SW_MUX_CTL_PAD_SION_SHIFT)) & IOMUXC_SW_MUX_CTL_PAD_SION_MASK)
    可以看出,我们配置了0x401F80E0U的第0—2位为0x5U,第4位为0

    我们来看一下这个0x401F80E0U到底是个什么地址
    QQ截图20181027190728.png
    可以看出来,第4位为0时可以设置功能复用,而0—2位设置的是功能复用,这里设置为GPIO1功能

    然后是IOMUXC_SetPinConfig函数
    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;
        }
    }
    可以看出是配置0x401F82D0U0x10B0u
    我们来看一下0x401F82D0U是什么
    QQ截图20181027144234.png
    QQ截图20181027144250.png
    可以看出来这里是对引脚功能的设置,这里的0x10B0u就是设置为 转化速率慢,驱动强度为R0/6,速度100MHz,关闭开漏,开启拉/保持器,选择为保持,100K下拉(无用),关闭滞回。
    感觉写这么一个数不好理解,我改写了一下这个函数

    //转换速率       0 慢     1 快
    //驱动强度       0 无     1 R0     2 R0/2   3 R0/3    4 R0/4    5 R0/5    6 R0/6    7 R0/7
    //输出速度       0 50MHz  1 100MHz   2 100MHz   3 200MHz
    //开漏输出       0 关闭   1 开启
    //拉/保持器      0 关闭   1 开启
    //拉/保持器设置  0 保持    1 拉
    //上下拉电阻     0 100K下拉   1 47K上拉   2 100K上拉   3 22K上拉
    //滞回器设置     0 关闭       1开启
    IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_02_GPIO1_IO02, IOMUXC_SW_PAD_CTL_PAD_SRE(0)    //转换速率慢
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_DSE(6)    //驱动强度R0/6
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_SPEED(2)  //速度100MHz
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_ODE(0)    //关闭开漏
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_PKE(1)    //拉/保持器开启
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_PUE(0)    //选择为保持
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_PUS(0)    //100K下拉(没用到)
                                                                                            |IOMUXC_SW_PAD_CTL_PAD_HYS(0));  //关闭滞回
    感觉这样更容易理解,更容易操作一点。

    接下来就是配置GPIO了,下面只放出关键程序

    gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; //设为输出 默认输出0 无中断
    GPIO_PinInit(GPIO1, 2, &led_config);

    这两句很好理解,首先设置led_config

    typedef struct _gpio_pin_config
    {
        gpio_pin_direction_t direction;                 //设置输出方向
        uint8_t outputLogic;                               //设置初始电平
        gpio_interrupt_mode_t interruptMode;     //设置中断模式
    } gpio_pin_config_t;

    里面有这三个成员 取值如下

    typedef enum _gpio_pin_direction
    {
        kGPIO_DigitalInput = 0U,  //输入
        kGPIO_DigitalOutput = 1U, //输出
    } gpio_pin_direction_t;

    typedef enum _gpio_interrupt_mode
    {
        kGPIO_NoIntmode = 0U,                 //无中断
        kGPIO_IntLowLevel = 1U,                //低电平中断
        kGPIO_IntHighLevel = 2U,               //高电平中断
        kGPIO_IntRisingEdge = 3U,              //上升沿中断
        kGPIO_IntFallingEdge = 4U,             //下降沿中断
        kGPIO_IntRisingOrFallingEdge = 5U, //上升下降沿中断
    } gpio_interrupt_mode_t;

    就是把GPIO1_2配置为输出模式,默认输出1,无中断。(这里的寄存器也没啥好分析的,接下来就不讨论了寄存器了)

    GPIO_PinWrite(GPIO1, 2, 0U);//点亮LED
    delay(10);
    GPIO_PinWrite(GPIO1, 2, 1U);//熄灭LED
    delay(10);

    相当简单的程序 运行结果就是灯一闪一闪的,效果见视频附件

    接下来是GPIO输入 参考原理图



    QQ截图20181027194521.png
    QQ截图20181027194547.png

    嗯,这GPIO5_0就是我们要的。对他进行配置



    IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0U);         //复用为GPIO
    IOMUXC_SetPinConfig(IOMUXC_SNVS_WAKEUP_GPIO5_IO00,   IOMUXC_SW_PAD_CTL_PAD_SRE(0)    //转换速率慢
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_DSE(0)    //无驱动强度
    (没用到)
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_SPEED(2)  //速度100MHz
    (没用到)
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_ODE(0)    //关闭开漏(没用到)
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_PKE(1)    //拉/保持器开启
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_PUE(1)    //选择为拉
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_PUS(3)    //22K上拉
                                                                                              |IOMUXC_SW_PAD_CTL_PAD_HYS(0));  //关闭滞回

    这里我们把它设为了22K上拉(这里只能配置为,拉/保持器开启,选择为拉。具体原因应该是RT1052把使能上下拉设为了输入专用了。而输出使用的是配置开漏,和配置驱动能力)。下面是main里程序(省略很多)


    gpio_pin_config_t key_config = {kGPIO_DigitalInput, 0, kGPIO_NoIntmode};  //设为输入 默认输出0 无中断
    GPIO_PinInit(GPIO5, 0, &key_interrupt_config);
    while(1)
    {
            GPIO_PinWrite(GPIO1, 2, GPIO_PinReadPadStatus(GPIO5,0));
    }

    补充一句,如果设置为输入模式那么默认输出电平就不起作用
    这里的GPIO_PinReadPadStatus是一个读取引脚电平的函数,运行结果是按住按键灯亮,松开灭。


    接下来是配置外部中断。参考MIMXRT1052.h


    QQ截图20181027174726.png

    可以发现包含GPIO5_0的中断是GPIO5_Combined_0_15_IRQn,中断回调函数是GPIO5_Combined_0_15_IRQHandler(MIMXRT1052.s有定义)
    还是和刚才一样配置引脚模式,下面是main里程序(省略很多)

            gpio_pin_config_t key_interrupt_config = {kGPIO_DigitalInput, 1, kGPIO_IntFallingEdge};  //设为输入 默认输出0 下降沿中断

            EnableIRQ(GPIO5_Combined_0_15_IRQn);//使能中断
            GPIO_PinInit(GPIO5, 0, &key_interrupt_config);
            GPIO_PortEnableInterrupts(GPIO5, 1U << 0); //使能特定引脚中断

    中断回调函数

    void GPIO5_Combined_0_15_IRQHandler(void)
    {
            delay(1);          //消除抖动
        if(GPIO_PinReadPadStatus(GPIO5, 0) == 0)  //二次判断
                    GPIO_PortToggle(GPIO1,1<<2);      //灯取反
            GPIO_PortClearInterruptFlags(GPIO5, 1 << 0);  //清除中断标志位
        __DSB();
    }


    这里的代码和普通的代码差不多,就不分析了。
    比较有意思的是这个__DSB();它的作用是只有CPU把这句话之前的代码全部执行完毕后才能继续向下执行。
    最后的效果是按下按键后灯转换状态补充一点如果不需要go to什么的,可以把output里的两个输出去掉,大大加快了编译速度
    QQ截图20181027203217.png
    最后不得不吐槽一句底板的绿灯有点太亮了。。。。。晚上拍的视频看着特别显眼。

    最后附上程序和视频
      MDK版本:5.24
      pack:NXP.MIMXRT1052_DFP.10.0.1.pack
      下载算法:飞凌嵌入式提供的 MIMXRT_QSPIFLASH.FLM
      启动方式:spi flash启动  
      下载方式:STlink

    led.zip

    1.46 MB, 下载次数: 43, 下载积分: 威望 1

    工程

    LED输出.zip

    2.1 MB, 下载次数: 36, 下载积分: 威望 1

    gpio输出现象

    按键(无中断).zip

    3.09 MB, 下载次数: 20, 下载积分: 威望 1

    gpio输入现象

    按键(有中断).zip

    4.05 MB, 下载次数: 22, 下载积分: 威望 1

    外部中断现象

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3917

    主题

    7535

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39887
    最后登录
    2025-8-18
    发表于 2018-10-29 13:16:55 | 显示全部楼层
    学习了,谢谢分享
    qiandao qiandao
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-19 03:57 , Processed in 0.079019 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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