GPIO 配置

一、GPIO引脚

引脚 对应位 当前用途 能不能直接改
INT0_2 EPORT0 bit2 编码器按键(下降沿中断) 需先 encoder_on = 0
INT0_3 EPORT0 bit3 空闲 可直接用
INT0_6 EPORT0 bit6 编码器 B 相 需先 encoder_on = 0
INT0_7 EPORT0 bit7 编码器 A 相 需先 encoder_on = 0

编码器开关在 User/module_select.h:

#define encoder_on    1      // 改成 0 释放 INT0_2/6/7

三个 PWM 脚,其中 PWM1_2 已被蜂鸣器占用,剩余空闲PWM:

引脚 PWM 模块 通道 预分频 状态
PWM1_0 PWM1 CH0 CP0 空闲
PWM1_1 PWM1 CH1 CP0 空闲
PWM0_3 PWM0 CH3 CP1 空闲

二、配置 GPIO

第 1 步:把 AIN 切成 GPIO

这四个脚默认是 ADC 输入,当 GPIO 用必须先关掉对应通道的 ADC,
否则读写全部无效。改 OPTION->ADCCDISR 的对应位:

引脚 位掩码
INT0_2 1 << 2
INT0_3 1 << 3
INT0_6 1 << 6
INT0_7 1 << 7

写法(以同时开 INT0_3 为例,掩码 0x08):

OPTION->U16_ADCCDISR.ADCCDISTEST = 1;
OPTION->U16_ADCCDISR.ADCCDISTEST = 2;
OPTION->U16_ADCCDISR.ADCCDISTEST = 3;      // ① 解锁序列 1→2→3
OPTION->U16_ADCCDISR.ADCCDIS |= (1 << 3);  // ② INT0_3 切 GPIO

多个脚一起开就按位或:(1<<2) | (1<<3) | (1<<6) | (1<<7) = 0xCC。

参考现有写法:Widget/uiEncoder.c 的 Encoder_Init() 用 value |= 0xC4;
开的就是 bit2/6/7;Function/if_port.c 用 |= (1<<1) 开 LCD_RST。

这一步是可逆的 —— 把同一位清 0 就恢复 ADC 功能,见第三节。

第 2 步:设方向与上下拉

EPORT0->EPDDR |=  (1 << 3);   // 输出
EPORT0->EPDDR &= ~(1 << 3);   // 输入
EPORT0->EPPUE |=  (1 << 3);   // 开上拉

第 3 步:读写

EPORT0->EPDR  |=  (1 << 3);                 // 输出高
EPORT0->EPDR  &= ~(1 << 3);                 // 输出低
EPORT0->EPBSR  =  (1 << 3);                 // 同上,原子置位(推荐)
EPORT0->EPBCR  =  (1 << 3);                 // 原子清零

level = (EPORT0->EPPDR >> 3) & 0x01;        // 读输入电平

寄存器速查:

寄存器 作用
EPDDR 方向,1 = 输出
EPPUE 上拉使能
EPDR 写输出电平
EPPDR 读引脚电平
EPBSR / EPBCR 原子置位 / 清零
EPIER 中断使能
EPPAR 中断触发方式
EPFR 中断标志(写 1 清)

三、切换回 ADC(复用回 AIN)

规则只有一条:同一个 ADCCDIS 位,置 1 = GPIO,清 0 = ADC。

ADCCDIS 位 引脚功能
1 GPIO(INT0_x)
0 ADC(AIN_x)

编号一一对应,库里也是成对给的:

引脚 切成 GPIO 切回 ADC 采样用
INT0_2 / AIN2 PIN_EPORT0_2() PIN_ADC_CH2_Default() ADC_CH2
INT0_3 / AIN3 PIN_EPORT0_3() PIN_ADC_CH3_Default() ADC_CH3
INT0_6 / AIN6 PIN_EPORT0_6() PIN_ADC_CH6_Default() ADC_CH6
INT0_7 / AIN7 PIN_EPORT0_7() PIN_ADC_CH7_Default() ADC_CH7

直接写寄存器 —— 与第 1 步唯一差别是 |= 换成 &= ~:

OPTION->U16_ADCCDISR.ADCCDISTEST = 1;
OPTION->U16_ADCCDISR.ADCCDISTEST = 2;
OPTION->U16_ADCCDISR.ADCCDISTEST = 3;        // 解锁序列 1→2→3
OPTION->U16_ADCCDISR.ADCCDIS &= ~(1 << 3);   // INT0_3 还给 ADC

采样:

#include "lt168_adc.h"

ADC_Init();                              // 整个程序调一次
uint16_t val = Get_ADC_Val(ADC_CH3);     // 12 位,0~4095
  • 分辨率 12 位(ADC_Init() 里 ADC->U32_ADC_CFGR1.RES = 0)
  • Get_ADC_Val() 是单次阻塞采样,别放在时序要求紧的地方
  • 除外部通道外还能采内部通道:VREFINT(14)、Temper_Sensor(15)
  • 完整例程:Lib/src/lt168_adc.c 的 ADC_Demo()

GPIO 和 ADC 不能同时用同一个脚 —— 切成 GPIO 后,该脚的模拟输入就失效了。


四、配置 PWM 输出

第 1 步:切到 PWM 功能

PWM 与 QSPI2 共用引脚,由 OPTION->CCR bit8 决定:

PIN_PWM_Default();      // 清 bit8 → 引脚给 PWM
// PIN_QSPI2();         // 置 bit8 → 引脚给 QSPI2

第 2 步:配频率与占空比

寄存器按通道区分,预分频器由 channel / 2 决定(见 lt168_pwm.c:60):

通道 预分频 时钟选择 周期 占空比 使能
CH0(PWM1_0) PPR.CP0 PCSR.CSR0 PCNR0 PCMR0 PCR.CH0EN
CH1(PWM1_1) PPR.CP0 PCSR.CSR1 PCNR1 PCMR1 PCR.CH1EN
CH3(PWM0_3) PPR.CP1 PCSR.CSR3 PCNR3 PCMR3 PCR.CH3EN

PWM1_0 输出 1 kHz、占空比 50%:

PIN_PWM_Default();

PWM1->U32_PPR.CP0     = 0;        // CH0/CH1 用 CP0,0 = 不分频
PWM1->U32_PCSR.CSR0   = 2;        // 8 分频 → 168/8 = 21MHz
PWM1->PCNR0           = 20999;    // 周期:21MHz / 21000 = 1kHz
PWM1->PCMR0           = 10500;    // 占空比 10500/21000 = 50%
PWM1->U32_PCR.CH0EN   = 1;        // 使能通道
PWM1->U32_PPCR.PDDR_0 = 1;        // 引脚设为输出

运行中改占空比:

PWM1->PCMR0 = 5250;               // 25%

PWM0_3(注意是 PWM0 模块、CH3、用 CP1):

PIN_PWM_Default();

PWM0->U32_PPR.CP1     = 0;
PWM0->U32_PCSR.CSR3   = 2;        // 8 分频 → 21MHz
PWM0->PCNR3           = 20999;    // 1 kHz
PWM0->PCMR3           = 10500;    // 50%
PWM0->U32_PCR.CH3EN   = 1;
PWM0->U32_PPCR.PDDR_3 = 1;

频率怎么算

f = 168MHz / (CSR 分频) / (CP + 1) / (PCNR + 1)

CSR 取值与分频的对应:

CSR 0 1 2 3 其它
分频 2 4 8 16 1

例如 CSR=2(8 分频)、CP=0、PCNR=20999:
168MHz / 8 / 1 / 21000 = 1 kHz。

已在用的参考配置:bsp.c 里蜂鸣器把 PWM1 的 CH2 配成 2.1 kHz / 50%
(CSR2=2、CP1=0、PCNR2=9999、PCMR2=5000)。


五、注意事项

项 说明
必须先切复用 INT0_x 不写 ADCCDISR 就还是 ADC,读写全无效
GPIO / ADC 互斥 同一个脚只能二选一,切成 GPIO 后模拟输入失效,切回 ADC 见第三节
解锁序列 写 ADCCDISR 前要走 ADCCDISTEST 1→2→3,直接赋值无效
INT0_2/6/7 被编码器占 用它们之前先 #define encoder_on 0,否则两边冲突
PWM vs QSPI2 同一个 bit8 控制;本工程没调 PIN_QSPI2(),PWM 可用
CP0/CP1 是共享的 CH0 和 CH1 共用 CP0,改一个会影响另一个通道的分频
PWM1_2 别动 那是蜂鸣器;好在它在 CP1,与 PWM1_0/1 的 CP0 互不干扰
清中断标志 EPFR 写 1 清,不清会反复进中断
电平中断 高/低电平中断不可常开,本工程用的都是边沿中断

六、已用的 GPIO

引脚 用途
INT0_0 / INT0_4 触摸(CTP)SDA / SCL
INT0_1 / INT0_5 触摸 INT(兼 LCD_RST)/ 触摸 RST
EPORT1_0 LT758 WAIT 握手脚,卡住会导致 4 秒看门狗复位
PWM1_2 蜂鸣器
作者:罗珍雪  创建时间:2026-10-20 10:28
最后编辑:罗珍雪  更新时间:2026-11-02 20:02