?? hal_gpio.c
字號:
/*
* 測試硬件平臺:LPLD_K60 Card
* 版權所有:北京拉普蘭德電子技術有限公司
* 網絡銷售:http://laplenden.taobao.com
* 公司門戶:http://www.lpld.cn
*
* 文件名: HAL_GPIO.c
* 用途: GPIO底層模塊相關函數
* 最后修改日期: 20120321
*
* 開發者使用協議:
* 本代碼面向所有使用者開放源代碼,開發者可以隨意修改源代碼。但本段及以上注釋應
* 予以保留,不得更改或刪除原版權所有者姓名。二次開發者可以加注二次版權所有者,
* 但應在遵守此協議的基礎上,開放源代碼、不得出售代碼本身。
*/
/*
*******需用到GPIO中斷,請在isr.h中粘貼一下代碼:*********
//GPIO模塊中斷服務定義
#undef VECTOR_103
#define VECTOR_103 LPLD_GPIO_Isr
#undef VECTOR_104
#define VECTOR_104 LPLD_GPIO_Isr
#undef VECTOR_105
#define VECTOR_105 LPLD_GPIO_Isr
#undef VECTOR_106
#define VECTOR_106 LPLD_GPIO_Isr
#undef VECTOR_107
#define VECTOR_107 LPLD_GPIO_Isr
//以下函數在LPLD_Kinetis底層包,不必修改
extern void LPLD_GPIO_Isr(void);
***********************代碼結束*************************
*/
#include "common.h"
#include "HAL_GPIO.h"
//用戶自定義中斷服務函數數組
GPIO_ISR_CALLBACK GPIO_ISR[5];
/*
* LPLD_GPIO_Init
* GPIO通用初始化函數
*
* 參數:
* port--端口基地址
* |__PORTA_BASE_PTR--Port A
* |__PORTB_BASE_PTR--Port B
* |__PORTC_BASE_PTR--Port C
* |__PORTD_BASE_PTR--Port D
* |__PORTE_BASE_PTR--Port E
* port_bit--端口位數
* |__0~31
* dir--端口數據方向
* |__1--輸出
* |__0--輸入
* data--輸出初始電平/輸入上拉或下拉
* |__2--如果dir=0,輸入內部下拉
* |__1--如果dir=0,輸入內部上拉; 如果dir=1,輸出高電平
* |__0--如果dir=0,輸入不使能上下拉; 如果dir=1,輸出低電平
* irqc--輸入中斷
* |__0--不使能中斷
* |__其他--見技術文檔 PORTx_PCRn寄存器 IRQC位描述
*
* 輸出:
* 0--配置錯誤
* 1--配置成功
*/
uint8_t LPLD_GPIO_Init(PORT_MemMapPtr port, uint8_t port_bit, uint8_t dir, uint8_t data, uint8_t irqc)
{
GPIO_MemMapPtr p;
//判斷端口位數合理性
if(port_bit>31)
return 0;
//選擇IO口時鐘控制掩碼
if(port == PORTA_BASE_PTR)
{
p = PTA_BASE_PTR;
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
}
else if(port == PORTB_BASE_PTR)
{
p = PTB_BASE_PTR;
SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;
}
else if(port == PORTC_BASE_PTR)
{
p = PTC_BASE_PTR;
SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;
}
else if(port == PORTD_BASE_PTR)
{
p = PTD_BASE_PTR;
SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;
}
else if(port == PORTE_BASE_PTR)
{
p = PTE_BASE_PTR;
SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;
}
else
{
return 0;
}
//配置為GPIO功能
PORT_PCR_REG(port, port_bit) = PORT_PCR_MUX(1);
//輸入或輸出設置
if(dir==1)
{
GPIO_PDDR_REG(p) |= 0x1u<<port_bit;
//設置初始輸出
if(data==1)
{
GPIO_PSOR_REG(p) = 0x1u<<port_bit;
}
else
{
GPIO_PCOR_REG(p) = 0x1u<<port_bit;
}
}
else
{
GPIO_PDDR_REG(p) &= ~(0x1u<<port_bit);
//配置中斷方式
if(irqc>0xC) return 0;
PORT_PCR_REG(port, port_bit) |= PORT_PCR_IRQC(irqc);
//配置內部上拉或下拉或不使能
if(data==1)
{
//上拉
PORT_PCR_REG(port, port_bit) |= PORT_PCR_PE_MASK | PORT_PCR_PS_MASK ;
}
else if(data==2)
{
//下拉
PORT_PCR_REG(port, port_bit) |= PORT_PCR_PE_MASK ;
}
else
{
//不使能上下拉
PORT_PCR_REG(port, port_bit) &= ~PORT_PCR_PE_MASK ;
}
}
return 1;
}
/*
* LPLD_GPIO_SetIsr
* 設置GPIO通道用戶定義的中斷服務函數
*
* 參數:
* port--端口基地址
* |__PORTA_BASE_PTR--Port A
* |__PORTB_BASE_PTR--Port B
* |__PORTC_BASE_PTR--Port C
* |__PORTD_BASE_PTR--Port D
* |__PORTE_BASE_PTR--Port E
* isr_func--用戶中斷程序入口地址
* |__用戶在工程文件下定義的中斷函數名,函數必須為:無返回值,無參數(eg. void isr(void);)
*
* 輸出:
* 0--配置錯誤
* 1--配置成功
*
*/
uint8_t LPLD_GPIO_SetIsr(PORT_MemMapPtr port, GPIO_ISR_CALLBACK isr_func)
{
//選擇IO口
if(port == PORTA_BASE_PTR)
{
GPIO_ISR[0] = isr_func;
return 1;
}
else if(port == PORTB_BASE_PTR)
{
GPIO_ISR[1] = isr_func;
return 1;
}
else if(port == PORTC_BASE_PTR)
{
GPIO_ISR[2] = isr_func;
return 1;
}
else if(port == PORTD_BASE_PTR)
{
GPIO_ISR[3] = isr_func;
return 1;
}
else if(port == PORTE_BASE_PTR)
{
GPIO_ISR[4] = isr_func;
return 1;
}
else
{
return 0;
}
}
/*
* LPLD_GPIO_Set
* 設置GPIO端口0~31位輸出
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
* data--輸出數據
* |__0x00000000~0xFFFFFFFF--低到高代表GPIO口的第0~31位數據
*
* 輸出:
*
*/
void LPLD_GPIO_Set(GPIO_MemMapPtr p, uint32_t data)
{
GPIO_PDOR_REG(p) = data;
}
/*
* LPLD_GPIO_Set_b
* 設置GPIO端口一位的輸出
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
* port_bit--位數
* |__0~31--GPIO口的第0~31位
* data--輸出數據
* |__0~1--位輸出高或低電平
*
* 輸出:
*
*/
void LPLD_GPIO_Set_b(GPIO_MemMapPtr p, uint8_t port_bit, uint8_t data)
{
if(data==0)
GPIO_PCOR_REG(p) = 0x1u<<port_bit;
else
GPIO_PSOR_REG(p) = 0x1u<<port_bit;
}
/*
* LPLD_GPIO_Toggle
* 設置GPIO端口0~31的電平翻轉
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
* data--翻轉數據
* |__0x00000000~0xFFFFFFFF--低到高代表GPIO口的第0~31位的翻轉,1為反轉,0為保持不變。
*
* 輸出:
*
*/
void LPLD_GPIO_Toggle(GPIO_MemMapPtr p, uint32_t data)
{
GPIO_PTOR_REG(p) = data;
}
/*
* LPLD_GPIO_Toggle_b
* 設置GPIO端口一位的翻轉
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
* port_bit--位數
* |__0~31--設置GPIO口的一位翻轉
*
* 輸出:
*
*/
void LPLD_GPIO_Toggle_b(GPIO_MemMapPtr p, uint8_t port_bit)
{
GPIO_PTOR_REG(p) = 0x1u<<port_bit;
}
/*
* LPLD_GPIO_Get
* 取得GPIO口的數據
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
*
* 輸出:
* 指定GPIO口的32位輸入
*
*/
uint32_t LPLD_GPIO_Get(GPIO_MemMapPtr p)
{
return GPIO_PDIR_REG(p);
}
/*
* LPLD_GPIO_Get_b
* 取得GPIO口某一位的數據
*
* 參數:
* p--GPIO口基地址
* |__PTA_BASE_PTR--Port A
* |__PTB_BASE_PTR--Port B
* |__PTC_BASE_PTR--Port C
* |__PTD_BASE_PTR--Port D
* |__PTE_BASE_PTR--Port E
* port_bit--位數
* |__0~31--GPIO口的第0~31位
*
* 輸出:
* 指定GPIO口的指定位數的電平
*
*/
uint8_t LPLD_GPIO_Get_b(GPIO_MemMapPtr p, uint8_t port_bit)
{
return (GPIO_PDIR_REG(p)>>port_bit)&0x1u;
}
/*
* LPLD_GPIO_Isr
* GPIO通用中斷底層入口函數
*
* 用戶無需修改,程序自動進入對應通道中斷函數
*/
void LPLD_GPIO_Isr(void)
{
#define GPIO_VECTORNUM (*(volatile uint8_t*)(0xE000ED04))
uint8_t gpio_port = GPIO_VECTORNUM - 103;
//調用用戶自定義中斷服務
GPIO_ISR[gpio_port]();
//清除中斷標志位
PORT_ISFR_REG((PORT_MemMapPtr)((0x40049+gpio_port)<<12))=0xFFFFFFFF;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -