一、頭文件:
#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 狀態,即讀取管腳輸入電平 }
三、小結:
主要是學會怎么調用,出現問題的話,檢查寄存器的配置(不過一般不需要)。