查看: 4072|回复: 3

[原创] 【LPC11U68】5. GPIO小试牛刀

[复制链接]
  • TA的每日心情
    奋斗
    昨天 20:47
  • 签到天数: 1485 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93126
    最后登录
    2024-5-8
    发表于 2018-11-2 21:32:26 | 显示全部楼层 |阅读模式
    本帖最后由 stm1024 于 2018-11-3 10:07 编辑

    前面把Systick搞定之后,延时就可以解决了。接下来肯定要对GPIO好好研究一番,GPIO是微控制器外设的精髓,把这玩意儿玩通了,可以实现一些时序逻辑,PWM波输出,甚至模拟一些协议(当然有硬件外设肯定是优先使用硬件外设了)。
    LPC11U68一共有100个PIN,根据手册LPC11U6x User Manual上的说明,P0的0~23 Port可用,P1的0~31 Port可用、P2和P0一样,是0~23 Port可用。
    这个芯片的GPIO口有如下特征:
    2018-11-02_211637.png
    可被配置为输入和输出,所有的PIN都被配置为中断失能的输入模式,Pin寄存器允许各Pin能被独立地配置。

    首先看schmetic知道了板子上的三色LED灯分别对应的是GPIO2的16,17,18号Port:
    22.png
    这样我们就知道,如果对应的PORT口为低电平,则电路导通,LED点亮,如果为高电平,则LED被截止,LED不亮。
    因此我们需要知道如何配置这些GPIO口和翻转IO口,先来一个快速检验的代码:
    1. int main()
    2. {
    3.     Board_Init();
    4.     while(1)
    5.     {
    6.         Board_LED_Toggle(0);
    7.         Delay_ms(1000);
    8.     }
    9. }
    复制代码
    红色LED正确翻转,没毛病。如果把参数粉笔修改为1,或者2,则对应的绿色和蓝色LED分别闪烁。
    但是我们需要知道原因。
    打开LPCOpen中的Board.c,查看代码,知道:
    1. void Board_LED_Toggle(uint8_t LEDNumber)
    2. {
    3.         if (LEDNumber < MAXLEDS) {
    4.                 Chip_GPIO_SetPinToggle(LPC_GPIO, ledports[LEDNumber], ledpins[LEDNumber]);
    5.         }
    6. }
    复制代码
    现在肯定是再找Chip_GPIO_SetPinToggle,在文件gpio_11u6x.h中:
    1. STATIC INLINE void Chip_GPIO_SetPinToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
    2. {
    3.         pGPIO->NOT[port] = (1 << pin);
    4. }
    复制代码
    显然是把某位取反。
    可以把代码简化:
    1. int main()
    2. {
    3.     Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO);
    4.     LPC_GPIO->DIR[2] |= 1UL << 16;
    5.     while(1)
    6.     {
    7.         LPC_GPIO->NOT[2]=(1<<16);
    8.         Delay_ms(1000);
    9.     }
    10. }
    复制代码
    看,我们连Board_Init()都省去了,直接使能GPIO口的RCC(如果仔细研究一下LPC_SYSCTL_BASE,也可以使用类似操作寄存器的方式),此外,我还发现,这个RCC默认是打开的(没仔细核对文档),因此删除Enable RCC的函数也是可以的。然后配置Port2的Pin16为输出模式,使用NOT字段,直接翻转当前状态。注意,只有配置为output的PIN才能这么使用。
    NXP和STM32(以及很多其他的微处理器)采用了类似的方式,把GPIO口的存储地址取了别名,GPIO口的基地址就是LPC_GPIO(本质上是LPC_GPIO_PORT_BASE ,0xA0000000),然后定义了一个结构体LPC_GPIO_T,其他还有很多的结构体和函数,大家可以慢慢研究一下。
    再改写一下,你可能就有点懵逼了:
    1. int main()
    2. {
    3.     LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 6);
    4.     LPC_GPIO->DIR[2] |= 1UL << 16;
    5.     while(1)
    6.     {
    7.         LPC_GPIO->NOT[2]=(1<<16);
    8.         Delay_ms(1000);
    9.     }
    10. }
    复制代码
    其实本质上是追踪函数实现,修改之后的产物,如果再修改,就直接上储存器地址了
    公司的小朋友都不帮我焊排针,其他的针脚或者多个针脚的测试,就没法玩了。
    这个MCU和STM32系列的GPIO配置各有千秋,总体上来说,LPC的相对要简单一点,蜻蜓点水般的只学了点皮毛,见笑了。  
    最后吐槽一下,大家收到板子以后,学到的知识别藏着掖着,多交流一下嘛,当然如果是憋大招的,就另当别论了。




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

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 20:47
  • 签到天数: 1485 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93126
    最后登录
    2024-5-8
     楼主| 发表于 2018-11-2 21:34:11 | 显示全部楼层
    沙发要自己坐。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2021-2-4 09:24
  • 签到天数: 190 天

    [LV.7]常住居民III

    38

    主题

    591

    帖子

    28

    金牌会员

    Rank: 6Rank: 6

    积分
    2193
    最后登录
    2023-12-1
    发表于 2018-11-2 21:49:34 | 显示全部楼层
    谢谢分享,板子上的LED闪瞎眼啊
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 20:47
  • 签到天数: 1485 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93126
    最后登录
    2024-5-8
     楼主| 发表于 2018-11-2 21:53:01 | 显示全部楼层
    mzy2364 发表于 2018-11-2 21:49
    谢谢分享,板子上的LED闪瞎眼啊

    我的钛合金狗眼已瞎
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-5-9 04:39 , Processed in 0.140973 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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