基于上篇《基于STM32F10X的GPIO驱动》增加GPIO的操作功能,并且优化提高部分函数效率。
最重要的添加了未带操作,这样就可以高效的控制GPIO了。
3、未解决的问题:
当前我无法将WHT_GPIO_Pin_enum和WHT_GPIO_Pin_Number_enum通过某种算法关联上,log2(data)不行,无法在编译的时候计算值。导致我需要重新添加枚举。有方法的麻烦分享下。
gpio_bsp.h
//作者:王海涛
#ifndef __GPIO_BSP_H__
#define __GPIO_BSP_H__
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
typedef enum
{
PortA = (uint32_t)GPIOA,
PortB = (uint32_t)GPIOB,
PortC = (uint32_t)GPIOC,
PortD = (uint32_t)GPIOD,
PortE = (uint32_t)GPIOE,
PortF = (uint32_t)GPIOF,
PortG = (uint32_t)GPIOG,
}WHT_GPIO_Port_enum;
typedef enum
{
Pin0 = GPIO_Pin_0,
Pin1 = GPIO_Pin_1,
Pin2 = GPIO_Pin_2,
Pin3 = GPIO_Pin_3,
Pin4 = GPIO_Pin_4,
Pin5 = GPIO_Pin_5,
Pin6 = GPIO_Pin_6,
Pin7 = GPIO_Pin_7,
Pin8 = GPIO_Pin_8,
Pin9 = GPIO_Pin_9,
Pin10 = GPIO_Pin_10,
Pin11 = GPIO_Pin_11,
Pin12 = GPIO_Pin_12,
Pin13 = GPIO_Pin_13,
Pin14 = GPIO_Pin_14,
Pin15 = GPIO_Pin_15,
PinAll= GPIO_Pin_All,
}WHT_GPIO_Pin_enum;
typedef enum
{
Pin_Number0 = 0,
Pin_Number1 = 1,
Pin_Number2 = 2,
Pin_Number3 = 3,
Pin_Number4 = 4,
Pin_Number5 = 5,
Pin_Number6 = 6,
Pin_Number7 = 7,
Pin_Number8 = 8,
Pin_Number9 = 9,
Pin_Number10 = 10,
Pin_Number11 = 11,
Pin_Number12 = 12,
Pin_Number13 = 13,
Pin_Number14 = 14,
Pin_Number15 = 15,
}WHT_GPIO_Pin_Number_enum;
typedef enum
{
Low = 0,
Hig = 1,
Bit_Reset = 0,
Bit_Set = 1,
}WHT_GPIO_State_enum;
typedef enum
{
Mode_Ain = (uint8_t)GPIO_Mode_AIN, //模拟输入
Mode_IN_FLOATING = (uint8_t)GPIO_Mode_IN_FLOATING,//浮空输入
Mode_IPD = (uint8_t)GPIO_Mode_IPD, //下拉输入
Mode_IPU = (uint8_t)GPIO_Mode_IPU, //上拉输入
Mode_Out_OD = (uint8_t)GPIO_Mode_Out_OD, //开漏输出
Mode_Out_PP = (uint8_t)GPIO_Mode_Out_PP, //推挽输出
Mode_AF_OD = (uint8_t)GPIO_Mode_AF_OD, //开漏复用输出
Mode_AF_PP = (uint8_t)GPIO_Mode_AF_PP, //推挽复用输出
}WHT_GPIO_Mode_enum;
typedef struct
{
void (*WHT_Set_GPIO_Mode)(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_Mode_enum mode); //pinx for WHT_GPIO_Pin_enum
void (*WHT_Set_GPIO_State)(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_State_enum state);//pinx for WHT_GPIO_Pin_enum
WHT_GPIO_State_enum(*WHT_Get_GPIO_State)(WHT_GPIO_Port_enum portx, WHT_GPIO_Pin_enum pinx);
uint16_t (*WHT_Get_GPIO_Prot_Value)(WHT_GPIO_Port_enum portx);
void (*WHT_Set_GPIO_Prot_Value)(WHT_GPIO_Port_enum portx,uint16_t port_value);
}WHT_GPIO_Device_t;
extern void WHT_GPIO_Init_Config(WHT_GPIO_Device_t* wht_gpio_device);
//备注:当前我无法将WHT_GPIO_Pin_enum和WHT_GPIO_Pin_Number_enum通过某种算法关联上,log2(data)不行,无法在编译的时候计算值
#define WHT_Set_GPIO_Pin_State(WHT_GPIO_Port_enum,WHT_GPIO_Pin_Number_enum) (*((volatile uint32_t*)(((WHT_GPIO_Port_enum+0x0c)&0xf0000000)+0x02000000+(((WHT_GPIO_Port_enum+0x0c)&0x00ffffff)<<5)+(WHT_GPIO_Pin_Number_enum<<2))))
#define WHT_Get_GPIO_Pin_State(WHT_GPIO_Port_enum,WHT_GPIO_Pin_Number_enum) (*((volatile uint32_t*)(((WHT_GPIO_Port_enum+0x08)&0xf0000000)+0x02000000+(((WHT_GPIO_Port_enum+0x08)&0x00ffffff)<<5)+(WHT_GPIO_Pin_Number_enum<<2))))
#endif /*__GPIO_BSP_H__*/
gpio_bsp.c
//作者:王海涛
#include "gpio_bsp.h"
static void wht_set_gpio_mode(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_Mode_enum mode)
{
GPIO_InitTypeDef GPIO_InitStruct;
uint32_t RCC_APB2Periph;
switch (portx)
{
case PortA:RCC_APB2Periph = RCC_APB2Periph_GPIOA; break;
case PortB:RCC_APB2Periph = RCC_APB2Periph_GPIOB; break;
case PortC:RCC_APB2Periph = RCC_APB2Periph_GPIOC; break;
case PortD:RCC_APB2Periph = RCC_APB2Periph_GPIOD; break;
case PortE:RCC_APB2Periph = RCC_APB2Periph_GPIOE; break;
case PortF:RCC_APB2Periph = RCC_APB2Periph_GPIOF; break;
case PortG:RCC_APB2Periph = RCC_APB2Periph_GPIOG; break;
default:
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph, ENABLE);
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = (GPIOMode_TypeDef)mode;
GPIO_InitStruct.GPIO_Pin = pinx;
GPIO_Init((GPIO_TypeDef*)portx, &GPIO_InitStruct);
}
static void wht_set_gpio_state(WHT_GPIO_Port_enum portx, uint16_t pinx, WHT_GPIO_State_enum state)
{
GPIO_WriteBit((GPIO_TypeDef*)portx, pinx, (BitAction)state);
}
static WHT_GPIO_State_enum wht_get_gpio_state(WHT_GPIO_Port_enum portx, uint16_t pinx)
{
return (WHT_GPIO_State_enum)GPIO_ReadInputDataBit((GPIO_TypeDef*)portx, pinx);
}
static uint16_t wht_get_gpio_prot_value(WHT_GPIO_Port_enum portx)
{
return GPIO_ReadInputData((GPIO_TypeDef*)portx);
}
static void wht_set_gpio_prot_value(WHT_GPIO_Port_enum portx,uint16_t port_value)
{
GPIO_Write((GPIO_TypeDef*)portx, port_value);
}
void WHT_GPIO_Init_Config(WHT_GPIO_Device_t* wht_gpio_device)
{
wht_gpio_device->WHT_Set_GPIO_Mode = wht_set_gpio_mode;
wht_gpio_device->WHT_Get_GPIO_State = wht_get_gpio_state;
wht_gpio_device->WHT_Set_GPIO_State = wht_set_gpio_state;
wht_gpio_device->WHT_Get_GPIO_Prot_Value = wht_get_gpio_prot_value;
wht_gpio_device->WHT_Set_GPIO_Prot_Value = wht_set_gpio_prot_value;
}
LED驱动为了适配新的GPIO驱动,故做了优化调整。
led_driver.h
//作者:王海涛
#ifndef __LED_DRIVER_H__
#define __LED_DRIVER_H__
#include "../../BSP/GPIO_BSP/gpio_bsp.h"
//Red
#define LED0_GPIO_Port PortB
#define LED0_GPIO_Pin Pin5
#define LED0_State WHT_Set_GPIO_Pin_State(LED0_GPIO_Port,Pin_Number5)
//Green
#define LED1_GPIO_Port PortB
#define LED1_GPIO_Pin Pin0
#define LED1_State WHT_Set_GPIO_Pin_State(LED1_GPIO_Port,Pin_Number0)
//Blue
#define LED2_GPIO_Port PortB
#define LED2_GPIO_Pin Pin1
#define LED2_State WHT_Set_GPIO_Pin_State(LED2_GPIO_Port,Pin_Number1)
typedef enum
{
LED_RED = 0,//红色
LED_GREEN = 1,//绿色
LED_BLUE = 2,//蓝色
LED_YELLOW = 3,//黄色(红+绿)
LED_PURPLE = 4,//紫色(红+蓝)
LED_CYAN = 5,//青色(绿+蓝)
LED_WHITE = 6,//白色(红+绿+蓝)
LED_RGBOFF = 7,//黑色(全部关闭)
}WHT_LED_Color_enum;
extern void WHT_LED_Init_Config(void);
extern void WHT_LED_Color_Set(WHT_LED_Color_enum LED_Color);
#endif /* __LED_DRIVER_H__ */
led_driver.c
//作者:王海涛
#include "led_driver.h"
static void gpio_init_config(void)
{
WHT_GPIO_Device_t wht_device;
WHT_GPIO_Init_Config(&wht_device);
WHT_LED_Color_Set(LED_WHITE);
wht_device.WHT_Set_GPIO_Mode(LED0_GPIO_Port, LED0_GPIO_Pin, Mode_Out_PP);
wht_device.WHT_Set_GPIO_Mode(LED1_GPIO_Port, LED1_GPIO_Pin, Mode_Out_PP);
wht_device.WHT_Set_GPIO_Mode(LED2_GPIO_Port, LED2_GPIO_Pin, Mode_Out_PP);
}
void WHT_LED_Color_Set(WHT_LED_Color_enum LED_Color)
{
switch (LED_Color)
{
case LED_RED:
LED0_State = Low;
LED1_State = Hig;
LED2_State = Hig;
break;
case LED_GREEN:
LED0_State = Hig;
LED1_State = Low;
LED2_State = Hig;
break;
case LED_BLUE:
LED0_State = Hig;
LED1_State = Hig;
LED2_State = Low;
break;
case LED_YELLOW:
LED0_State = Low;
LED1_State = Low;
LED2_State = Hig;
break;
case LED_PURPLE:
LED0_State = Low;
LED1_State = Hig;
LED2_State = Low;
break;
case LED_CYAN:
LED0_State = Hig;
LED1_State = Low;
LED2_State = Low;
break;
case LED_WHITE:
LED0_State = Low;
LED1_State = Low;
LED2_State = Low;
break;
case LED_RGBOFF:
LED0_State = Hig;
LED1_State = Hig;
LED2_State = Hig;
break;
default:
return;
}
}
void WHT_LED_Init_Config(void)
{
gpio_init_config();
}