1 GPIO相关¶
1.1 GPIO操作和调试方法¶
1.1.1 RTT driver层操作方法¶
The MCU series of SiCh is dual-core architecture. Hcpu includes the PA port, Lcpu includes the PB port, and the 58 and 56 series also include low-power IO: PBR port;
In order to facilitate the unified operation of GPIO ports by the RTT operating system, a unified GPIO arrangement method is currently adopted for the PA, PB, and PBR ports in the pin device operations of the RTThread operating system;:
PA01 corresponds to 1, PA78 corresponds to 78;,
Add 96 to the PB port, that is, PB0 corresponds to 96, PB1 corresponds to 97, PB40 corresponds to 136;
Add 160 to the PBR0 port, that is, PBR0 corresponds to 160, PBR1 corresponds to 161, PBR2 corresponds to 162;
PA, PB, PBR can use the function GET_PIN or GET_PIN_2 to get the pin number;,
The first parameter of the GET_PIN function is 0, 1, 2, corresponding to PBR, GPIO1 (PA) and GPIO2 (PB);,
例如
pin_numble=GET_PIN(0, 0);//PBR0 对应Value;为160
PBR1就是GET_PIN(0, 1)=161,
PB1就是GET_PIN(2, 1)=97,
PA1就是GET_PIN(1, 1)=1
GET_PIN_2的第一个参数是hwp_pbr,hwp_gpio1,hwp_gpio2,
pin_numble=GET_PIN_2(hwp_pbr,1); //PBR1 Value;为161
pin_numble=GET_PIN_2(hwp_gpio2,1); //PB1 Value;为97
pin_numble=GET_PIN_2(hwp_gpio1,1); //PA1 Value;为1
After the unified GPIO arrangement, IO can be operated according to the general interface;,操作代码如下:
rt_pin_mode(160, PIN_MODE_OUTPUT); /* 配置PBR0输出 */
rt_pin_write(160, PIN_LOW); /* PBR0输出低电平 */
rt_pin_mode(160, PIN_MODE_INPUT_PULLUP); /* 配置PBR0为输入口,Note;此处配置上下拉,目前代码没有生效,需用HAL函数配置 */
if (1 == rt_pin_read(160)) /* 读PBR0状态 */
//
rt_pin_mode(78, PIN_MODE_OUTPUT); /* 配置PA78输出 */
rt_pin_write(78, 0);/* PA78 输出低 */
//
rt_pin_mode(79, PIN_MODE_INPUT_PULLUP);/* 配置PA79为输入口,Note;此处配置上下拉,目前代码没有生效,需用HAL函数配置 */
if (1 == rt_pin_read(79)) /* 读PA79状态 */
Configured as interrupt input mode;:
rt_pin_mode(144, PIN_MODE_INPUT_PULLUP);//配置PB48为输入口(48+96=144),Note;此处配置上下拉,目前代码没有生效,需用HAL函数配置
curr_state = rt_pin_read(144); /* 读 PB48口状态 */
rt_pin_attach_irq(144, PIN_IRQ_MODE_FALLING, chsc5816tp_irq_handler, RT_NULL);/*配置为下降沿触发,中断函数为chsc5816tp_irq_handler */
rt_pin_irq_enable(144, 1);/* 启动 PB48 GPIO中断*/
//
rt_pin_mode(160,PIN_MODE_INPUT); //配置PBR0为输入模式,Note;此处配置上下拉,目前代码没有生效,需用HAL函数配置
rt_pin_attach_irq(160,PIN_IRQ_MODE_FALLING,(void*)bt5376a_wakeup_event_handle, (void*)(rt_uint32_t)160); //配置为下降沿中断和中断处理函数bt5376a_wakeup_event_handle
rt_pin_irq_enable(160,1); //Enable interrupt;
Note;:
1,The DRV layer function cannot modify the GPIO Function, need to use the HAL layer function, default set in the pin initialization BSP_PIN_Init function during chip power-on or standby wake-up process;;
2,Hcpu can fully operate the resources of Lcpu, including the PB port, but Lcpu cannot directly read and write the PA port, otherwise Hardfault will occur;;
3,Before using the pin device for read/write operations, it is necessary to set the mode with rt_pin_mode first, even if the hal layer has set the input/output;;
4,采用RTT层操作GPIO,进入Standby休眠后,IO状态已经做了自动备份和恢复,备份函数pm_pin_backup();
恢复函数pm_pin_restore();
,执行HAL_HPAON_DISABLE_PAD();
后,此时操作GPIO,GPIO对外输出电平也会保持不变,执行HAL_HPAON_ENABLE_PAD();
后,GPIO和pinmux的寄存器配置就会输出到外部GPIO;Deep休眠GPIO状态会保持,不会变;
5,The GPIO operation at the RTT layer can also refer to the RTT official website;:
PIN设备 (rt-thread.org):
1.1.2 HAL层操作方法¶
When the RTT operating system is not yet up, for example, the underlying drv_io.c can directly call the GPIO functions of the HAL interface to read and write the GPIO port;
PA/PB口操作方法:
Set the PA/PB function and pull-up/pull-down function, PA/PB needs to be distinguished by one parameter;:
HAL_PIN_Set(PAD_PA03,GPIO_A3,PIN_NOPULL, 1); //Set;PA03为GPIO模式,无上下拉
输出高低:
BSP_GPIO_Set(3, 0, 1); //PA03输出低
BSP_GPIO_Set(3, 0, 0); //PB03输出低
GPIO is configured as input/output mode, PA24 is configured as input mode as shown in the figure below;:
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pin = 24;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(hwp_gpio1, &GPIO_InitStruct);
Read;IO数Value;:
int value;
value = HAL_GPIO_ReadPin((GPIO_TypeDef *)hwp_gpio1, 48); //读PA48的Value;:
value = HAL_GPIO_ReadPin((GPIO_TypeDef *)hwp_gpio2, 48); //读PB48的Value;:
Note;:
1,To operate GPIO at the HAL layer, parameters are needed to distinguish between hcpu and lcpu, so it is no longer possible to operate PB48 as 96+48 at the DRV layer;;
2,HAL层操作GPIO,进入Standby休眠后,IO状态已经做了自动备份和恢复,备份函数pm_pin_backup();
恢复函数pm_pin_restore();
,执行后HAL_HPAON_DISABLE_PAD();
后GPIO对外输出电平会保持不变,执行HAL_HPAON_ENABLE_PAD();
后,GPIO和pinmux的寄存器就会输出到外部GPIO;
PBR口操作方法:
HAL_PBR_ConfigMode(2,1);//配置PBR2为输出模式,第1个参数0对应PBR0, 2对应PBR2;第2个参数,1为输出,0位输入;
HAL_PBR_WritePin(2,1); //配置PBR2输出高
value=HAL_PBR_ReadPin(0); //Read;PBR0的Value;,返回0或者1,返回Value;少于1表示有错误,比如输入pin为无效Value;
HAL_PIN_Set_Analog(PAD_PBR1, 0); //Set;PBR1为模拟输入,对外为高阻态
HAL_PIN_Set(PAD_PBR1, PBR_GPO, PIN_NOPULL, 0); //配置PBR1为GPIO模式
具体各个IO支持哪些function,查看文件bf0_pin_const.c中pin_pad_func_hcpu
或者硬件文档SF32LB5XX_Pin config_X.xlsx
Note;:
PBR0 is by default in the PWR_REQ mode, this mode is where the hardware automatically controls the high and low output levels, LCPU outputs high when awake, and low when asleep;, 所以When some boards use this PIN to control the power supply of the large core PSRAM or NOR, it is necessary to FORCE output high, to prevent PSRAM from losing power after the small core sleeps;,操作如下:
HAL_PBR0_FORCE1_ENABLE();
1.1.3 寄存器操作GPIO方法¶
Below is the direct operation of GPIO registers PA24 for high, low, and toggle output;:(需预先配置好GPIO输出状态),寄存器含义参照芯片手册
#define PM_DEBUG_PIN_HIGH() ((GPIO1_TypeDef *)hwp_gpio1)->DOSR0 |= (1UL << 24)//PA00 - PA31
#define PM_DEBUG_PIN_LOW() ((GPIO1_TypeDef *)hwp_gpio1)->DOCR0 |= (1UL << 24)
#define PM_DEBUG_PIN_TOGGLE() ((GPIO1_TypeDef *)hwp_gpio1)->DOR0 ^= (1UL << 24)
Below is an example of register operation for IO initialization and read/write operations;:
pin_test is the test program;:
#ifdef SOC_BF0_HCPU
#define PA_HIGH(port) (port > 31) ? (((GPIO1_TypeDef *)hwp_gpio1)->DOR1 |= (1UL << (port-32))) : (((GPIO1_TypeDef *)hwp_gpio1)->DOR0 |= (1UL << port))
#define PA_LOW(port) (port > 31) ? (((GPIO1_TypeDef *)hwp_gpio1)->DOR1 &= (~(1UL << (port-32)))) : (((GPIO1_TypeDef *)hwp_gpio1)->DOR0 &= (~(1UL << port)))
#define PA_TOGGLE(port) (port > 31) ? (((GPIO1_TypeDef *)hwp_gpio1)->DOR1 ^= (1UL << (port-32))) : (((GPIO1_TypeDef *)hwp_gpio1)->DOR0 ^= (1UL << port))
#define PA_VALUE(port) (port > 31) ? (((GPIO1_TypeDef *)hwp_gpio1)->DIR1 &= (1UL << (port-32))) : (((GPIO1_TypeDef *)hwp_gpio1)->DIR0 &= (1UL << port))
#define PA_INIT(port,mode) \
do \
{ \
GPIO_InitTypeDef GPIO_InitStruct; \
GPIO_InitStruct.Mode = mode; \
GPIO_InitStruct.Pin = port; \
GPIO_InitStruct.Pull = GPIO_NOPULL; \
HAL_PIN_Set(PAD_PA00+port, GPIO_A0+port, PIN_NOPULL, 1); \
HAL_GPIO_Init(hwp_gpio1, &GPIO_InitStruct); \
} \
while (0)
#ifndef SF32LB52X
#define PB_HIGH(port) (port > 31) ? (((GPIO2_TypeDef *)hwp_gpio2)->DOR1 |= (1UL << (port-32))) : (((GPIO2_TypeDef *)hwp_gpio2)->DOR0 |= (1UL << port))
#define PB_LOW(port) (port > 31) ? (((GPIO2_TypeDef *)hwp_gpio2)->DOR1 &= (~(1UL << (port-32)))) : (((GPIO2_TypeDef *)hwp_gpio2)->DOR0 &= (~(1UL << port)))
#define PB_TOGGLE(port) (port > 31) ? (((GPIO2_TypeDef *)hwp_gpio2)->DOR1 ^= (1UL << (port-32))) : (((GPIO2_TypeDef *)hwp_gpio2)->DOR0 ^= (1UL << port))
#define PB_VALUE(port) (port > 31) ? (((GPIO2_TypeDef *)hwp_gpio2)->DIR1 &= (1UL << (port-32))) : (((GPIO2_TypeDef *)hwp_gpio2)->DIR0 &= (1UL << port))
#define PB_INIT(port,mode) \
do \
{ \
GPIO_InitTypeDef GPIO_InitStruct; \
GPIO_InitStruct.Mode = mode; \
GPIO_InitStruct.Pin = port; \
GPIO_InitStruct.Pull = GPIO_NOPULL; \
HAL_PIN_Set(PAD_PB00+port, GPIO_B0+port, PIN_NOPULL, 0); \
HAL_GPIO_Init(hwp_gpio2, &GPIO_InitStruct); \
} \
while (0)
#endif
int pin_test(int argc, char **argv)
{
char i;
uint8_t pin,value;
if (argc > 1)
{
pin = strtoul(argv[3], 0, 10);
value = strtoul(argv[4], 0, 10);
rt_kprintf("pin:%d,value:%d,\n",pin,value);
if ((strcmp("pa", argv[1]) == 0) || (strcmp("PA", argv[1]) == 0))
{
if (strcmp("-w", argv[2]) == 0)
{
if(value == 1)
{
PA_HIGH(pin);
rt_kprintf("PA%d set high\n",pin);
}
else if(value == 0)
{
PA_LOW(pin);
rt_kprintf("PA%d set low\n",pin);
}
else
{
PA_TOGGLE(pin);
rt_kprintf("PA%d toggle\n",pin);
}
}
else if (strcmp("-r", argv[2]) == 0)
{
if(PA_VALUE(pin))
rt_kprintf("PA%d is high, %x\n",pin,PA_VALUE(pin));
else
rt_kprintf("PA%d is low, %x\n",pin,PA_VALUE(pin));
}
else if (strcmp("-init", argv[2]) == 0)
{
if(value == 0)
{
PA_INIT(pin,GPIO_MODE_INPUT);
rt_kprintf("PA%d INIT set input\n",pin);
}
else
{
PA_INIT(pin,GPIO_MODE_OUTPUT);
rt_kprintf("PA%d INIT set output\n",pin);
}
}
}
#ifndef SF32LB52X
else if ((strcmp("pb", argv[1]) == 0) || (strcmp("PB", argv[1]) == 0))
{
if (strcmp("-w", argv[2]) == 0)
{
if(value == 1)
{
PB_HIGH(pin);
rt_kprintf("PB%d set high\n",pin);
}
else if(value == 0)
{
PB_LOW(pin);
rt_kprintf("PB%d set low\n",pin);
}
else
{
PB_TOGGLE(pin);
rt_kprintf("PA%d toggle\n",pin);
}
}
else if (strcmp("-r", argv[2]) == 0)
{
if(PB_VALUE(pin))
rt_kprintf("PB%d is high, %x\n",pin,PB_VALUE(pin));
else
rt_kprintf("PB%d is low, %x\n",pin,PB_VALUE(pin));
}
else if (strcmp("-init", argv[2]) == 0)
{
if(value == 0)
{
PB_INIT(pin,GPIO_MODE_INPUT);
rt_kprintf("PB%d INIT set input\n",pin);
}
else
{
PB_INIT(pin,GPIO_MODE_OUTPUT);
rt_kprintf("PB%d INIT set output\n",pin);
}
}
}
#endif
}
else
{
rt_kprintf("example:\npin_test pa -init 29 0 #set PA29 to input \n");
rt_kprintf("pin_test pa -init 29 1 #set PA29 to output\n");
rt_kprintf("pin_test pa -w 29 1 #write PA29 to high level\n");
rt_kprintf("pin_test pa -w 29 0 #write PA29 to low level\n");
rt_kprintf("pin_test pa -r 29 #read PA29\n");
rt_kprintf("pin_test pb -init 29 1 #set PB29 to output\n");
}
return 0;
}
MSH_CMD_EXPORT(pin_test, forward pin_test command); /* 导出到 msh 命令列表中 */
#endif
调用方法:
PA_INIT(29,GPIO_MODE_OUTPUT); //PA29 is initialized as an output port;
PA_HIGH(29);//PA29 outputs high;
PA_TOGGLE(29);//PA29 level flips;
PA_INIT(33,GPIO_MODE_INPUT);//PA33 is configured as an input port;
uint8_t value = PA_VALUE(33);//Read PA33, a non-zero value represents high, and 0 represents low level;
PB_INIT(2,GPIO_MODE_OUTPUT); //PB02 is initialized as an output port;
1.1.4 GPIO调试方法¶
方法1:
Use the serial port finsh command, corresponding implementation function:int cmd_pin(int argc, char **argv)
; After Hcpu/Lcpu enables the finsh function (Hcpu is enabled by default), on the serial console platform, you can use the pin command line to check the gpio status and let GPIO output high or low levels, such as:;
pin //查看命令提示
pin status all //View the status of all GPIOs;.
pin status 120 //Check the status of 120-96=24 PB24;41
pin mode 120 0 //Set PB24 to output mode;
pin write 78 1 //Set PA78 to output high;
pin mux 106 2 //Set 106-96=10 PB10 to function 2 I2C4_SDA;
pin status 160 //160-160=0 Get PBR0 status;
方法2:
Use tools like Ozone and Jlink to connect to the MCU, read the pinmux and gpio registers, and compare with the user manual to see if it is configured correctly;pinmux寄存器地址对应方法:
register.h
中PA口对应PINMUX1_BASE或hwp_pinmux1
,PB口对应PINMUX2_BASE或者hwp_pinmux2
,
例如PA03的pinmux寄存器地址为:hwp_pinmux1->PAD_PA03
gpio寄存器地址对应方法:
PA口GPIO1_BASE或hwp_gpio1
,PB口对应GPIO2_BASE或hwp_gpio2
PBR口IO(PBR) 的输入使能、输出使能、上下拉电阻等功能可以通过 RTC 的 PBRxR 寄存器配置,比如PBR0地址为hwp_rtc->BKP0R
1.2 55X系列 PA口在睡眠唤醒后会有电平波动¶
HCPU PA port will first restore to the chip's default pull-up and pull-down after sleep wake-up, as shown in the figure below:; <br>
At this time, the user program has not started running, then execute the values set in BSP_IO_Init in the pinmux.c file;
Therefore, if the HCPU GPIO level is inconsistent with the default pull-up/pull-down during sleep, there may be a jump of about 10ms after waking up;
After LCPU PB port wakes up from sleep, the value before waking up can be saved until the BSP_IO_Init function is executed, so as long as the GPIO port status is set in BSP_IO_Init, the LCPU GPIO value can be maintained during sleep.;
For example, if you want PA03 to remain high after booting, but since PA03 defaults to pull-down, there will be about 10ms of low level after waking up from sleep. In actual use, you need to find a pin that defaults to pull-up to replace PA03, such as PA10.;
备注:
This issue does not exist for the 56X, 52X series PA ports;
1.3 TP的驱动 IRQ中断怎么配置¶
1,Menuconfig配置
After configuration, it will be generated in rtconfig.h:;
#define TOUCH_IRQ_PIN 79
2,pinmux.c中,Need to confirm the mode and pull-up/pull-down status of this IO port;:
HAL_PIN_Set(PAD_PA79, GPIO_A79, PIN_NOPULL, 1); // GPIO mode, no pull-up;,
3,This definition will be used in drv_touch.c. The driver can directly use the two functions in drv_touch.c;:
rt_touch_irq_pin_attach(PIN_IRQ_MODE_FALLING, cst816_irq_handler, NULL);
rt_touch_irq_pin_enable(1);
Or define the interrupt yourself in the initialization function;:
rt_pin_mode(TOUCH_IRQ_PIN, PIN_MODE_INPUT); //Configured as input;
rt_pin_attach_irq(TOUCH_IRQ_PIN, PIN_IRQ_MODE_FALLING, (void *) cst816_irq_handler,(void *)(rt_uint32_t)TOUCH_IRQ_PIN);//Configure falling edge interrupt and interrupt callback function;
rt_pin_irq_enable(TOUCH_IRQ_PIN, 1); //Enable interrupt;
4,Hcpu’s serial port input command: pin status 79 to confirm whether the configuration is correct;。
1.4 如何detach touch irq¶
In the touch driver deinit function, before detaching the irq, it is necessary to first disable the interrupt of this pin;:
static rt_err_t deinit(void)
{
rt_pin_irq_enable(TOUCH_IRQ_PIN, 0); //disable irq
rt_pin_detach_irq(TOUCH_IRQ_PIN);
...
1.5 Why PA55 is the default pull-down port PD, but when I power on, I don’t do any operation, PA55 tests as high level;?¶
根本Reason;: 客户的OTA代码中, 有对PA55进行拉高操作.
让客户在用户程序pinmux.c中,添加__asm("B .");
断点命令,
Test PA55 port, it is high;,
mem32 0x50000038 20 Read the corresponding register, there is an operation that outputs high;,
jlink输入r,Reset the chip;,
在读寄存器Value;恢复正常, PA55电平也正常,
由于用户程序是从0x10060000开始跑的, 复位后 是从0x10020000 OTA的代码开始跑, 然后跳到用户的0x1006000的代码, 而OTA代码drv_io.c中操作了,PA55,导致该现象.
1.6 55系列MCU复用USB的PA01/PA03漏电风险¶
Generally, it is recommended that customers do not use PA01;,
由于PA01,PA03是复用USB口功能, PA01,PA03当作GPIO使用时, 要特别谨慎;
1, Inside PA01, there is an 18K pull-down resistor in active and light_sleep modes, outputting a high level, otherwise there will be leakage current. In standby and deep_sleep modes, the 18k pull-down resistor does not take effect;.
2,在standby模式下, PA01,PA03输出电平不一致, 会出现通过USB电路,出现漏电流,
具体而言,Leakage of approximately 20uA will occur when the following conditions are met;:
a,Enter standby sleep;
b,The configuration levels of PA01 and PA03 are inconsistent (one outputs high or pulls up, the other outputs low or pulls down);。该漏电大小是不确定的Value;,可能随板子或环境变化有差异。
c,A patch solution to eliminate leakage: When entering sleep, make the levels of the two IOs consistent, or set at least one of them to a high-impedance state (no pull-up or pull-down);。
d,细节上有一些补充:1. The pull-down resistor of PA01 will not leak in standby and deep_sleep modes, but only leaks during active or light_sleep; 2. High impedance is not only our configuration, but also there should be no pull-up or pull-down on the board;,
可以采用下面方式输出高阻态:
HAL_PIN_Set_Analog(PAD_PA01,1); /* Analog input is Func10, shutting off GPIO output, input enable IE is turned off, which means high impedance state; */
HAL_PIN_Set_Analog(PAD_PA03,1);
1.7 55系列MCU-PB47/PB48配置32768时钟输出¶
Before use, it is necessary to confirm that the MCU has attached a 32768 crystal and disabled;#define LXT_DISABLE 1
另外需要修改两点:
1,Enable flag bit, taking PB47 as an example;:
#define LPSYS_AON_DBGMUX_PB47_SEL_LPCLK (0x1UL << LPSYS_AON_DBGMUX_PB47_SEL_Pos)
MODIFY_REG(hwp_lpsys_aon->DBGMUX,LPSYS_AON_DBGMUX_PB47_SEL_Msk,LPSYS_AON_DBGMUX_PB47_SEL_LPCLK);
2,If you need to keep 32k output during sleep, you need to mask the part shown in the screenshot below;。
Because if LPSYS_AON_ANACR_PB_AON_ISO is set to 1, the wake-up pins PB43~PB48 can maintain the level during sleep, but the cost is that they cannot output 32k or lptim3 controlled waveforms;。屏蔽后PB43~PB48这几个唤醒管脚睡眠期间不能保持电平,所以不能用作GPIO输出管脚
3,需要Note;:
因为步骤2,PB为了输出32k关闭了standy下IO保持功能, 因此PB口的唤醒脚PB43-48在standby模式下,由于内部上下拉不再生效,外部要必须给确定电平或者视外部连接设为输出高或者低,防止standby模式下PB43-PB48漏电。
1.8 增加PB25为按键KEY2¶
1,Lcpu中 menuconfig → Sifli middleware → Enable button library Set;按键个数为2
2,Lcpu中 menuconfig → Select board peripherals → Key config Set;KEY2对应GPIO为121(96+25)
3,Lcpu中 menuconfig → Sifli middleware → Enable button library Set;按键个数为2
4,Lcpu中 menuconfig → Select board peripherals → Key config Set;KEY2对应GPIO为121(96+25)
5,In Lcpu, configure the initialization and wake-up source of KEY2 in the init_pin function of sensor_service.c;
6,In Hcpu, configure the message subscription of KEY2 in the init_pin function of watch_demo.c;
1.9 提高GPIO驱动能力¶
Set DS0 and DS1 bits to 1, the strongest driving capability;
HAL_PIN_Set_DS0(PAD_PA10,1,1); //PA10 DS0置1
HAL_PIN_Set_DS1(PAD_PA10,1,1); //PA10 DS1置1
HAL_PIN_Set_DS1(PAD_PB16,0,1); //PB16 DS1置1
1.10 GPIO配置为高阻模式¶
如下,Set this IO to analog input state, and the IO port is in high impedance state to the outside;
HAL_PIN_Set_Analog(PAD_PA17, 1); //PA17 Set;为模拟输入,对外高阻
HAL_PIN_Set_Analog(PAD_PB27, 0); //PB27 Set;为模拟输入,对外高阻
Recover from high impedance state to the original IO state;,如下:
HAL_PIN_Set(PAD_PA17, GPIO_A17, PIN_NOPULL, 1);
HAL_PIN_Set(PAD_PB27, GPIO_B27, PIN_NOPULL, 0);
HAL_PIN_SetMode(PAD_PA17, 1, PIN_DIGITAL_IO_PULLDOWN); //sdk版本v2.2.0后,不再需要
HAL_PIN_SetMode(PAD_PB27, 0, PIN_DIGITAL_IO_PULLUP); //sdk版本v2.2.0后,不再需要
HAL_PIN_Set_Analog会把IO的IE位置0,If;只调用的HAL_PIN_Set函数配置,该函数不会操作IE位,此时输入不能用,需要IO恢复成输入口使用,还需调用HAL_PIN_SetMode函数配置,把IE为恢复为1(sdk版本v2.2.0后,不再需要)。
Note;:
After SDK version v2.2.0, the operation to restore IE to 1 has been added in the HAL_PIN_Set function, no need to add the HAL_PIN_SetMode function anymore;
1.11 52X PA22/PA23 32K晶体复用IO, I2C无法输出波形问题¶
Reason;:
For 52X, the default IE of other IOs is 1, while the IE of the two 32K IOs is 0 by default;,
The default process, the HAL_PIN_Set function, does not set IE to 1, and for PA22 and PA23, the default IE is 0, so the waveform cannot be output;
Solution;:
Add the HAL_PIN_SetMode function to set the IO as a normal IO, the IE bit will be set to 1, and I2C can output normally;。
Note;:
For 56X, the IE bits of the two 32K IOs, PA55 and PA56, are 1 by default, so this issue does not exist;。
After SDK version v2.2.0, the operation to restore IE to 1 has been added in the HAL_PIN_Set function, no need to add the HAL_PIN_SetMode function anymore;
1.12 PAXX_I2C_UART和PAXX_TIM配置方法¶
For the 55 and 58 series MCUs, each IO is a fixed I2C, UART, PWM output port;,From the 56 and 52 series MCUs onwards, in order to increase the flexibility of IO, it has become flexible configuration as shown in the figure below;:
Because the I2CX_PINR, USART1_PINR, GPTIMX_PINR registers have been introduced in HPSYS_CFG and LPSYS_CFG;,如下图:
As described in the above register diagram: the corresponding I2C1 and I2C2 can be configured to be output on PA00-PA78;,Specifically, which I2C, UART, TIMER outputs can be configured on the PA port depends on which I2C, UART, and TIMER the HCPU possesses;,Note that those owned only by LCPU (e.g., I2C5, UART5) cannot be configured to the PA port, similarly, those owned only by HCPU (e.g., I2C1, UART1) cannot be configured to the PB port of LCPU;,For detailed information on which resources the HCPU possesses, you can refer to the chip user manual;,In the code, the corresponding registers can be viewed in HPSYS_CFG_TypeDef in hpsys_cfg.h and LPSYS_CFG_TypeDef in lpsys_cfg.h;,Additionally, the functions that the MCU can configure are listed in the bf0_pin_const.h file;,如下图:
例如,Correct configuration;(举例为56系列MCU):
HAL_PIN_Set(PAD_PA32, USART1_RXD, PIN_PULLUP, 1);
HAL_PIN_Set(PAD_PA32, I2C1_SCL, PIN_PULLUP, 1);
HAL_PIN_Set(PAD_PA42, GPTIM2_CH4, PIN_NOPULL, 1);//GPTIM2_CH1-GPTIM2_CH4都可以,GPTIM2_CH5不行,因为没有此配置,详情查看对应芯片手册的寄存器:hwp_hpsys_cfg->GPTIM2_PINR
Incorrect configuration;:
HAL_PIN_Set(PAD_PA42,USART4_TXD,PIN_NOPULL, 1);//错误,UART4在Lcpu上,不能配置到Hcpu的PA口
HAL_PIN_Set(PAD_PB37,GPTIM2_CH4,PIN_NOPULL, 0);//错误,GPTIM2在Hcpu上,不能配置到Lcpu的PB口