/** * @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 设置指定引脚输出高电平或者低电平 * @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 设置引脚复用功能 这个函数会被很多其他外设模块驱动程序调用 * @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 读取一个引脚上的电平状态 * @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; } }