#include #include "./GPIO.h" /* GPIO私有数据类型 */ typedef struct { GPIO_TypeDef *GPIOx; GPIOMode_TypeDef GPIO_Mode; GPIOOType_TypeDef GPIO_OType; GPIOPuPd_TypeDef GPIO_PuPd; uint32_t RCC_AHB1Periph_GPIOx; } gpio_priv_obj_t; /* GPIO相关操作函数声明 */ static int gpio_init(gpio_obj_t *pDev, uint16_t gpio_pin, char *gpio_mode, char *gpio_pupd); static void gpio_deinit(gpio_obj_t *pDev); static void gpio_set_output(gpio_obj_t *pDev, uint16_t gpio_pin, uint8_t voltage); static uint16_t gpio_read_output(gpio_obj_t *pDev); static uint16_t gpio_read_input(gpio_obj_t *pDev); static void gpio_open_irq(gpio_obj_t *pDev, uint8_t GPIO_PinSource, uint8_t EXTI_Trigger, uint8_t Priority, CallBack irq_handle); static void gpio_close_irq(gpio_obj_t *pDev, uint8_t GPIO_PinSource); /* GPIOA私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_a_priv = { GPIOA, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOA }; /* GPIOA结构体对象 */ static gpio_obj_t g_stm32f103_gpio_a = { "gpio_a", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_a_priv }; /* GPIOB私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_b_priv = { GPIOB, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOB }; /* GPIOB结构体对象 */ static gpio_obj_t g_stm32f103_gpio_b = { "gpio_b", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_b_priv }; /* GPIOC私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_c_priv = { GPIOC, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOC }; /* GPIOC结构体对象 */ static gpio_obj_t g_stm32f103_gpio_c = { "gpio_c", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_c_priv }; /* GPIOD私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_d_priv = { GPIOD, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOD }; /* GPIOD结构体对象 */ static gpio_obj_t g_stm32f103_gpio_d = { "gpio_d", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_d_priv }; /* GPIOE私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_e_priv = { GPIOE, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOE }; /* GPIOE结构体对象 */ static gpio_obj_t g_stm32f103_gpio_e = { "gpio_e", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_e_priv }; /* GPIOF私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_f_priv = { GPIOF, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOF }; /* GPIOF结构体对象 */ static gpio_obj_t g_stm32f103_gpio_f = { "gpio_f", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_f_priv }; /* GPIOG私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_g_priv = { GPIOG, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOG }; /* GPIOG结构体对象 */ static gpio_obj_t g_stm32f103_gpio_g = { "gpio_g", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_g_priv }; /* GPIOH私有数据 */ static gpio_priv_obj_t g_stm32f103_gpio_h_priv = { GPIOH, GPIO_Mode_IN, (GPIOOType_TypeDef)0, (GPIOPuPd_TypeDef)0, RCC_AHB1Periph_GPIOH }; /* GPIOH结构体对象 */ static gpio_obj_t g_stm32f103_gpio_h = { "gpio_h", 0, "gpio_mode", gpio_init, gpio_deinit, gpio_set_output, gpio_read_output, gpio_read_input, gpio_open_irq, gpio_close_irq, &g_stm32f103_gpio_h_priv }; /* GPIO外设列表 */ static gpio_obj_t *g_gpio_devs[] = { &g_stm32f103_gpio_a, &g_stm32f103_gpio_b, &g_stm32f103_gpio_c, &g_stm32f103_gpio_d, &g_stm32f103_gpio_e, &g_stm32f103_gpio_f, &g_stm32f103_gpio_g, &g_stm32f103_gpio_h }; /* GPIO模式私有数据列表 */ static GPIOMode_TypeDef g_gpio_mode_priv_list[] = { GPIO_Mode_AN, GPIO_Mode_IN, GPIO_Mode_AF, GPIO_Mode_OUT }; /* GPIO模式列表 */ static char *g_gpio_mode_list[] = { "AN", "IN", "AF_PP", "AF_OD", "OUT_PP", "OUT_OD" }; /* GPIO输出模式私有数据列表 */ static GPIOOType_TypeDef g_gpio_out_mode_priv_list[] = { GPIO_OType_PP, GPIO_OType_OD }; /* GPIO上下拉模式私有数据列表 */ static GPIOPuPd_TypeDef g_gpio_pupd_priv_list[] = { GPIO_PuPd_NOPULL, GPIO_PuPd_UP, GPIO_PuPd_DOWN }; /* GPIO上下拉输出模式列表 */ static char *g_gpio_pupd_list[] = { "NONE", "UP", "DOWN" }; /* GPIO中断注册函数列表 */ /* gpio_irq_handle_list[x] --> EXTI_Line_x */ CallBack g_gpio_irq_handle_list[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; /* *@函数名:gpio_init *@函数功能:初始化指定GPIO端口 *@参数: * @pDev:指定GPIO端口句柄 * @gpio_pin:GPIO端口引脚 * value:gpio_pin_0 ~ gpio_pin_15,支持位或同时初始化相同端口的多个引脚 * @gpio_mode:GPIO模式 * value:"IN"、 "AF_PP"、 "AF_OD"、 "AN"、 "OUT_PP"、 "OUT_OD" *@返回值 * 0:GPIO初始化成功 * -1:GPIO初始化失败 */ static int gpio_init(gpio_obj_t *pDev, uint16_t gpio_pin, char *gpio_mode, char *gpio_pupd) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; uint8_t gpio_mode_flag = 0; uint8_t gpio_pupd_flag = 0; uint8_t gpio_mode_num = sizeof(g_gpio_mode_list) / sizeof(g_gpio_mode_list[0]); uint8_t gpio_pupd_num = sizeof(g_gpio_pupd_list) / sizeof(g_gpio_pupd_list[0]); for(uint8_t i = 0; i < gpio_mode_num; i++) { if(0 == strcmp(gpio_mode, g_gpio_mode_list[i])) { pDev->gpio_mode = g_gpio_mode_list[i]; gpio_mode_flag = 1; if(0 == strcmp(gpio_mode, "OUT_PP")) { gpio_priv_obj->GPIO_Mode = g_gpio_mode_priv_list[3]; gpio_priv_obj->GPIO_OType = g_gpio_out_mode_priv_list[0]; //设置输出模式为推挽输出 } else if(0 == strcmp(gpio_mode, "OUT_OD")) { gpio_priv_obj->GPIO_Mode = g_gpio_mode_priv_list[3]; gpio_priv_obj->GPIO_OType = g_gpio_out_mode_priv_list[1]; //设置输出模式为开漏输出 } else if(0 == strcmp(gpio_mode, "AF_PP")) { gpio_priv_obj->GPIO_Mode = g_gpio_mode_priv_list[2]; gpio_priv_obj->GPIO_OType = g_gpio_out_mode_priv_list[0]; //设置复用输出模式为推挽输出 } else if(0 == strcmp(gpio_mode, "AF_OD")) { gpio_priv_obj->GPIO_Mode = g_gpio_mode_priv_list[2]; gpio_priv_obj->GPIO_OType = g_gpio_out_mode_priv_list[1]; //设置输出模式为开漏输出 } else { gpio_priv_obj->GPIO_Mode = g_gpio_mode_priv_list[i]; } break; } } for(uint8_t i = 0; i < gpio_pupd_num; i++) { if(0 == strcmp(gpio_pupd, g_gpio_pupd_list[i])) { gpio_priv_obj->GPIO_PuPd = g_gpio_pupd_priv_list[i]; gpio_pupd_flag = 1; break; } } if((0 == gpio_mode_flag) || (0 == gpio_pupd_flag)) { return -1; } pDev->gpio_pin = gpio_pin; RCC_AHB1PeriphClockCmd(gpio_priv_obj->RCC_AHB1Periph_GPIOx, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = pDev->gpio_pin; GPIO_InitStructure.GPIO_Mode = gpio_priv_obj->GPIO_Mode; GPIO_InitStructure.GPIO_OType = gpio_priv_obj->GPIO_OType; GPIO_InitStructure.GPIO_PuPd = gpio_priv_obj->GPIO_PuPd; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(gpio_priv_obj->GPIOx, &GPIO_InitStructure); return 0; } /* *@函数名:gpio_deinit *@函数功能:复位指定GPIO端口 *@参数: * @pDev:指定GPIO端口句柄 *@返回值:无 */ static void gpio_deinit(gpio_obj_t *pDev) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; GPIO_DeInit(gpio_priv_obj->GPIOx); } /* *@函数名:gpio_set_output *@函数功能:设置GPIO端口指定引脚电平 *@参数: * @pDev:指定GPIO端口句柄 * @gpio_pin:GPIO端口引脚 * value:gpio_pin_0 ~ gpio_pin_15,支持位或同时初始化相同端口的多个引脚 * @voltage:输出引脚电平 * value:0:低电平、 1:高电平 *@返回值:无 */ static void gpio_set_output(gpio_obj_t *pDev, uint16_t gpio_pin, uint8_t voltage) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; GPIO_WriteBit(gpio_priv_obj->GPIOx, gpio_pin, (BitAction)voltage); } /* *@函数名:gpio_read_output *@函数功能:读取GPIO端口输出的电平 *@参数: * @pDev:指定GPIO端口句柄 *@返回值:一组GPIO电平 */ static uint16_t gpio_read_output(gpio_obj_t *pDev) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; return GPIO_ReadOutputData(gpio_priv_obj->GPIOx); } /* *@函数名:gpio_read_input *@函数功能:读取GPIO端口输入的电平 *@参数: * @pDev:指定GPIO端口句柄 *@返回值:一组GPIO电平 */ static uint16_t gpio_read_input(gpio_obj_t *pDev) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; return GPIO_ReadInputData(gpio_priv_obj->GPIOx); } /* *@函数名:gpio_open_irq *@函数功能:开启GPIO引脚中断 *@参数: * @pDev:指定GPIO端口句柄 * @GPIO_PinSource:中断引脚号:0 ~ 15 * @EXTI_Trigger:中断触发方式 * value:0:上升沿触发、 1:下降沿触发、 2:上升沿和下降沿都触发 * @Priority:中断抢占式优先级 *@返回值:无 */ static void gpio_open_irq(gpio_obj_t *pDev, uint8_t GPIO_PinSource, uint8_t EXTI_Trigger, uint8_t Priority, CallBack irq_handle) { gpio_priv_obj_t *gpio_priv_obj = pDev->gpio_priv_data; g_gpio_irq_handle_list[GPIO_PinSource] = irq_handle; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); /* 将GPIOx对应到GPIO_PortSourcex */ uint8_t GPIO_PortSource = (uint8_t)((uint16_t)((uint32_t)gpio_priv_obj->GPIOx & 0x0000ffff) / 0x0400); SYSCFG_EXTILineConfig(GPIO_PortSource, GPIO_PinSource); switch(EXTI_Trigger) { case 0:EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; break; case 1:EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; break; case 2:EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; break; default:break; } EXTI_InitStructure.EXTI_Line = (1 << GPIO_PinSource); EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); if(GPIO_PinSource < 5) { NVIC_InitStructure.NVIC_IRQChannel = (GPIO_PinSource + 6); } else if((4 < GPIO_PinSource) && (10 > GPIO_PinSource)) { NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; } else { NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; } NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Priority; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /* *@函数名:gpio_close_irq *@函数功能:关闭GPIO引脚中断 *@参数: * @pDev:指定GPIO端口句柄 * @GPIO_PinSource:中断引脚号:0 ~ 15 *@返回值:无 */ static void gpio_close_irq(gpio_obj_t *pDev, uint8_t GPIO_PinSource) { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = (1 << GPIO_PinSource); EXTI_InitStructure.EXTI_LineCmd = DISABLE; EXTI_Init(&EXTI_InitStructure); if(GPIO_PinSource < 5) { NVIC_InitStructure.NVIC_IRQChannel = (GPIO_PinSource + 6); } else if((4 < GPIO_PinSource) && (10 > GPIO_PinSource)) { NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; } else if((9 < GPIO_PinSource) && (16 > GPIO_PinSource)) { NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; } else { } NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); } /* *@函数名:EXTI0_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI0_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line0)) { (g_gpio_irq_handle_list[0])(); } EXTI_ClearITPendingBit(EXTI_Line0); } /* *@函数名:EXTI1_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI1_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line1)) { (g_gpio_irq_handle_list[1])(); } EXTI_ClearITPendingBit(EXTI_Line1); } /* *@函数名:EXTI2_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI2_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line2)) { (g_gpio_irq_handle_list[2])(); } EXTI_ClearITPendingBit(EXTI_Line2); } /* *@函数名:EXTI3_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI3_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line3)) { (g_gpio_irq_handle_list[3])(); } EXTI_ClearITPendingBit(EXTI_Line3); } /* *@函数名:EXTI4_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI4_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line4)) { (g_gpio_irq_handle_list[4])(); } EXTI_ClearITPendingBit(EXTI_Line4); } /* *@函数名:EXTI9_5_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI9_5_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line5)) { (g_gpio_irq_handle_list[5])(); EXTI_ClearITPendingBit(EXTI_Line5); } else if(SET == EXTI_GetITStatus(EXTI_Line6)) { (g_gpio_irq_handle_list[6])(); EXTI_ClearITPendingBit(EXTI_Line6); } else if(SET == EXTI_GetITStatus(EXTI_Line7)) { (g_gpio_irq_handle_list[7])(); EXTI_ClearITPendingBit(EXTI_Line7); } else if(SET == EXTI_GetITStatus(EXTI_Line8)) { (g_gpio_irq_handle_list[8])(); EXTI_ClearITPendingBit(EXTI_Line8); } else { (g_gpio_irq_handle_list[9])(); EXTI_ClearITPendingBit(EXTI_Line9); } } /* *@函数名:EXTI15_10_IRQHandler *@函数功能:GPIO中断处理 *@参数:无 *@返回值:无 */ void EXTI15_10_IRQHandler(void) { if(SET == EXTI_GetITStatus(EXTI_Line10)) { (g_gpio_irq_handle_list[10])(); EXTI_ClearITPendingBit(EXTI_Line10); } else if(SET == EXTI_GetITStatus(EXTI_Line11)) { (g_gpio_irq_handle_list[11])(); EXTI_ClearITPendingBit(EXTI_Line11); } else if(SET == EXTI_GetITStatus(EXTI_Line12)) { (g_gpio_irq_handle_list[12])(); EXTI_ClearITPendingBit(EXTI_Line12); } else if(SET == EXTI_GetITStatus(EXTI_Line13)) { (g_gpio_irq_handle_list[13])(); EXTI_ClearITPendingBit(EXTI_Line13); } else if(SET == EXTI_GetITStatus(EXTI_Line14)) { (g_gpio_irq_handle_list[14])(); EXTI_ClearITPendingBit(EXTI_Line14); } else { (g_gpio_irq_handle_list[15])(); EXTI_ClearITPendingBit(EXTI_Line15); } } /* *@函数名:Get_GPIO_Handle *@函数功能:获取GPIO句柄 *@参数: * @name:指定GPIO端口 * value:gpio_x x可以是a ~ g *@返回值:GPIO端口句柄 */ gpio_obj_t *get_gpio_obj(char *name) { gpio_obj_t *gpio_return_handle= NULL; uint8_t gpio_dev_num = sizeof(g_gpio_devs) / sizeof(g_gpio_devs[0]); for(uint8_t i = 0; i < gpio_dev_num; i++) { if(0 == strcmp(name, g_gpio_devs[i]->name)) { gpio_return_handle = g_gpio_devs[i]; return gpio_return_handle; } } return gpio_return_handle; }