GPIO配置与使用

目录

  1. GPIO基础
  2. 与STM32对比
  3. GPIO寄存器
  4. 手动配置GPIO
  5. SysConfig配置GPIO
  6. 实战示例

GPIO基础

F280049C的GPIO特性:

  • GPIO数量: 最多59个GPIO引脚
  • 复用功能: 每个引脚可配置为GPIO或外设功能
  • 输入输出: 可配置为输入、输出或开漏模式
  • 上拉下拉: 内部上拉电阻可配置
  • 中断功能: 支持GPIO中断(XINT)

GPIO分组

GPIO按端口分组:

  • GPA: GPIO0-GPIO31
  • GPB: GPIO32-GPIO58

与STM32对比

配置流程对比

步骤 STM32 F280049C
1. 时钟使能 __HAL_RCC_GPIOx_CLK_ENABLE() 不需要(GPIO时钟默认使能)
2. 引脚模式 GPIO_InitStruct.Mode GPIO_setDirectionMode()
3. 引脚复用 GPIO_InitStruct.Alternate GPIO_setPinConfig()
4. 上拉下拉 GPIO_InitStruct.Pull GPIO_setPadConfig()
5. 输出速度 GPIO_InitStruct.Speed GPIO_setQualificationMode()

代码对比

1
2
3
4
5
6
7
8
9
10
11
12
13
// STM32 HAL库
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// F280049C DriverLib
GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);
GPIO_setPinConfig(GPIO_0_GPIO0);

GPIO寄存器

主要寄存器组

1. 方向控制寄存器

1
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;  // 1=输出, 0=输入

2. 数据寄存器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 读取输入
uint32_t value = GpioDataRegs.GPADAT.bit.GPIO0;

// 写入输出
GpioDataRegs.GPADAT.bit.GPIO0 = 1;

// 置位(推荐)
GpioDataRegs.GPASET.bit.GPIO0 = 1;

// 清零(推荐)
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;

// 翻转
GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;

3. 复用功能寄存器

1
2
3
4
5
6
7
// GPIO0配置为GPIO功能
GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;

// GPIO0配置为EPWM1A功能
GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;

4. 上拉使能寄存器

1
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;  // 0=使能上拉, 1=禁用上拉

手动配置GPIO

方法1: 直接寄存器操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "F28x_Project.h"

void GPIO_Init_Register(void)
{
EALLOW; // 解锁保护寄存器

// 配置GPIO0为输出
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // 使能上拉
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // 配置为GPIO功能
GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // 配置为输出

// 配置GPIO1为输入
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // 使能上拉
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // 配置为GPIO功能
GpioCtrlRegs.GPAGMUX1.bit.GPIO1 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; // 配置为输入
GpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 0; // 同步采样

EDIS; // 锁定保护寄存器
}

void GPIO_Write(void)
{
// 方法1: 直接写GPADAT
GpioDataRegs.GPADAT.bit.GPIO0 = 1;

// 方法2: 使用SET寄存器(推荐)
GpioDataRegs.GPASET.bit.GPIO0 = 1;

// 方法3: 使用CLEAR寄存器(推荐)
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;

// 方法4: 翻转
GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;
}

uint32_t GPIO_Read(void)
{
return GpioDataRegs.GPADAT.bit.GPIO1;
}

方法2: DriverLib库函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "driverlib.h"
#include "device.h"

void GPIO_Init_DriverLib(void)
{
// 配置GPIO0为输出
GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD); // 标准推挽输出
GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT); // 输出模式
GPIO_setPinConfig(GPIO_0_GPIO0); // GPIO功能

// 配置GPIO1为输入(带上拉)
GPIO_setPadConfig(1, GPIO_PIN_TYPE_PULLUP); // 使能上拉
GPIO_setDirectionMode(1, GPIO_DIR_MODE_IN); // 输入模式
GPIO_setPinConfig(GPIO_1_GPIO1); // GPIO功能
GPIO_setQualificationMode(1, GPIO_QUAL_SYNC); // 同步采样
}

void GPIO_Write_DriverLib(void)
{
GPIO_writePin(0, 1); // 写高电平
GPIO_writePin(0, 0); // 写低电平
GPIO_togglePin(0); // 翻转
}

uint32_t GPIO_Read_DriverLib(void)
{
return GPIO_readPin(1);
}

GPIO配置选项详解

1. 引脚类型 (Pin Type)

1
2
3
4
GPIO_PIN_TYPE_STD       // 标准推挽输出
GPIO_PIN_TYPE_PULLUP // 使能内部上拉
GPIO_PIN_TYPE_INVERT // 输入反相
GPIO_PIN_TYPE_OD // 开漏输出

2. 方向模式 (Direction Mode)

1
2
GPIO_DIR_MODE_IN   // 输入模式
GPIO_DIR_MODE_OUT // 输出模式

3. 采样模式 (Qualification Mode)

1
2
3
4
GPIO_QUAL_SYNC    // 同步采样(2个SYSCLK周期)
GPIO_QUAL_3SAMPLE // 3次采样
GPIO_QUAL_6SAMPLE // 6次采样
GPIO_QUAL_ASYNC // 异步采样(不推荐)

SysConfig配置GPIO

步骤1: 创建SysConfig文件

  1. 在CCS项目中右键 -> New -> SysConfig File
  2. 命名为 myproject.syscfg

步骤2: 添加GPIO

  1. 在左侧面板找到 GPIO
  2. 点击 “+” 添加GPIO实例
  3. 配置参数:
1
2
3
4
5
6
7
GPIO Instance: GPIO0
├── Pin Configuration
│ ├── Pin: 0
│ ├── Direction: Output
│ ├── Qualification: Synchronous
│ └── Pin Type: Standard (Push-Pull)
└── Initial Value: Low

步骤3: 生成代码

保存 .syscfg 文件后,自动生成:

  • board.c - 初始化代码
  • board.h - 头文件

步骤4: 使用生成的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "board.h"

void main(void)
{
Device_init();
Device_initGPIO();

// 调用SysConfig生成的初始化函数
Board_init();

while(1)
{
GPIO_writePin(0, 1);
DEVICE_DELAY_US(500000);
GPIO_writePin(0, 0);
DEVICE_DELAY_US(500000);
}
}

SysConfig生成的代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// board.c (自动生成)
void Board_init(void)
{
Board_initGPIO();
}

void Board_initGPIO(void)
{
// GPIO0配置
GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);
GPIO_setPinConfig(GPIO_0_GPIO0);
GPIO_writePin(0, 0); // 初始值为低
}

实战示例

示例1: LED闪烁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "driverlib.h"
#include "device.h"

#define LED_GPIO 31 // 假设LED连接到GPIO31

void main(void)
{
// 初始化设备
Device_init();
Device_initGPIO();

// 配置LED引脚
GPIO_setPadConfig(LED_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(LED_GPIO, GPIO_DIR_MODE_OUT);
GPIO_setPinConfig(GPIO_31_GPIO31);

// 使能全局中断
EINT;
ERTM;

while(1)
{
GPIO_togglePin(LED_GPIO);
DEVICE_DELAY_US(500000); // 延时500ms
}
}

示例2: 按键检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "driverlib.h"
#include "device.h"

#define LED_GPIO 31
#define BUTTON_GPIO 34

void main(void)
{
Device_init();
Device_initGPIO();

// 配置LED(输出)
GPIO_setPadConfig(LED_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(LED_GPIO, GPIO_DIR_MODE_OUT);
GPIO_setPinConfig(GPIO_31_GPIO31);

// 配置按键(输入,带上拉)
GPIO_setPadConfig(BUTTON_GPIO, GPIO_PIN_TYPE_PULLUP);
GPIO_setDirectionMode(BUTTON_GPIO, GPIO_DIR_MODE_IN);
GPIO_setPinConfig(GPIO_34_GPIO34);
GPIO_setQualificationMode(BUTTON_GPIO, GPIO_QUAL_6SAMPLE);

EINT;
ERTM;

while(1)
{
// 按键按下时点亮LED(假设按键按下为低电平)
if(GPIO_readPin(BUTTON_GPIO) == 0)
{
GPIO_writePin(LED_GPIO, 1);
}
else
{
GPIO_writePin(LED_GPIO, 0);
}

DEVICE_DELAY_US(10000); // 延时10ms消抖
}
}

示例3: GPIO中断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "driverlib.h"
#include "device.h"

#define LED_GPIO 31
#define BUTTON_GPIO 34

// 中断服务函数
__interrupt void xint1_isr(void)
{
GPIO_togglePin(LED_GPIO);

// 清除中断标志
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

void main(void)
{
Device_init();
Device_initGPIO();

// 配置LED
GPIO_setPadConfig(LED_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(LED_GPIO, GPIO_DIR_MODE_OUT);
GPIO_setPinConfig(GPIO_31_GPIO31);

// 配置按键
GPIO_setPadConfig(BUTTON_GPIO, GPIO_PIN_TYPE_PULLUP);
GPIO_setDirectionMode(BUTTON_GPIO, GPIO_DIR_MODE_IN);
GPIO_setPinConfig(GPIO_34_GPIO34);

// 配置GPIO中断(XINT1)
GPIO_setInterruptPin(BUTTON_GPIO, GPIO_INT_XINT1);
GPIO_setInterruptType(GPIO_INT_XINT1, GPIO_INT_TYPE_FALLING_EDGE);
GPIO_enableInterrupt(GPIO_INT_XINT1);

// 初始化PIE中断
Interrupt_initModule();
Interrupt_initVectorTable();

// 注册中断服务函数
Interrupt_register(INT_XINT1, &xint1_isr);
Interrupt_enable(INT_XINT1);

EINT;
ERTM;

while(1)
{
// 主循环空闲
}
}

示例4: 多个GPIO控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "driverlib.h"
#include "device.h"

// 定义LED引脚
#define LED1_GPIO 0
#define LED2_GPIO 1
#define LED3_GPIO 2
#define LED4_GPIO 3

void GPIO_InitLEDs(void)
{
uint16_t leds[] = {LED1_GPIO, LED2_GPIO, LED3_GPIO, LED4_GPIO};

for(int i = 0; i < 4; i++)
{
GPIO_setPadConfig(leds[i], GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(leds[i], GPIO_DIR_MODE_OUT);
GPIO_writePin(leds[i], 0);
}

GPIO_setPinConfig(GPIO_0_GPIO0);
GPIO_setPinConfig(GPIO_1_GPIO1);
GPIO_setPinConfig(GPIO_2_GPIO2);
GPIO_setPinConfig(GPIO_3_GPIO3);
}

void LED_Pattern(void)
{
// 流水灯效果
GPIO_writePin(LED1_GPIO, 1);
DEVICE_DELAY_US(200000);
GPIO_writePin(LED1_GPIO, 0);

GPIO_writePin(LED2_GPIO, 1);
DEVICE_DELAY_US(200000);
GPIO_writePin(LED2_GPIO, 0);

GPIO_writePin(LED3_GPIO, 1);
DEVICE_DELAY_US(200000);
GPIO_writePin(LED3_GPIO, 0);

GPIO_writePin(LED4_GPIO, 1);
DEVICE_DELAY_US(200000);
GPIO_writePin(LED4_GPIO, 0);
}

void main(void)
{
Device_init();
Device_initGPIO();

GPIO_InitLEDs();

EINT;
ERTM;

while(1)
{
LED_Pattern();
}
}

常见问题

1. GPIO不工作?

  • 检查是否调用了 Device_initGPIO()
  • 检查引脚复用配置是否正确
  • 检查是否使用了 EALLOWEDIS

2. 如何选择GPIO引脚?

  • 查看数据手册的引脚定义表
  • 避免与调试接口冲突(GPIO28/29)
  • 考虑外设复用需求

3. GPIO速度慢?

  • 使用 GPASETGPACLEAR 代替 GPADAT
  • 减少寄存器访问次数
  • 使用位操作而非整个寄存器读写

4. 按键抖动?

  • 使用 GPIO_setQualificationMode() 设置采样模式
  • 软件延时消抖
  • 使用定时器中断进行周期性检测

下一步

学习完GPIO后,继续学习:


参考资料

  • TMS320F28004x Technical Reference Manual
  • C2000Ware DriverLib API Guide
  • GPIO Example Code in C2000Ware