历史上的今天
返回首页

历史上的今天

今天是:2025年04月06日(星期日)

2021年04月06日 | 恩智浦 飞思卡尔Freescale Kinetis KEA128学习笔记3--GPIO模块(一)

2021-04-06 来源:eefocus

KEA128芯片有7组IO,PORTA--H每组8个引脚,PORTI有7个引脚,共计71个。


单个引脚驱动能力是2.5mA,内部均可上拉到VDD,无内部下拉。应通过编程将未使用引脚内部上拉。


MCU处在运行、等待、调试模式下,GPIO正常工作,停止模式下,GPIO停止工作。


下面是端口控制寄存器介绍,主要是端口滤波寄存器,上拉使能寄存器和高驱动能力使能寄存器

GPIO有三组寄存器,分别为GPIOA、GPIOB、GPIOC。每组有7个寄存器,分别为输出寄存器(PDOR)、输出置1寄存器(PSOR)、输出清0寄存器(PCOR)、输出取反寄存器(PTOR)、输入寄存器(PDIR)、数据放向寄存器(PDDR)、输入禁止寄存器(PIDR)。


GPIO编程步骤:


1.设定GPIO是输入还是输出,设置数据方向寄存器


2.若是输出则设定GPIO的值,低0高1


3.若是输入则通过输入寄存器获得引脚的状态。低0高1.


//===========================================================================

//文件名称:common.h

//功能概要:公共要素头文件

//版权所有:苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)

//版本更新:2015-06-05  V2.0

//芯片类型:KEA128

//===========================================================================

 

#ifndef __COMMON_H       //防止重复定义(_COMMON_H  开头)

#define __COMMON_H

 

// 1.芯片寄存器映射文件及处理器内核属性文件

#include "core_cmFunc.h"

#include "core_cmInstr.h"

#include "core_cm0plus.h"

#include "SKEAZ1284.h"           // 包含芯片头文件

#include "system_SKEAZ1284.h"    // 包含芯片系统初始化文件

 

#define  SYSTEM_CLK_KHZ   DEFAULT_SYSTEM_CLOCK/1000// 芯片系统时钟频率(KHz)

#define  CORE_CLK_KHZ     SYSTEM_CLK_KHZ           // 芯片内核时钟频率(KHz)

#define  BUS_CLK_KHZ      SYSTEM_CLK_KHZ/2         // 芯片总线时钟频率(KHz)

 

// 2.定义开关总中断

#define ENABLE_INTERRUPTS   __enable_irq   // 开总中断

#define DISABLE_INTERRUPTS  __disable_irq  // 关总中断

 

// 3.位操作宏函数(置位、清位、获得寄存器一位的状态)

#define BSET(bit,Register)  ((Register)|= (1<<(bit)))    // 置寄存器的一位

#define BCLR(bit,Register)  ((Register) &= ~(1<<(bit)))  // 清寄存器的一位

#define BGET(bit,Register)  (((Register) >> (bit)) & 1)  // 获得寄存器一位的状态

 

// 4.重定义基本数据类型(类型别名宏定义)

typedef unsigned char uint_8;   // 无符号8位数,字节

typedef unsigned short int uint_16;  // 无符号16位数,字

typedef unsigned long int uint_32;  // 无符号32位数,长字

typedef char int_8;    // 有符号8位数

typedef short int int_16;   // 有符号16位数

typedef int int_32;   // 有符号32位数

// 不优化类型

typedef volatile uint_8 vuint_8;  // 不优化无符号8位数,字节

typedef volatile uint_16 vuint_16; // 不优化无符号16位数,字

typedef volatile uint_32 vuint_32; // 不优化无符号32位数,长字

typedef volatile int_8 vint_8;   // 不优化有符号8位数

typedef volatile int_16 vint_16;  // 不优化有符号16位数

typedef volatile int_32 vint_32;  // 不优化有符号32位数

 

#endif       //防止重复定义(_COMMON_H结尾)

//===========================================================================

//文件名称:gpio.h

//功能概要:GPIO底层驱动构件头文件

//版权所有:苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)

//版本更新:2015-06-05  V2.0

//芯片类型:KEA128

//===========================================================================

 

#ifndef GPIO_H        //防止重复定义(GPIO_H  开头)

#define GPIO_H

 

#include "common.h"   //包含公共要素头文件

 

// 端口号地址偏移量宏定义

#define PORTA    (0<<8)

#define PORTB    (1<<8)

#define PORTC    (2<<8)

#define PORTD    (3<<8)

#define PORTE    (4<<8)

#define PORTF    (5<<8)

#define PORTG    (6<<8)

#define PORTH    (7<<8)

#define PORTI    (8<<8)

//引脚方向宏定义

#define GPIO_IN      0

#define GPIO_OUTPUT  1

 

//===========================================================================

//函数名称:gpio_init

//函数返回:无

//参数说明:port_pin:(端口号)|(引脚号)(例:PORTB|(5) 表示为B口5号脚)

//       dir:引脚方向(0=输入,1=输出,可用引脚方向宏定义)

//       state:端口引脚初始状态(0=低电平,1=高电平)

//功能概要:初始化指定端口引脚作为GPIO引脚功能,并定义为输入或输出,若是输出,

//       还指定初始状态是低电平或高电平

//===========================================================================

void gpio_init(uint_16 port_pin, uint_8 dir, uint_8 state);

 

//===========================================================================

//函数名称:gpio_set

//函数返回:无

//参数说明:port_pin:(端口号)|(引脚号)(例:PORTB|(5) 表示为B口5号脚)

//       state:希望设置的端口引脚状态(0=低电平,1=高电平)

//功能概要:当指定端口引脚被定义为GPIO功能且为输出时,本函数设定引脚状态

//===========================================================================

void gpio_set(uint_16 port_pin, uint_8 state);

 

//===========================================================================

//函数名称:gpio_get

//函数返回:指定端口引脚的状态(1或0)

//参数说明:port_pin:(端口号)|(引脚号)(例:PORTB|(5) 表示为B口5号脚)

//功能概要:当指定端口引脚被定义为GPIO功能且为输入时,本函数获取指定引脚状态

//===========================================================================

uint_8 gpio_get(uint_16 port_pin);

 

//===========================================================================

//函数名称:gpio_reverse

//函数返回:无

//参数说明:port_pin:(端口号)|(引脚号)(例:PORTB|(5) 表示为B口5号脚)

//功能概要:当指定端口引脚被定义为GPIO功能且为输出时,本函数反转引脚状态

//===========================================================================

void gpio_reverse(uint_16 port_pin);

 

//===========================================================================

//函数名称:gpio_pull

//函数返回:无

//参数说明:port_pin:端口号|引脚号(例:PORTB|(5) 表示为B口5号脚)

//          pullselect:引脚上拉使能选择( 0=上拉除能,1=上拉使能)

//功能概要:使指定引脚上拉高电平

//===========================================================================

void gpio_pull(uint_16 port_pin, uint_8 pullselect);

 

#endif     //防止重复定义(GPIO_H  结尾)

//===========================================================================

//声明:

//(1)我们开发的源代码,在本中心提供的硬件系统测试通过,真诚奉献给社会,不足之处,欢迎指正。

//(2)对于使用非本中心硬件系统的用户,移植代码时,请仔细根据自己的硬件匹配。

//

//苏州大学飞思卡尔嵌入式中心

//技术咨询:0512-65214835  http://sumcu.suda.edu.cn

//===========================================================================

//文件名称:gpio.c

//功能概要:GPIO底层驱动构件源文件

//版权所有:苏州大学飞思卡尔嵌入式中心(sumcu.suda.edu.cn)

//版本更新:2015-06-05  V2.0

//芯片类型:KEA128

//===========================================================================

#include "gpio.h"   //包含本构件头文件

 

uint_32 bit;    //内部变量,用于记录引脚在端口寄存器中的偏移量

//内部函数声明

//解析端口号和引脚

static void gpio_port_pin_num(uint_16 port_pin,uint_8* port,uint_8* pin);

//解析基地址和引脚在寄存器中的偏移量

static void gpio_ptr_bit(uint_16 port_pin,GPIO_MemMapPtr* gpio_ptr,uint_32* bit);

//===========================================================================

//函数名称:gpio_init

//函数返回:无

//参数说明:port_pin:(端口号)|(引脚号)(例:PORTB|(5) 表示为B口5号脚)

//       dir:引脚方向(0=输入,1=输出,可用引脚方向宏定义)

//       state:端口引脚初始状态(0=低电平,1=高电平)

//功能概要:初始化指定端口引脚作为GPIO引脚功能,并定义为输入或输出,若是输出,

//       还指定初始状态是低电平或高电平

//===========================================================================

void gpio_init(uint_16 port_pin, uint_8 dir, uint_8 state)

{

//局部变量声明

GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针

gpio_ptr_bit(port_pin,&gpio_ptr,&bit);//计算基地址和和引脚在寄存器中的偏移量

//根据带入参数dir,决定引脚为输出还是输入

if (1 == dir)   //希望为输出

{

//端口数据方向寄存器定义为输出

BSET(bit, GPIO_PDDR_REG(gpio_ptr));//1为通用输出,0零表示作为输入

//输出清零寄存器

BSET(bit, GPIO_PCOR_REG(gpio_ptr));//该寄存器置1,引脚输出被置位为0

//初始状态为低电平

gpio_set(port_pin, state);   //调用gpio_set函数,设定引脚初始状态

else 

{

//希望为输入

BCLR(bit, GPIO_PDDR_REG(gpio_ptr));

}

}

 

//===========================================================================

//函数名称:gpio_set

//函数返回:无

//参数说明:port_pin:端口号|引脚号(例:PORTB|(5) 表示为B口5号脚)

//       state:引脚初始状态(0=低电平,1=高电平)

//功能概要:设定引脚状态为低电平或高电平

//===========================================================================

void gpio_set(uint_16 port_pin, uint_8 state)

{

//局部变量声明

GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针

gpio_ptr_bit(port_pin,&gpio_ptr,&bit);//计算基地址和和引脚在寄存器中的偏移量

//根据带入参数state,决定引脚为输出1还是0

if (1==state) 

{

BSET(bit,gpio_ptr->PDOR);//对应位置为1

} else {

BCLR(bit,gpio_ptr->PDOR);//对应位置为0

}

}

 

//===========================================================================

//函数名称:gpio_get

//函数返回:指定引脚的状态(1或0)

//参数说明:port_pin:端口号|引脚号(例:PORTB|(5) 表示为B口5号脚)

//功能概要:获取指定引脚的状态(1或0)

//===========================================================================

uint_8 gpio_get(uint_16 port_pin)

{

//局部变量声明

GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针

gpio_ptr_bit(port_pin,&gpio_ptr,&bit);//计算基地址和和引脚在寄存器中的偏移量

//返回引脚的状态

return ((BGET(bit,gpio_ptr->PDIR))>=1 ? 1:0);

}

 

//===========================================================================

//函数名称:gpio_reverse

//函数返回:无

//参数说明:port_pin:端口号|引脚号(例:PORTB|(5) 表示为B口5号脚)

//功能概要:反转指定引脚输出状态。

//===========================================================================

void gpio_reverse(uint_16 port_pin)

{

//局部变量声明

GPIO_MemMapPtr gpio_ptr;    //声明port_ptr为GPIO结构体类型指针

gpio_ptr_bit(port_pin,&gpio_ptr,&bit);//计算基地址和和引脚在寄存器中的偏移量

//反转指定引脚输出状态

BSET(bit,gpio_ptr->PTOR);

}

 

//===========================================================================

//函数名称:gpio_pull

//函数返回:无

//参数说明:port_pin:端口号|引脚号(例:PORTB|(5) 表示为B口5号脚)

//       pullselect:引脚上拉使能选择( 0=上拉除能,1=上拉使能)

//功能概要:使指定引脚上拉高电平

//===========================================================================

void gpio_pull(uint_16 port_pin, uint_8 pullselect)

{

//局部变量声明

uint_8 port;                //端口号

uint_8 pin;                 //引脚号

gpio_port_pin_num(port_pin, &port, &pin);   //解析出端口号及引脚号

//计算引脚在寄存器中的偏移量

if (port < 4)               //端口号为PORTA~PORTD

{

//引脚所在的位数

bit = 8 * port + pin;

if (1==pullselect){BSET(bit,PORT_PUE0);}//端口上拉使能低位寄存器0上拉使能

else {BCLR(bit,PORT_PUE0);}//上拉除能(不使能)

}

else if(3 {

//引脚所在的位数

bit = 8 * (port - 4) + pin;

if (1==pullselect){BSET(bit,PORT_PUE1);}//端口上拉使能低位寄存器1上拉使能

else {BCLR(bit,PORT_PUE1);}

}

else                       //端口号为PORTI

{

//引脚所在的位数

bit = 8 * (port - 8) + pin;

if (1==pullselect){BSET(bit,PORT_PUE2);}//端口上拉使能低位寄存器2上拉使能

else {BCLR(bit,PORT_PUE2);}

}

}

 

//----------------------以下为内部函数存放处----------------------------------------

推荐阅读

史海拾趣

3D PLUS公司的发展小趣事

面对日新月异的电子行业,3D PLUS公司始终保持创新精神,不断推动3D技术的升级。公司研发团队成功研发出全方位彩色人体扫描仪,这一设备能够在极短的时间内实现360度人像扫描,且清晰度极高,为互联网人体应用提供了强有力的支持。此外,公司还不断在软件、算法等方面进行优化,提升3D技术的精度和效率,满足市场的不断需求。

GuangDong Province MengCo Semiconductor Co., Ltd公司的发展小趣事
选用质量可靠、性能稳定的元器件是确保电路可靠性的基础。
ACP Optoelectronic Technology Co Ltd公司的发展小趣事

在国内市场取得一定成绩后,ACP Optoelectronic Technology Co Ltd开始积极拓展国际市场。公司积极参加国际电子展会和技术交流活动,与海外企业建立合作关系,拓展销售渠道。经过几年的努力,ACP Optoelectronic Technology Co Ltd的产品已经成功打入多个国际市场,公司也逐渐发展成为一家具有国际影响力的光电企业。

CETC公司的发展小趣事

随着电子行业的快速发展,CETC意识到单打独斗难以应对市场的快速变化。于是,公司积极寻求与其他企业的合作,共同推动产业的发展。在与某知名通信设备制造商的合作中,CETC提供了先进的电子元件和解决方案,双方共同开发出了多款畅销产品,实现了市场的共赢。这种合作模式不仅提升了CETC的市场竞争力,也促进了整个电子行业的健康发展。

ETC2公司的发展小趣事

随着环保意识的日益增强,ETC2公司也积极响应国家环保政策,致力于推动ETC技术的绿色环保应用。他们研发了低能耗、低排放的ETC设备,并推广使用电子发票等环保支付方式。这些举措不仅减少了能源消耗和环境污染,也为ETC2公司树立了绿色环保的企业形象。

ApexTool Group公司的发展小趣事

随着全球电子市场的不断扩大,Apex Tool Group积极实施全球化战略,拓展市场版图。公司在全球范围内建立了多个生产基地和分销网络,以便更好地服务全球客户。同时,Apex Tool Group还积极与全球知名的电子企业开展合作,共同推动电动工具技术的创新和发展。这些举措使得Apex Tool Group在全球电子行业中的地位日益稳固。

问答坊 | AI 解惑

某一个放大电路在输入端加入的信号电压值不变

某一个放大电路在输入端加入的信号电压值不变…

查看全部问答>

能推荐个好的gps模块吗

最近要用gps模块做同步授时,哪位用过给推荐下。天线越小越好…

查看全部问答>

PCI封装 规范

各位高手好。 最近在做PCI卡,小弟请教一下您PCI卡的尺寸/规范,以及电路封装。 谢谢您的帮助。 我的邮箱:wangwei4611@163.com …

查看全部问答>

linux c嵌入汇编编译报错

__asm__(\"ldw 0(%0), %%r0\" : : \"r\" (addr)); 就这段代码,是从内核中拿来用的。 20   21#define ARCH_HAS_PREFETCH   22static inline void prefetch(const void *addr)   23{   24  &nbs ...…

查看全部问答>

如何检测西门子gprs模块收到数据?

用西门子的gprs手机模块实现tcp连接时,用什么方式知道已经收到数据,可以读出来了? 谢谢…

查看全部问答>

s7-200 如何实现正弦曲线的输出

PLC  西门子 S7-200 PLC经过PID调节,输出变频器的频率控制容器压力。 现在想在升压的过程中,让压力值按照正弦曲线上升,如何编程?请给个思路。…

查看全部问答>

USB加密狗用的单片机CPU

请问大家,一般USB加密狗中用的CPU是什么型号,最便宜最可靠的是哪个型号。谢谢…

查看全部问答>

directshow问题

各位大侠帮忙看看这个问题 http://topic.eeworld.net/u/20090210/18/09cb0f9d-cf2c-49c9-a84e-29d981e9a4e9.html …

查看全部问答>

[新手问题]philips的LPC系列ARM启动代码相关问题

在初始化堆栈的时候 ... InitStack:               # MOV     R1, LR                 LDR   &nb ...…

查看全部问答>

msp430下载问题

手里有块利尔达的msp430F2274板子,板子上有个并行接口,也提供了并口线。应该可以通过电脑从并口下载程序,但是在debug这步出现了问题,提示:初始化失败,让检查硬件是否连接,检查驱动是否安装,还有重启电脑什么的。我都试过了,硬件连接肯定 ...…

查看全部问答>