OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5409|回复: 3

<新手向>第二期 裸机开发 P25 第13.3讲 通用GPIO驱动 随堂笔记

[复制链接]

5

主题

17

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-3-22
在线时间
35 小时
发表于 2020-3-25 00:09:05 | 显示全部楼层 |阅读模式
/********************************************/
时间        :2020/03/24/
作者        :YOKI
导师        :正点原子 左忠凯
硬件        :正点原子 ALPHA I.MX LINUX 开发板
/*******************************************/
本例程通过编写 led、蜂鸣器 按键 练习 GPIO 口的 通用设置
预期功能:通过一个简单的函数实现对任意一个GPIO引脚的读写
GPIOx->GDIR &= ~(1<<0);      //GDIR 置 0 输入模式
GPIOx->GDIR |=  (1<<0);      //GDIR 置 1 输出模式
((GPIOx->DR) >> pin) & 0x01; //读引脚电平
(GPIOx->DR) &= ~(1<<pin);break;   //给引脚写 0 低电平
(GPIOx->DR) |=  (1<<pin);break;   //给引脚写 1 高电平
以上就是这些函数实现的基础
/***************** GPIO口初始化函数 ************************/
/* 参数1:GPIOx      GPIO口名称  如:GPIO1、GPIO5           
/* 参数2:pin        引脚号      如: 18 、1               
/* 参数3:direction  输入输出    如: INPUT output        
/* 例如:设置GPIO5_IO01为输出模式:                        
/* GPIOx_init(GPIO5,1,output);                        
/*********************************************************/
void GPIOx_init (GPIO_Type *GPIOx,  uint8_t pin, uint8_t direction)
{
    if (direction == INPUT||direction == input ){
        GPIOx->GDIR &= ~(1<<pin);  //置0 输入模式
        }
        
    if (direction == OUTPUT||direction == output){
        GPIOx->GDIR |= (1<<pin);   //置1 输出模式
        }
}
这是我自己编写的初始化函数,和视频中基本一样,只有函数的最后一个参数稍有不同,我没使用枚举类型的结构体,
而是在 bsp_gpio.h 头文件 中用宏定义 定义代替了:
#define  INPUT      0
#define  input        0
#define  OUTPUT   1
#define  output      1
这样更直观一点,当然我还是很赞同视频中的写法,不过大家不必完全照抄 左萌主 的代码,重点是有自己的收获就好,
有自己的想法就去试验以下,哪怕错了也没关系。

/***************** GPIOx引脚写数据**************************/
/* 参数1:GPIOx      GPIO口名称  如:GPIO1、GPIO5           
/* 参数2:pin        引脚号      如: 18 、1               
/* 例如:写GPIO1_IO18 高电平:                             
/* GPIOx_pin_write(GPIO1,18,1);                        
*********************************************************/
void GPIOx_pin_write(GPIO_Type *GPIOx,  uint8_t pin,int value)
{   
  //  GPIOx->GDIR |= (1<<pin);   //置1 输出模式
    switch (value)
        {
        case 0GPIOx->DR) &= ~(1<<pin);break;   // 写 0 低电平
        case 1GPIOx->DR) |=  (1<<pin);break;   // 写 1 高电平
            
        defaultGPIOx->DR) &= ~(1<<pin);break;  // 默认 写0 低电平
        }
}
这个函数只是写数据没用 if 语句换成了 switch 语句 本质上没啥区别,
只是自己觉得这里用 条件分支 switch 更合适更美观。
然后被注释掉的那一条语句留着以后用(想把 void GPIOx_init()函数精简掉)
//  GPIOx->GDIR |= (1<<pin);   //置1 输出模式
/***************** GPIOx引脚读取函数 ***********************/
/* 参数1:GPIOx      GPIO口名称  如:GPIO1、GPIO5           
/* 参数2:pin        引脚号      如: 18 、1               
/* 例如:读取GPIO1_IO18电平:                           
/* GPIOx_pin_read(GPIO1,18);                        
*********************************************************/
int GPIOx_pin_read(GPIO_Type *GPIOx, uint8_t pin)
{   
  //  GPIOx->GDIR &= ~(1<<pin);  //置0 输入模式
    uint8_t pin_value;
    pin_value = ((GPIOx->DR) >> pin) & 0x01;
    return( pin_value);
}
这个函数和视频里也一样,我一开始用的 pin_value = ((GPIOx->DR) >> pin); 没用 “按 位 与0” 消除 高位的影响,
验证时发现 返回值不是预期的 0X0 或 0X1 这里备注一下。
解答上一篇《正点原子 linux 第二期 裸机开发视频 P23-24 第13讲 按键输入实验》的疑问:
函数 IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0) 的第四个参数:
0x020E0318     IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B  也就是 电气配置寄存器 地址
这里已经把 IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B 写上去了
但是却在最后一个(第五个)参数写了0  未对 IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B 进行配置
假如直接写成下面这个语句:
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0X1F080);
是否就完成了 IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B  也就是 电气配置寄存器 的配置?
也就不需要后面第二条语句来配置电气属性了
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18,0x1F080);
经过实际验证后发现可以直接在 IO复用时 就对 电气属性进行配置:
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18,0X1F080);
效果是完全一样的,不过这只是对GPIO来说是这样,其它功能复用时可不可以这样做以后再验证。
本节思考:
这篇编写的GPIO通用驱动虽然可以对任意的GPIO引脚进行读写,但是前提是这些引脚已经被复用为GPIO,且电气属性配置完成了。
也就是说 GPIO初始化、GPIO读写函数 要在下列两个函数之后使用:
IOMUXC_SetPinMux();     //功能复用
IOMUXC_SetPinConfig();  //电气配置
我的 main.c 中没有直接这两个函数是因为 在 key led beep 初始化时已经进行过一次复用和配置了。
大家试验一下把 前面的初始化注释掉后,直接使用GPIO读写来操作 led beep 和key 看看这几个 GPIO驱动还有没有效果。
/**********************************************************************************************/
个人总结:  通用GPIO编写实验  
之前都是一边看视频一边跟着写代码,这一次尝试了先看完视频然后独立写自己的代码实现同样的功能,这样自己的思考会多一点点,
学习是一个模仿加思考的过程,只要原理相同,自己也可以写出好的代码。齐白石说:学我者生,像我死者。大概就是这个意思,
哪怕有时候错了也没关系,慢慢去完善,修改。
以上注释和代码都是在学习 《正点原子 linux 第二期 裸机开发视频 P25 第13.3讲 通用GPIO驱动编写》 过程中
跟着 左萌主 学习并加入了一点点自己的思考写成的,作为一个小菜鸡,我大着胆子发出来跟大家一起记录学习
如果有帮助请大家自行参考、下载,如果 转载 请注明出处,并在论坛和我联系。如果有错误请大神指正!左萌主赛高!
作者        :YOKI
导师        :正点原子 左忠凯 (请允许我叫你一声导师吧)
硬件        :正点原子 ALPHA I.MX LINUX 开发板
/*********************************************************************************************/


7_2_key_bsp.rar

267.93 KB, 下载次数: 0

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

890

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2390
金钱
2390
注册时间
2019-9-25
在线时间
397 小时
发表于 2020-3-26 13:32:18 | 显示全部楼层
回复 支持 反对

使用道具 举报

5

主题

17

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-3-22
在线时间
35 小时
 楼主| 发表于 2020-3-26 15:46:53 | 显示全部楼层

谢谢回复 你的名字让我想到 灵剑山 的名菜 哈哈哈
回复 支持 反对

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2178
金钱
2178
注册时间
2018-8-27
在线时间
258 小时
发表于 2020-3-26 17:13:21 | 显示全部楼层
总结的不错!
森罗万象
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 07:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表