⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_gpio.c

📁 Kinetis_K60开源底层驱动开发包(20120328)
💻 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 + -