简介:
最近在学i.mx6ull的裸机开发,感觉看的视频讲的不好,于是我就参考着STM32的固件库自己写了一个类似STM32的GPIO的驱动,谁想用拿走就好,能打赏几个钱就更好啦,毕竟纯原创嘛,还是有点辛苦的。
```头文件
#ifndef __BSP_GPIO_H
#define __BSP_GPIO_H
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
#include "myCortexA7.h" /* 里面是基本数据类型的重命名,自己写一下就好啦 */
/**
* @brief GPIO Configuration slew rate filed enumeration
*/
typedef enum{
SRE_Slow_Slew_Rate=0, /*!< slow slew rate mode */
SRE_Fast_Slew_Rate, /*!< fast slew rate mode */
}PADSRE_TypeDef;
/**
* @brief GPIO Configuration drive strength capibility enumeration
*/
typedef enum{
DSE_Output_Disable=0, /*!< disable output */
DSE_R0_1, /*!< drive strength: R0 */
DSE_R0_2, /*!< drive strength: R0/2 */
DSE_R0_3, /*!< drive strength: R0/3 */
DSE_R0_4, /*!< drive strength: R0/4 */
DSE_R0_5, /*!< drive strength: R0/5 */
DSE_R0_6, /*!< drive strength: R0/6 */
DSE_R0_7, /*!< drive strength: R0/7 */
}PADDSE_TypeDef;
/**
* @brief GPIO Configuration speed enumeration
*/
typedef enum{
SPEED_low_50MHz=0, /*!< low: 50MHz */
SPEED_medium_100MHz, /*!< dmedium: 100MHz */
SPEED_Medium_100MHz, /*!< dmedium: 100MHz */
SPEED_fast_200MHz, /*!< max: 200MHz */
}PADSPEED_TypeDef;
/**
* @brief GPIO Configuration open drain enumeration
*/
typedef enum{
ODE_Open_drain_disable=0, /*!< open drain disabled */
ODE_Open_drain_enable, /*!< open drain enabled */
}PADODE_TypeDef;
/**
* @brief GPIO Configuration pull/keep enumeration
*/
typedef enum{
PKE_Pull_keeper_disable=0, /*!< pull/keeper disabled */
PKE_Pull_keeper_enable, /*!< pull/keeper enabled */
}PADPKE_TypeDef;
/**
* @brief GPIO Configuration pull/keep select enumeration
*/
typedef enum{
PUE_Keeper=0, /*!< keeper */
PUE_Pull, /*!< pull */
}PADPUE_TypeDef;
/**
* @brief GPIO Configuration pull up/down enumeration
*/
typedef enum{
PUS_100K_Pull_Down=0, /*!< 100K Ohm pull down */
PUS_47K_Pull_Up, /*!< 47K Ohm pull up */
PUS_100K_Pull_Up, /*!< 100K Ohm pull up */
PUS_22K_Pull_Up, /*!< 100K Ohm pull up */
}PADPUS_TypeDef;
/**
* @brief GPIO Configuration hyst. enable enumeration
*/
typedef enum{
HYS_Hysteresis_disable=0, /*!< pull/keeper disabled */
HYS_Hysteresis_enable, /*!< pull/keeper enabled */
}PADHYS_TypeDef;
/**
* @brief GPIO Configuration input/output direcction enumeration
*/
typedef enum{
DIR_Mode_input=0U, /*!< pull/keeper disabled */
DIR_Mode_output, /*!< pull/keeper enabled */
}PADDIR_TypeDef;
/**
* @brief PAD Init structure definition
*/ /* PAD IOMUX Register CPSR */
/* 只用与常见的GPIO,使用前要对照以下参考手册,看看寄存器位的定义是否满足 */
typedef struct
{
union { /*!< configure IOMUXC electric register */
struct{
uint32_t SRE:1; /*!< bit: 0 Slew Rate Field */
uint32_t _reserved0:2; /*!< bit: 1..2 Reserved */
uint32_t DSE:3; /*!< bit: 3..5 Drive Strength capibility */
uint32_t SPEED:2; /*!< bit: 6..7 Speed Field */
uint32_t _reserved1:3; /*!< bit: 8..10 Reserved */
uint32_t ODE:1; /*!< bit: 11 Open Drain Enable */
uint32_t PKE:1; /*!< bit: 12 Pull/Keep enable */
uint32_t PUE:1; /*!< bit: 13 Pull/Keep selsect */
uint32_t PUS:2; /*!< bit: 14..15 Pull up/down configure */
uint32_t HYS:1; /*!< bit: 16 Hyst enable */
uint32_t _reserved2:15; /*!< bit: 17..31 If-Then execution state bits 0-1 */
} b;
uint32_t w;
} pad;
PADDIR_TypeDef DIR;
} PAD_InitTypeDef;
/**
* @brief GPIO Bit SET and Bit RESET enumeration
*/
typedef enum
{
Bit_RESET = 0,
Bit_SET
}BitAction;
/** @defgroup GPIO_pins_define
* @{
*/
#define GPIO_Pin_0 ((uint32_t)0x00000001) /* Pin 0 selected */
#define GPIO_Pin_1 ((uint32_t)0x00000002) /* Pin 1 selected */
#define GPIO_Pin_2 ((uint32_t)0x00000004) /* Pin 2 selected */
#define GPIO_Pin_3 ((uint32_t)0x00000008) /* Pin 3 selected */
#define GPIO_Pin_4 ((uint32_t)0x00000010) /* Pin 4 selected */
#define GPIO_Pin_5 ((uint32_t)0x00000020) /* Pin 5 selected */
#define GPIO_Pin_6 ((uint32_t)0x00000040) /* Pin 6 selected */
#define GPIO_Pin_7 ((uint32_t)0x00000080) /* Pin 7 selected */
#define GPIO_Pin_8 ((uint32_t)0x00000100) /* Pin 8 selected */
#define GPIO_Pin_9 ((uint32_t)0x00000200) /* Pin 9 selected */
#define GPIO_Pin_10 ((uint32_t)0x00000400) /* Pin 10 selected */
#define GPIO_Pin_11 ((uint32_t)0x00000800) /* Pin 11 selected */
#define GPIO_Pin_12 ((uint32_t)0x00001000) /* Pin 12 selected */
#define GPIO_Pin_13 ((uint32_t)0x00002000) /* Pin 13 selected */
#define GPIO_Pin_14 ((uint32_t)0x00004000) /* Pin 14 selected */
#define GPIO_Pin_15 ((uint32_t)0x00008000) /* Pin 15 selected */
#define GPIO_Pin_16 ((uint32_t)0x00010000) /* Pin 16 selected */
#define GPIO_Pin_17 ((uint32_t)0x00020000) /* Pin 17 selected */
#define GPIO_Pin_18 ((uint32_t)0x00040000) /* Pin 18 selected */
#define GPIO_Pin_19 ((uint32_t)0x00080000) /* Pin 19 selected */
#define GPIO_Pin_20 ((uint32_t)0x00100000) /* Pin 20 selected */
#define GPIO_Pin_21 ((uint32_t)0x00200000) /* Pin 21 selected */
#define GPIO_Pin_22 ((uint32_t)0x00400000) /* Pin 22 selected */
#define GPIO_Pin_23 ((uint32_t)0x00800000) /* Pin 23 selected */
#define GPIO_Pin_24 ((uint32_t)0x01000000) /* Pin 24 selected */
#define GPIO_Pin_25 ((uint32_t)0x02000000) /* Pin 25 selected */
#define GPIO_Pin_26 ((uint32_t)0x04000000) /* Pin 26 selected */
#define GPIO_Pin_27 ((uint32_t)0x08000000) /* Pin 27 selected */
#define GPIO_Pin_28 ((uint32_t)0x10000000) /* Pin 28 selected */
#define GPIO_Pin_29 ((uint32_t)0x20000000) /* Pin 29 selected */
#define GPIO_Pin_30 ((uint32_t)0x40000000) /* Pin 30 selected */
#define GPIO_Pin_31 ((uint32_t)0x80000000) /* Pin 31 selected */
/**
* @brief GPIO interrupt mode enumeration
*/
typedef enum{
INT_lowLevel=0U,
INT_highLevel,
INT_risingEdge,
INT_fallingEdge,
INT_twoEdge,
}PADINT_TypeDef;
/**
* @brief GPIO interrupt pin number enumeration
*/
typedef enum{
NUM_pin0=0U,
NUM_pin1,
NUM_pin2,
NUM_pin3,
NUM_pin4,
NUM_pin5,
NUM_pin6,
NUM_pin7,
NUM_pin8,
NUM_pin9,
NUM_pin10,
NUM_pin11,
NUM_pin12,
NUM_pin13,
NUM_pin14,
NUM_pin15,
NUM_pin16,
NUM_pin17,
NUM_pin18,
NUM_pin19,
NUM_pin20,
NUM_pin21,
NUM_pin22,
NUM_pin23,
NUM_pin24,
NUM_pin25,
NUM_pin26,
NUM_pin27,
NUM_pin28,
NUM_pin29,
NUM_pin30,
NUM_pin31,
}PADNUM_TypeDef;
typedef struct{
PADNUM_TypeDef interruptPin;
PADINT_TypeDef interruptMode;
}PAD_INTTypeDef;
/* Initialization and Configuration functions *******/
void GPIO_Init(uint32_t muxRegister,
uint32_t muxMode,
uint32_t inputRegister,
uint32_t inputDaisy,
uint32_t configRegister,
GPIO_Type* GPIOx,
uint32_t GPIO_Pin,
PAD_InitTypeDef PAD_InitStruct
);
/* GPIO Read and Write functions **********************************************/
uint8_t GPIO_ReadInputDataBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin);
void GPIO_WriteBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin, BitAction BitVal);
void GPIO_SetBits(GPIO_Type* GPIOx, uint32_t GPIO_Pin);
void GPIO_ResetBits(GPIO_Type* GPIOx, uint32_t GPIO_Pin);
/* interrupt */
void GPIO_ITConfig(GPIO_Type* GPIOx, uint32_t GPIO_Pin,
PAD_INTTypeDef PAD_INTStruct,
FunctionalState newState);
ITStatus GPIO_getITStatus(GPIO_Type* GPIOx, uint32_t GPIO_Pin);
void GPIO_clearITPendingBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin);
#endif /* __BSP_GPIO_H */
下面是源文件:
```源文件
#include "bsp_gpio.h"
/*!
* @brief Sets the IOMUXC pin mux mode.
* @note The first five parameters can be filled with the pin function ID macros.
* this function is not supuort to configure inputOnfield!!
* @param muxRegister The pin mux register.
* @param muxMode The pin mux mode.
* @param inputRegister The select input register.
* @param inputDaisy The input daisy.
* @param configRegister The config register.
* @param inputOnfield Software input on field.
*/
void GPIO_Init(uint32_t muxRegister,
uint32_t muxMode,
uint32_t inputRegister,
uint32_t inputDaisy,
uint32_t configRegister,
GPIO_Type* GPIOx,
uint32_t GPIO_Pin,
PAD_InitTypeDef PAD_InitStruct
)
{
/* configure IOMUXC register */
*((volatile uint32_t *)muxRegister) =
IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode);
if (inputRegister)
{
*((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy);
}
if (configRegister)
{
*((volatile uint32_t *)configRegister) = PAD_InitStruct.pad.w;
}
/* GDIR */
if(PAD_InitStruct.DIR == DIR_Mode_output ){ /* output mode */
GPIOx->GDIR |= GPIO_Pin;
}
else{
GPIOx->GDIR &= ~GPIO_Pin;
}
}
/**
* @brief Reads the specified input port pin.
* @param GPIOx: where x can be (1..) to select the GPIO peripheral
*
* @param GPIO_Pin: specifies the port bit to read.
* This parameter can be GPIO_Pin_x where x can be (0..31).
* @retval The input port pin value.
*/
uint8_t GPIO_ReadInputDataBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin){
uint8_t bitStatus = 0x00;
if( (GPIOx->DR & GPIO_Pin) != (uint32_t)Bit_RESET){
bitStatus = (uint8_t)Bit_SET;
}
else{
bitStatus = (uint8_t)Bit_RESET;
}
return bitStatus;
}
/**
* @brief Sets or clears the selected data port bit.
* @param GPIOx: where x can be (1..) to select the GPIO peripheral
* @param GPIO_Pin: specifies the port bit to be written.
* This parameter can be one of GPIO_Pin_x where x can be (0..31).
* @param BitVal: specifies the value to be written to the selected bit.
* This parameter can be one of the BitAction enum values:
* @arg Bit_RESET: to clear the port pin
* @arg Bit_SET: to set the port pin
* @retval None
*/
void GPIO_WriteBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin, BitAction BitVal){
if(BitVal != Bit_RESET){ /* 写1 */
GPIOx->DR |= GPIO_Pin;
}
else{
GPIOx->DR &= ~GPIO_Pin;
}
}
/**
* @brief Sets the selected data port bits.
* @param GPIOx: where x can be (1..) to select the GPIO peripheral
* @param GPIO_Pin: specifies the port bits to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..31).
* @retval None
*/
void GPIO_SetBits(GPIO_Type* GPIOx, uint32_t GPIO_Pin){
GPIOx->DR |= GPIO_Pin;
}
/**
* @brief Clears the selected data port bits.
* @param GPIOx: where x can be (1..) to select the GPIO peripheral
* @param GPIO_Pin: specifies the port bits to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..31).
* @retval None
*/
void GPIO_ResetBits(GPIO_Type* GPIOx, uint32_t GPIO_Pin){
GPIOx->DR &= ~GPIO_Pin;
}
/**
* @brief Enables or disables the specified Pad interrupts.
* @param GPIO_Pin: select the pin
* @param PAD_INTStruct: specifies the GPIO interrupts mode and pin number
* @param NewState: new state of the TIM interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void GPIO_ITConfig(GPIO_Type* GPIOx, uint32_t GPIO_Pin,
PAD_INTTypeDef PAD_INTStruct,
FunctionalState newState)
{
if(newState != DISABLE){
/* enable the interrupt source */
GPIOx->IMR |= GPIO_Pin;
if(PAD_INTStruct.interruptMode == INT_twoEdge){
GPIOx->EDGE_SEL |= GPIO_Pin;
}
else if(GPIO_Pin < GPIO_Pin_16){
GPIOx->ICR1 |= ( PAD_INTStruct.interruptMode<<(PAD_INTStruct.interruptPin*2) );
}
else{
GPIOx->ICR2 |= ( PAD_INTStruct.interruptMode<<( (PAD_INTStruct.interruptPin-16UL)*2) );
}
}
else{
/* disable the interrupt source */
GPIOx->IMR &= ~GPIO_Pin;
}
}
/**
* @brief Checks whether the GPIO pad interrupt has occurred or not.
* @param GPIOx: where x can be 1 to 14 to select the TIM peripheral.
* @param GPIO_Pin: GPIO_Pin_x, x can be 0...31
* @retval The new state of the GPIO pad interrupt(SET or RESET).
*/
ITStatus GPIO_getITStatus(GPIO_Type* GPIOx, uint32_t GPIO_Pin){
ITStatus bitStatus = RESET;
uint32_t itstatus=0x0;
itstatus = GPIOx->ISR & GPIO_Pin;
if(itstatus != (uint32_t)RESET){
bitStatus = SET;
}
else{
bitStatus = RESET;
}
return bitStatus;
}
void GPIO_clearITPendingBit(GPIO_Type* GPIOx, uint32_t GPIO_Pin){
/* clear the IT Bit */
GPIOx->ISR |= GPIO_Pin;
}
里面的函数都是经过作者测试没毛病的,放心用就好啦
还有就是,毕竟是自己凑合着写的,里面肯定有些小疏漏什么,但绝对不影响功能,放心用,出问题了欢迎找我