智能車學習(十四)——K60單片機GPIO學習


一、頭文件:

#ifndef __MK60_GPIO_H__
#define __MK60_GPIO_H__

#include "MK60_gpio_cfg.h"

/*
 * 定義管腳方向
 */
typedef enum GPIO_CFG
{
    //這里的值不能改!!!
    GPI         = 0,                                //定義管腳輸入方向      GPIOx_PDDRn里,0表示輸入,1表示輸出
    GPO         = 1,                                //定義管腳輸出方向
} GPIO_CFG;

#define HIGH  1u
#define LOW   0u

extern  GPIO_MemMapPtr      GPIOX[PTX_MAX];
#define GPIOX_BASE(PTxn)     GPIOX[PTX(PTxn)]       //GPIO模塊的地址



/****************************外部使用****************************/

extern void    gpio_init  (PTXn_e, GPIO_CFG, uint8 data);    //初始化gpio
extern void    gpio_ddr   (PTXn_e, GPIO_CFG);                //設置引腳數據方向
extern void    gpio_set   (PTXn_e,           uint8 data);    //設置引腳狀態
extern void    gpio_turn  (PTXn_e);                          //反轉引腳狀態
extern uint8   gpio_get   (PTXn_e);                          //讀取引腳狀態



//如下 4個 函數 的 PTxn 只能是 宏定義,不能是 變量
#define GPIO_SET(PTxn,data)       (PTXn_T(PTxn,OUT)= (data))    //設置輸出電平
#define GPIO_TURN(PTxn)           (PTXn_T(PTxn,T)= 1)           //翻轉輸出電平
#define GPIO_GET(PTxn)            (PTXn_T(PTxn,IN))             //讀取引腳輸入狀態
#define GPIO_DDR(PTxn,ddr)        (PTXn_T(PTxn,DDR) = ddr)      //輸入輸出狀態


//如下  函數 的 PTxn 可以是  宏定義,也可以是 變量

//n位操作
#define GPIO_SET_NBIT(NBIT,PTxn,data)   GPIO_PDOR_REG(GPIOX_BASE(PTxn)) =   (                                                   \
                                                                                (                                               \
                                                                                    GPIO_PDOR_REG(GPIOX_BASE(PTxn))             \
                                                                                    &                                           \
                                                                                    ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    \
                                                                                )                                               \
                                                                                |   ((data)                                     \
                                                                                    &(                                          \
                                                                                        ((1<<NBIT)-1)                           \
                                                                                            <<PTn(PTxn)                         \
                                                                                     ))                                         \
                                                                            )


#define GPIO_DDR_NBIT(NBIT,PTxn,ddr)   GPIO_PDDR_REG(GPIOX_BASE(PTxn))  =   (                                                   \
                                                                                (                                               \
                                                                                    GPIO_PDDR_REG(GPIOX_BASE(PTxn))             \
                                                                                    &                                           \
                                                                                    ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    \
                                                                                )                                               \
                                                                                |   ((ddr)                                      \
                                                                                    &(                                          \
                                                                                        ((1<<NBIT)-1)                           \
                                                                                        <<PTn(PTxn)                             \
                                                                                    ))                                          \
                                                                            )

#define GPIO_T_NBIT(NBIT,PTxn,data)   GPIO_PTOR_REG(GPIOX_BASE(PTxn))  =   (                                                    \
                                                                                (                                               \
                                                                                    GPIO_PTOR_REG(GPIOX_BASE(PTxn))             \
                                                                                    &                                           \
                                                                                    ((uint32)( ~(((1<<NBIT)-1)<<PTn(PTxn))))    \
                                                                                )                                               \
                                                                                |   ((data)                                     \
                                                                                    &(                                          \
                                                                                        ((1<<NBIT)-1)                           \
                                                                                        <<PTn(PTxn)                             \
                                                                                    ))                                          \
                                                                            )


#define GPIO_GET_NBIT(NBIT,PTxn)    (( GPIO_PDIR_REG(GPIOX_BASE(PTxn))>>PTn(PTxn) ) & ((1<<NBIT)-1))


#endif      //__MK60_GPIO_H__

二、源文件:

/*
 * 包含頭文件
 */
#include "common.h"
#include "MK60_port.h"
#include "MK60_gpio.h"

/*
 * 定義數組
 */
GPIO_MemMapPtr GPIOX[PTX_MAX] = {PTA_BASE_PTR, PTB_BASE_PTR, PTC_BASE_PTR, PTD_BASE_PTR, PTE_BASE_PTR}; //定義五個指針數組保存 GPIOX 的地址

/*!
 *  @brief      初始化gpio
 *  @param      PTxn    端口
 *  @param      cfg     引腳方向,0=輸入,1=輸出
 *  @param      data    輸出初始狀態,0=低電平,1=高電平 (對輸入無效)
 *  @since      v5.0
 *  Sample usage:       gpio_init (PTA8, GPI,0);    //初始化 PTA8 管腳為輸入
 */
void gpio_init (PTXn_e ptxn, GPIO_CFG cfg, uint8 data)
{
    //復用管腳為GPIO功能
    port_init( ptxn, ALT1);

    //端口方向控制輸入還是輸出
    if(  cfg == GPI )
    {
        //設置端口方向為輸入
        GPIO_PDDR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));       // GPIO PDDR 管腳號 清0,即對應管腳配置為端口方向輸入
    }
    else
    {
        //設置端口方向為輸出
        GPIO_PDDR_REG(GPIOX_BASE(ptxn)) |= (1 << PTn(ptxn));        // GPIO PDDR 管腳號 置1,即對應管腳配置為端口方向輸出

        //端口輸出數據
        if(data == 0)
        {
            GPIO_PDOR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));   // GPIO PDOR 管腳號 清0,即對應管腳配置為端口輸出低電平
        }
        else
        {
            GPIO_PDOR_REG(GPIOX_BASE(ptxn))  |= (1 << PTn(ptxn));   // GPIO PDOR 管腳號 置1,即對應管腳配置為端口輸出高電平
        }
    }
}

/*!
 *  @brief      設置引腳數據方向
 *  @param      PTxn    端口
 *  @param      cfg     引腳方向,0=輸入,1=輸出
 *  @since      v5.0
 *  Sample usage:       gpio_ddr (PTA8, GPI);    //設置 PTA8 管腳為輸入
 */
void  gpio_ddr   (PTXn_e ptxn, GPIO_CFG cfg)
{
    //端口方向控制輸入還是輸出
    if(  cfg == GPI )
    {
        //設置端口方向為輸入
        GPIO_PDDR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));           // GPIO PDDR 管腳號 清0,即對應管腳配置為端口方向輸入
    }
    else
    {
        //設置端口方向為輸出
        GPIO_PDDR_REG(GPIOX_BASE(ptxn)) |= (1 << PTn(ptxn));            // GPIO PDDR 管腳號 置1,即對應管腳配置為端口方向輸出
    }
}

/*!
 *  @brief      設置引腳狀態
 *  @param      PTxn    端口
 *  @param      data    輸出初始狀態,0=低電平,1=高電平 (對輸入無效)
 *  @since      v5.0
 *  @warning    務必保證數據方向為輸出(DEBUG模式下,有斷言進行檢測)
 *  Sample usage:       gpio_set (PTA8, 1);    // PTA8 管腳 輸出 1
 */
void gpio_set (PTXn_e ptxn, uint8 data)
{
    ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPO ); // 斷言,檢測 輸出方向是否為輸出
                                                                            // 獲取 GPIO PDDR 管腳號 ,比較是否為輸出

    //端口輸出數據
    if(data == 0)
    {
        GPIO_PDOR_REG(GPIOX_BASE(ptxn)) &= ~(1 << PTn(ptxn));   // GPIO PDOR 管腳號 清0,即對應管腳配置為端口輸出低電平
    }
    else
    {
        GPIO_PDOR_REG(GPIOX_BASE(ptxn))  |= (1 << PTn(ptxn));   // GPIO PDOR 管腳號 置1,即對應管腳配置為端口輸出高電平
    }
}


/*!
 *  @brief      反轉引腳狀態
 *  @param      PTxn    端口
 *  @since      v5.0
 *  @warning    務必保證數據方向為輸出(DEBUG模式下,有斷言進行檢測)
 *  Sample usage:       gpio_turn (PTA8);    // PTA8 管腳 輸出 反轉
 */
void gpio_turn (PTXn_e ptxn)
{
    ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPO ); // 斷言,檢測 輸出方向是否為輸出
                                                                            // 獲取 GPIO PDDR 管腳號 ,比較是否為輸出

    GPIO_PTOR_REG( GPIOX_BASE(ptxn))  =  1 << (PTn(ptxn ));                 // GPIO PTOR ptxn 置1,其他清0 ,即對應管腳配置為端口輸出反轉,其他位不變
                                                                            // 此處不能用 BIT_SET 這個宏來置1 ,因為必須保證其他位 不變,其他位直接清0即可
}

/*!
 *  @brief      讀取引腳輸入狀態
 *  @param      PTxn    端口
 *  @return     管腳的狀態,1為高電平,0為低電平
 *  @since      v5.0
 *  @warning    務必保證數據方向為輸入(DEBUG模式下,有斷言進行檢測)
 *  Sample usage:       uint8 pta8_data = gpio_get (PTA8);    // 獲取 PTA8 管腳 輸入電平
 */
uint8 gpio_get(PTXn_e ptxn)
{
    ASSERT( BIT_GET( GPIO_PDDR_REG(GPIOX_BASE(ptxn)) , PTn(ptxn)) == GPI ); // 斷言,檢測 輸出方向是否為輸入
                                                                            // 獲取 GPIO PDDR 管腳號 ,比較是否為輸入

    return ((GPIO_PDIR_REG(GPIOX_BASE(ptxn)) >> PTn(ptxn )) & 0x01);        // 獲取 GPIO PDIR ptxn 狀態,即讀取管腳輸入電平
}

 

 

 

 

三、小結:

    主要是學會怎么調用,出現問題的話,檢查寄存器的配置(不過一般不需要)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM