i.MX6ULL:给你STM32的开发体验(i.MX6ULL的GPIO驱动的STM32方式的实现

简介:

       最近在学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;
}

 

里面的函数都是经过作者测试没毛病的,放心用就好啦

还有就是,毕竟是自己凑合着写的,里面肯定有些小疏漏什么,但绝对不影响功能,放心用,出问题了欢迎找我

你可能感兴趣的:(嵌入式linux,linux,嵌入式)