一、头文件:

#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 状态,即读取管脚输入电平
}

 

 

 

 

三、小结:

    主要是学会怎么调用,出现问题的话,检查寄存器的配置(不过一般不需要)。

智能车学习(十四)——K60单片机GPIO学习的更多相关文章

  1. 深度学习课程笔记(十四)深度强化学习 --- Proximal Policy Optimization (PPO)

    深度学习课程笔记(十四)深度强化学习 ---  Proximal Policy Optimization (PPO) 2018-07-17 16:54:51  Reference: https://b ...

  2. scrapy爬虫学习系列四:portia的学习入门

    系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备:      http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...

  3. 智能车学习(十五)——K60野火2013版例程

    一.中断函数注册方法: 1.格式: 配置某个功能的中断 注册中断函数 开启中断 2.一个例子 pit_init_ms(PIT0,);//定时中断初始化 set_vector_handler(PIT0_ ...

  4. 《SLAM十四讲》个人学习知识点梳理

    0.引言 从六月末到八月初大概一个月时间一直在啃SLAM十四讲[1]这本书,这本书把SLAM中涉及的基本知识点都涵盖了,所以在这里做一个复习,对这本书自己学到的东西做一个梳理. 书本地址:http:/ ...

  5. 强化学习(十四) Actor-Critic

    在强化学习(十三) 策略梯度(Policy Gradient)中,我们讲到了基于策略(Policy Based)的强化学习方法的基本思路,并讨论了蒙特卡罗策略梯度reinforce算法.但是由于该算法 ...

  6. Scala学习十四——模式匹配和样例类

    一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...

  7. 强化学习(十九) AlphaGo Zero强化学习原理

    在强化学习(十八) 基于模拟的搜索与蒙特卡罗树搜索(MCTS)中,我们讨论了MCTS的原理和在棋类中的基本应用.这里我们在前一节MCTS的基础上,讨论下DeepMind的AlphaGo Zero强化学 ...

  8. JMeter学习(十四)JMeter函数学习(转载)

    转载自 http://www.cnblogs.com/yangxia-test JMeter函数是一些能够转化在测试树中取样器或者其他配置元件的域的特殊值.一个函数的调用就像这样:${_functio ...

  9. android学习十四(android的接收短信)

    收发短信是每一个手机主要的操作,android手机当然也能够接收短信了. android系统提供了一系列的API,使得我们能够在自己的应用程序里接收和发送短信. 事实上接收短信主要是利用我们前面学过的 ...

随机推荐

  1. delphi XE5下安卓开发技巧

    delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...

  2. MySQL key_len 大小的计算

    背景: 当用Explain查看SQL的执行计划时,里面有列显示了 key_len 的值,根据这个值可以判断索引的长度,在组合索引里面可以更清楚的了解到了哪部分字段使用到了索引. 环境: CREATE ...

  3. Effective C++ -----条款37:绝不重新定义继承而来的缺省参数值

    绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数-----你唯一应该覆写的东西-----却是动态绑定.

  4. 后台子线程(非主线程)更新UI引起的警告

    一.问题描述 -(void)sendAsynchronousRequest { NSLog(@"%@",[NSThread currentThread]); [SVProgress ...

  5. MySQL 获得当前日期时间\时间戳 函数 ( 转自传智播客)

    MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now(); +-------+ | now() | +-- ...

  6. Android异步加载访问网络图片-解析json

    来自:http://www.imooc.com/video/7871 推荐大家去学习这个视频,讲解的很不错. 慕课网提供了一个json网址可以用来学习:http://www.imooc.com/api ...

  7. 【python】dict4ini和xmltodict模块用途

    dict4ini模块:可以读写配置文件 xmltodict模块:将xml和json互相转换  https://pypi.python.org/pypi/xmltodict

  8. 【网络】ssl与ssh

    ssh(安全外壳协议):百度百科 ssl(安全套接字):http://kb.cnblogs.com/page/162080/ https应用了ssl协议 ssh与ssl的区别:http://blog. ...

  9. ios手势

    iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小   1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...

  10. 搞笑世界杯(codevs 1060)

    题目描述 Description 随着世界杯小组赛的结束,法国,阿根廷等世界强队都纷纷被淘汰,让人心痛不已. 于是有 人组织了一场搞笑世界杯,将这些被淘汰的强队重新组织起来和世界杯一同比赛.你和你的朋 ...