上一篇介绍了对于GPIO的寄存器的操作,这篇主要讲讲GPIO的初始化。下面这段是例程中对于GPIO的初始化代码
void init_gpio()
{
//Set PTA19 and PTE26 (connected to SW1 and SW2) for GPIO functionality, falling IRQ,
// and to use internal pull-ups. (pin defaults to input state)
PORTA_PCR19=PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA)|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK;
PORTE_PCR26=PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA)|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK;
//Set PTA10, PTA11, PTA28, and PTA29 (connected to LED's) for GPIO functionality
PORTA_PCR10=(0|PORT_PCR_MUX(1));
PORTA_PCR11=(0|PORT_PCR_MUX(1));
PORTA_PCR28=(0|PORT_PCR_MUX(1));
PORTA_PCR29=(0|PORT_PCR_MUX(1));
//Change PTA10, PTA11, PTA28, PTA29 to outputs
GPIOA_PDDR=GPIO_PDDR_PDD(GPIO_PIN(10) | GPIO_PIN(11) | GPIO_PIN(28) | GPIO_PIN(29) );
}
分析如下:
(1) PORTA_PCR19=PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA)|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK;
#define PORTA_PCR19 PORT_PCR_REG(PORTA_BASE_PTR,19)
#define PORT_PCR_REG(base,index) ((base)->PCR[index])
/** PORT - Peripheral register structure */
typedef struct PORT_MemMap {
uint32_t PCR[32]; /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */
uint32_t GPCLR; /**< Global Pin Control Low Register, offset: 0x80 */
uint32_t GPCHR; /**< Global Pin Control High Register, offset: 0x84 */
uint8_t RESERVED_0[24];
uint32_t ISFR; /**< Interrupt Status Flag Register, offset: 0xA0 */
uint8_t RESERVED_1[28];
uint32_t DFER; /**< Digital Filter Enable Register, offset: 0xC0 */
uint32_t DFCR; /**< Digital Filter Clock Register, offset: 0xC4 */
uint32_t DFWR; /**< Digital Filter Width Register, offset: 0xC8 */
} volatile *PORT_MemMapPtr;
以上内容通过寻址指定到PORTA_PCR19.
等式右侧
PORT_PCR_MUX(1)|PORT_PCR_IRQC(0xA)|PORT_PCR_PE_MASK|PORT_PCR_PS_MASK
(1)PORT_PCR_MUX(1)
#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x))<<PORT_PCR_MUX_SHIFT))&PORT_PCR_MUX_MASK)
#define PORT_PCR_MUX_MASK 0x700u
#define PORT_PCR_MUX_SHIFT 8
这部分代码用来进行Port端口的复用功能的选择。以PTA19为例,在数据手册中对其的定义如下:
144 LQFP |
144 MAP BGA |
Pin Name | Default | ALT0 | ALT1 | ALT2 | ALT3 | ALT4 | ALT5 | ALT6 | ALT7 | EzPort |
73 | M11 | PTA19 | XTAL | XTAL | PTA19 | FTM1_FLT0 | FTM1_CLKIN1 | LPT0_ALT1 |
PCR(Port Control Register)寄存器中第8~10位用来对引脚的复用进行选择
Pin10~8 Function
000 Pin Disabled(analog)
001 Alternative 1
010 Alternative 2
011 Alternative 3
100 Alternative 4
101 Alternative 5
110 Alternative 6
111 Alternative 7
所以上面的操作过程中将1左移8位,即就是赋值mux(10~8)为001,即就是选择引脚PTA的复用为Alternative 1,即就是当作GPIO使用。
PORT_PCR_MUX_MASK的含义就是确保mux(10~8)的值不超过111,即不超过7
(2)PORT_PCR_IRQC(0xA)
#define PORT_PCR_IRQC_MASK 0xF0000u
#define PORT_PCR_IRQC_SHIFT 16
#define PORT_PCR_IRQC(x) (((uint32_t)(((uint32_t)(x))<<PORT_PCR_IRQC_SHIFT))&PORT_PCR_IRQC_MASK)
将0xA,即4‘b1010左移16位,从而将PCR寄存器中的IRQC19~16赋值为:1010.
PCR寄存器中的IRQC19~16位用来进行中断的配置
0000 Interrupt/DMA request disabled.
0001 DMA request on rising edge.
0010 DMA request on falling edge.
0011 DMA request on either edge.
0100 Reserved.
1000 Interrupt when logic zero.
1001 Interrupt on rising edge.
1010 Interrupt on falling edge.
1011 Interrupt on either edge.
1100 Interrupt when logic one.
Others Reserved
所以上面的配置是在下降沿出发中断。
(3)PORT_PCR_PE_MASK
#define PORT_PCR_PE_MASK 0x2u
#define PORT_PCR_PE_SHIFT 1
PCR寄存器中的PE(Pull Enable)位是用来使能内部拉电阻,置1为输入引脚使能内部拉电阻
(4)PORT_PCR_PS_MASK
#define PORT_PCR_PS_MASK 0x1u
#define PORT_PCR_PS_SHIFT 0
PCR寄存器中的PS(Pull Select)位是用来选择拉的类型,置1为上拉,置0为下拉