一 、概述
前面一篇博文通过讲述在 MCUXpresso IDE 进行配置 GPIO 的引脚,所以这一篇博文具体讲讲 GPIO 配置的寄存器,毕竟打小就被告诫不能做不三不四的人,但是也不能那么二只会用配置工具,里面寄存器怎么配置也要懂一丢丢的 ~
二、寄存器配置 GPIO 入门
- 习惯使用用户手册
翻到手册 I/O Pin Configuration 这一章节,如图 1 所示,我们可以看到 IO 口的配置的几个重要模式和功能(上下拉模式,转换速率,开漏模式,输入倒转功能),这里介绍要配置这几个参数需要开启 IOCON 的时钟在 AHBCLKCTRL0 寄存器当中。
- IO 引脚的IOCON 寄存器描述
IOCON 寄存器描述了每一个 IO 引脚都可以使用这个寄存器,但是不同的引脚所对应的寄存器类型不太一样,如图 2 所示,其中的区别就是每一个具体 IO 引脚所配置的功能不一样,例如 D类型只能配置数字引脚,A 类型的可以选择模拟引脚和数字引脚(模拟的引脚常见的是作为 ADC 输入等功能来使用),I 类型指的是该 IO 引脚可以复用为 I2C 通信接口时需要在这里配置它的 I2C 功能的一些特性。
具体的功能配置区别这里不做详细叙述,这里只介绍如何配置 GPIO 的寄存器作为普通引脚来使用。
图2 I/O Pin Configuration 描述
- IOCON 寄存器具体描述
了解到 IO 引脚在 IOCON 寄存器的配置,其中配置为普通 IO 引脚一般只用到 IOCON 寄存器的 9 ~ 0 bit , 如图 3 所示,这 10个 bit 的配置值得具体描述分为6个分别是: FUNC(3:0 bit), MODE(5:4 bit), SLEW(6 bit), INVERT(7 bit), DIGIMODE(8 bit), OD(9 bit), 这里要注意的就是功能 FUNC 的配置,由于只是配置为普通 IO 口,这 4 个 bit 默认为 0 即可(IO 口配置为其他的功能需要具体的去查表,这里不做多描述)。
图3 IOCON 寄存器 9 ~ 0 bit具体描述
- 还没完,GPIO 的寄存器才开始
话不多说,大致了解通用 GPIO 章节的介绍后,直接看寄存器,发现寄存器有点多,如图 4 所示,至此知道前面的寄存器只是通用的配置 GPIO 的功能模式等,具体的 IO 口配置的方向,电平状态还是需要这些寄存器进一步配置,这里会着重介绍这几个常用的寄存器,然后就可以直接起飞去配置寄存器了 ~ ~
这里的寄存器分为 0 组 和 1 组,主要是 LPC55S69 有两组 GPIO , IO 口电平相关的寄存器一般用到 :
B 寄存器读写 IO 引脚GPIO -> B[port][pin] = output; 或者读回 return GPIO -> B[port][pin];
SET 寄存器设置 IO 引脚的高电平 GPIO -> SET[port] = mask;(mask 是 32 位的数据)
CLR 寄存器清除引脚的高电平状态 GPIO -> CLR[port] = mask;(mask 是 32 位的数据)
NOT 寄存器翻转引脚的电平状态 GPIO -> NOT[port] = mask; (mask 是 32 位的数据)
其他的 IO 口 Port 和 Pin 电平相关的寄存器请参考寄存器的详细描述。
IO 口方向相关的寄存器一般用到 :DIR 寄存器设置引脚方向 GPIO -> DIR[port] = pin;(0 输入,1输出,pin 是 32 位数据)
- 现在可愉快的配置寄存器了
这里举个例子,用配置寄存器的方法实现 :三个按键分别控制 RGB 灯翻转,初始化灯全部亮。
以下是主函数的代码,仅供参考,在 BOARD_InitPins(); 里面仅配置 UART 引脚。
- 下载烧录的效果
烧录到开发板的效果就不演示了,具体的效果脑补一下就明明白白了,这里主要是带大家一起熟悉寄存器的操作。
int main(void)
{
uint32_t s1_state = 0;
uint32_t s2_state = 0;
uint32_t s3_state = 0;
uint32_t modefunc = IOCON_PIO_FUNC0 |
IOCON_PIO_MODE_INACT |
IOCON_PIO_SLEW_STANDARD |
IOCON_PIO_INV_DI |
IOCON_PIO_DIGITAL_EN |
IOCON_PIO_OPENDRAIN_DI;
uint32_t Smodefunc = modefunc | IOCON_PIO_MODE_PULLUP;
/* Board pin, clock, debug console init */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/******IO Configuration ******/
CLOCK_EnableClock(kCLOCK_Iocon);
IOCON->PIO[0][10] = Smodefunc; //S1
IOCON->PIO[0][18] = Smodefunc; //S2
IOCON->PIO[1][18] = Smodefunc; //S3
IOCON->PIO[1][4] = modefunc; //LED1
IOCON->PIO[1][6] = modefunc; //LED2
IOCON->PIO[1][7] = modefunc; //LED3
//CLOCK_DisableClock(kCLOCK_Iocon);//save power
/* enable clock for GPIO*/
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
GPIO->DIR[0] &= ~0x40400;//S1 S2 S3 input
GPIO->DIR[1] &= ~0x40000;//S3 input
GPIO->DIR[1] |= 0xD0;//LED1 LED2 LED3 output
GPIO->B[1][4] = 0;//LED1 output 0
GPIO->B[1][6] = 0;//LED2 output 0
GPIO->B[1][7] = 0;//LED3 output 0
BOARD_InitPins();
BOARD_BootClockPLL100M();
BOARD_InitDebugConsole();
/* Print a note to terminal. */
PRINTF("\r\n GPIO Driver example\r\n");
PRINTF("\r\n The LED is taking turns to shine.\r\n");
/* Set systick reload value to generate 1ms interrupt */
SysTick_Config(SystemCoreClock / 1000U);
while (1)
{
s1_state = GPIO->B[0][10];
s2_state = GPIO->B[0][18];
s3_state = GPIO->B[1][18];
if (!s1_state)
{
PRINTF("\r\n s1 state: %x\r\n", s1_state);
GPIO->NOT[1] = 1u << 4;
}
if (!s2_state)
{
PRINTF("\r\n s2 state: %x\r\n", s2_state);
GPIO->NOT[1] = 1u << 6;
}
if (!s3_state)
{
PRINTF("\r\n s3 state: %x\r\n", s3_state);
GPIO->NOT[1] = 1u << 7;
}
/* Delay 1000 ms */
SysTick_DelayTicks(1000U);
}
}
三、总结与参考
- 官方的 SDK 例程和数据手册很重要,容易让用户很快熟悉并应用
- 开发环境 MCUXpresso IDE 也是很强大,非常方便用户
- 提供用户手册参考和原理图参考
《 LPC55S69-SCH.pdf 》
《 UM11126_LPC55S6x_LPC55S2x_LPC552x User manual.pdf 》
- 提供修改后的 gpio_led_output.c 的参考代码
- 后续会慢慢深入介绍其他的外设,敬请期待
【LPC55 系列】LPC55S69 开发之 ADC 详解
【LPC55 系列】LPC55S69 开发之 SysTick 详解
【LPC55 系列】LPC55S69 开发之 Ctimer 详解
……
END 阿里嘎多!!!
评论
mosu
2021年9月25日