/** * @brief GPIO初始化配置 * @code * //初始化配置PORTB端口的10引脚为推挽输出引脚 * GPIO_InitTypeDef GPIO_InitStruct1; //申请一个结构变量 * GPIO_InitStruct1.instance = HW_GPIOB; //选择PORTB端口 * GPIO_InitStruct1.mode = kGPIO_Mode_OPP; //推挽输出 * GPIO_InitStruct1.pinx = 10; //选择10引脚 * //调用初始化GPIO函数 * GPIO_Init(&GPIO_InitStruct1); * @endcode * @param GPIO_InitStruct: GPIO初始化结构体,包含了引脚状态参数 GPIO_InitStruct.instance :端口号 HW_GPIOA ~ HW_GPIOE * @retval None */ void GPIO_Init(GPIO_InitTypeDef * GPIO_InitStruct) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(GPIO_InitStruct->instance)); assert_param(IS_PORT_ALL_INSTANCE(GPIO_InitStruct->instance)); assert_param(IS_GPIO_ALL_PIN(GPIO_InitStruct->pinx)); /* config state */ switch(GPIO_InitStruct->mode) { case kGPIO_Mode_IFT: PORT_PinPullConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kPullDisabled); GPIO_PinConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kInput); break; case kGPIO_Mode_IPD: PORT_PinPullConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kPullDown); GPIO_PinConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kInput); break; case kGPIO_Mode_IPU: PORT_PinPullConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kPullUp); GPIO_PinConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kInput); break; case kGPIO_Mode_OPP: PORT_PinPullConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kPullDisabled); GPIO_PinConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kOutput); break; default: break; } /* config pinMux */ PORT_PinMuxConfig(GPIO_InitStruct->instance, GPIO_InitStruct->pinx, kPinAlt1); }
/** * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct. * @param GPIOx GPIO Port * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure * that contains the configuration information for the specified GPIO peripheral. * @retval An ErrorStatus enumeration value: * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content * - ERROR: Not applicable */ ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) { uint32_t pinmask; uint32_t pinpos; uint32_t currentpin; /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); /* ------------------------- Configure the port pins ---------------- */ /* Initialize pinpos on first pin set */ pinmask = ((GPIO_InitStruct->Pin) << GPIO_PIN_MASK_POS) >> GPIO_PIN_NB; pinpos = POSITION_VAL(pinmask); /* Configure the port pins */ while ((pinmask >> pinpos) != 0U) { /* skip if bit is not set */ if ((pinmask & (1U << pinpos)) != 0U) { /* Get current io position */ if (pinpos < GPIO_PIN_MASK_POS) { currentpin = (0x00000101U << pinpos); } else { currentpin = ((0x00010001U << (pinpos - GPIO_PIN_MASK_POS)) | 0x04000000U); } /* Check Pin Mode and Pin Pull parameters */ assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); /* Pin Mode configuration */ LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); /* Pull-up Pull-down resistor configuration*/ LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) { /* Check speed and Output mode parameters */ assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed)); assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); /* Speed mode configuration */ LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); /* Output mode configuration*/ LL_GPIO_SetPinOutputType(GPIOx, currentpin, GPIO_InitStruct->OutputType); } } pinpos++; } return (SUCCESS); }
/** * @brief 设置指定引脚输出高电平或者低电平 * @note 此引脚首先配置成输出引脚 * @code * //设置PORTB端口的10引脚输出高电平 * GPIO_WriteBit(HW_GPIOB, 10, 1); * @endcode * @param instance: GPIO模块号 * @arg HW_GPIOA :芯片的PORTA端口 * @arg HW_GPIOB :芯片的PORTB端口 * @arg HW_GPIOC :芯片的PORTC端口 * @arg HW_GPIOD :芯片的PORTD端口 * @arg HW_GPIOE :芯片的PORTE端口 * @param pinIndex :端口上的引脚号 0~31 * @param data : 引脚的电平状态 * @arg 0 : 低电平 * @arg 1 : 高电平 * @retval None */ void GPIO_WriteBit(uint32_t instance, uint8_t pinIndex, uint8_t data) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(instance)); assert_param(IS_PORT_ALL_INSTANCE(instance)); assert_param(IS_GPIO_ALL_PIN(pinIndex)); (data) ? (GPIO_InstanceTable[instance]->PSOR |= (1 << pinIndex)):(GPIO_InstanceTable[instance]->PCOR |= (1 << pinIndex)); }
/** * @brief 设置引脚为输入还是输出功能 用户一般不必调用 * @note 只有当引脚作为GPIO时才有意义 * @code * // 将PORTB端口的3引脚设置输入引脚 * GPIO_PinConfig(HW_GPIOB, 3, kInpput); * @endcode * @param instance: GPIO模块号 * @arg HW_GPIOA :芯片的PORTA端口 * @arg HW_GPIOB :芯片的PORTB端口 * @arg HW_GPIOC :芯片的PORTC端口 * @arg HW_GPIOD :芯片的PORTD端口 * @arg HW_GPIOE :芯片的PORTE端口 * @param pinIndex :端口上的引脚号 0~31 * @param mode :输入或者输出设置 * @arg kInpput :输入功能选择 * @arg kOutput :输出功能选择 * @retval None */ void GPIO_PinConfig(uint32_t instance, uint8_t pinIndex, GPIO_PinConfig_Type mode) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(instance)); assert_param(IS_PORT_ALL_INSTANCE(instance)); assert_param(IS_GPIO_ALL_PIN(pinIndex)); SIM->SCGC5 |= SIM_GPIOClockGateTable[instance]; (mode == kOutput) ? (GPIO_InstanceTable[instance]->PDDR |= (1 << pinIndex)):(GPIO_InstanceTable[instance]->PDDR &= ~(1 << pinIndex)); }
/** * @brief De-initialize GPIO registers (Registers restored to their default values). * @param GPIOx GPIO Port * @retval An ErrorStatus enumeration value: * - SUCCESS: GPIO registers are de-initialized * - ERROR: Wrong GPIO Port */ ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx) { ErrorStatus status = SUCCESS; /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); /* Force and Release reset on clock of GPIOx Port */ if (GPIOx == GPIOA) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOA); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOA); } else if (GPIOx == GPIOB) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOB); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOB); } else if (GPIOx == GPIOC) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOC); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOC); } else if (GPIOx == GPIOD) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOD); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOD); } #if defined(GPIOE) else if (GPIOx == GPIOE) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOE); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOE); } #endif #if defined(GPIOF) else if (GPIOx == GPIOF) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOF); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOF); } #endif #if defined(GPIOG) else if (GPIOx == GPIOG) { LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_GPIOG); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_GPIOG); } #endif else { status = ERROR; } return (status); }
/** * @brief 设置引脚复用功能 这个函数会被很多其他外设模块驱动程序调用 * @note 复用功能可参考 Reference Manual 的 Signal Multiplexing and Signal Descriptions 章节 * @code * // 将一PORTA端口的3引脚复用成1模式. * PORT_PinMuxConfig(HW_GPIOA, 3, kPinAlt1); * @endcode * @param instance: GPIO模块号 * @arg HW_GPIOA :芯片的PORTA端口 * @arg HW_GPIOB :芯片的PORTB端口 * @arg HW_GPIOC :芯片的PORTC端口 * @arg HW_GPIOD :芯片的PORTD端口 * @arg HW_GPIOE :芯片的PORTE端口 * @param pinIndex :端口上的引脚号 0~31 * @param pinMux :复用功能选项,不同的复用值代表不同的功能 * @arg kPinAlt0 :引脚复用成0模式 * @arg . : . * @arg . : . * @arg . : . * @arg kPinAlt7 :引脚复用成7模式 * @retval None */ void PORT_PinMuxConfig(uint32_t instance, uint8_t pinIndex, PORT_PinMux_Type pinMux) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(instance)); assert_param(IS_PORT_ALL_INSTANCE(instance)); assert_param(IS_GPIO_ALL_PIN(pinIndex)); SIM->SCGC5 |= SIM_GPIOClockGateTable[instance]; PORT_InstanceTable[instance]->PCR[pinIndex] &= ~(PORT_PCR_MUX_MASK); PORT_InstanceTable[instance]->PCR[pinIndex] |= PORT_PCR_MUX(pinMux); }
/** * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct. * @param GPIOx GPIO Port * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure * that contains the configuration information for the specified GPIO peripheral. * @retval An ErrorStatus enumeration value: * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content * - ERROR: Not applicable */ ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) { uint32_t pinpos = 0x00000000U; uint32_t currentpin = 0x00000000U; /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); /* ------------------------- Configure the port pins ---------------- */ /* Initialize pinpos on first pin set */ pinpos = POSITION_VAL(GPIO_InitStruct->Pin); /* Configure the port pins */ while ((((GPIO_InitStruct->Pin) & 0x0000FFFFU) >> pinpos) != 0x00000000U) { /* Get current io position */ if(pinpos <8 ) { currentpin = (GPIO_InitStruct->Pin) & (0x00000101U << pinpos); } else { currentpin = (GPIO_InitStruct->Pin) & ((0x00010001U << (pinpos-8)) | 0x04000000U); } if (currentpin) { /* Pin Mode configuration */ LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); /* Pull-up Pull down resistor configuration*/ LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_FLOATING)) { /* Speed mode configuration */ LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); } } pinpos++; } if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_FLOATING)) { /* Check Output mode parameters */ assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); /* Output mode configuration*/ LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType); } return (SUCCESS); }
/** * @brief 读取一个引脚上的电平状态 * @code * //读取PORTB端口的10引脚的电平状态 * uint8_t status ; //用于存储引脚的状态 * status = GPIO_ReadBit(HW_GPIOB, 10); //获取引脚的状态并存储到status中 * @endcode * @param instance: GPIO模块号 * @arg HW_GPIOA :芯片的PORTA端口 * @arg HW_GPIOB :芯片的PORTB端口 * @arg HW_GPIOC :芯片的PORTC端口 * @arg HW_GPIOD :芯片的PORTD端口 * @arg HW_GPIOE :芯片的PORTE端口 * @param pinIndex :端口上的引脚号 0~31 * @retval * @arg 0 : 低电平 * @arg 1 : 高电平 */ uint8_t GPIO_ReadBit(uint32_t instance, uint8_t pinIndex) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(instance)); assert_param(IS_PORT_ALL_INSTANCE(instance)); assert_param(IS_GPIO_ALL_PIN(pinIndex)); /* input or output */ if(((GPIO_InstanceTable[instance]->PDDR) >> pinIndex) & 0x01) { return ((GPIO_InstanceTable[instance]->PDOR >> pinIndex) & 0x01); } else { return ((GPIO_InstanceTable[instance]->PDIR >> pinIndex) & 0x01);
/** * @brief 设置一个引脚的上下拉电阻功能 用户一般不必调用 * @code * // 将PORTA端口的3引脚设置为上拉电阻(在输入的情况下) * PORT_PinPullConfig(HW_GPIOA, 3, kPullUp); * @endcode * @param instance: GPIO模块号 * @arg HW_GPIOA :芯片的PORTA端口 * @arg HW_GPIOB :芯片的PORTB端口 * @arg HW_GPIOC :芯片的PORTC端口 * @arg HW_GPIOD :芯片的PORTD端口 * @arg HW_GPIOE :芯片的PORTE端口 * @param pinIndex :端口上的引脚号 0~31 * @param pull :引脚电阻模式选择 * @arg kPullDisabled :关闭电阻上下拉 * @arg kPullUp :上拉电阻 * @arg kPullDown :下拉电阻 * @retval None */ void PORT_PinPullConfig(uint32_t instance, uint8_t pinIndex, PORT_Pull_Type pull) { /* param check */ assert_param(IS_GPIO_ALL_INSTANCE(instance)); assert_param(IS_PORT_ALL_INSTANCE(instance)); assert_param(IS_GPIO_ALL_PIN(pinIndex)); SIM->SCGC5 |= SIM_GPIOClockGateTable[instance]; switch(pull) { case kPullDisabled: PORT_InstanceTable[instance]->PCR[pinIndex] &= ~PORT_PCR_PE_MASK; break; case kPullUp: PORT_InstanceTable[instance]->PCR[pinIndex] |= PORT_PCR_PE_MASK; PORT_InstanceTable[instance]->PCR[pinIndex] |= PORT_PCR_PS_MASK; break; case kPullDown: PORT_InstanceTable[instance]->PCR[pinIndex] |= PORT_PCR_PE_MASK; PORT_InstanceTable[instance]->PCR[pinIndex] &= ~PORT_PCR_PS_MASK; break; default: break; } }
/** * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct. * @param GPIOx GPIO Port * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure * that contains the configuration information for the specified GPIO peripheral. * @retval An ErrorStatus enumeration value: * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content * - ERROR: Not applicable */ ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) { uint32_t pinpos = 0x00000000U; uint32_t currentpin = 0x00000000U; /* Check the parameters */ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); /* ------------------------- Configure the port pins ---------------- */ /* Initialize pinpos on first pin set */ /* pinpos = 0; useless as already done in default initialization */ /* Configure the port pins */ while (((GPIO_InitStruct->Pin) >> pinpos) != 0x00000000U) { /* Get current io position */ currentpin = (GPIO_InitStruct->Pin) & (0x00000001U << pinpos); if (currentpin) { /* Pin Mode configuration */ LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) { /* Check Speed mode parameters */ assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed)); /* Speed mode configuration */ LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); } /* Pull-up Pull down resistor configuration*/ LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); if (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE) { /* Check Alternate parameter */ assert_param(IS_LL_GPIO_ALTERNATE(GPIO_InitStruct->Alternate)); /* Speed mode configuration */ if (currentpin < LL_GPIO_PIN_8) { LL_GPIO_SetAFPin_0_7(GPIOx, currentpin, GPIO_InitStruct->Alternate); } else { LL_GPIO_SetAFPin_8_15(GPIOx, currentpin, GPIO_InitStruct->Alternate); } } } pinpos++; } if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) { /* Check Output mode parameters */ assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); /* Output mode configuration*/ LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType); } return (SUCCESS); }