8044|7

53

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

Hanker TI M4 开发板开发应用教程第三章第三节:按键中断与按键扫描 [复制链接]

第四章Hanker TM4C123 外设应用
4.3 TM4C123 的按键控制
4.31 原理分析:
按键的输入其实就是对GPIO 口进行操作。同时引入了中断的概念。实际上按键控制分为两种情况,第一种是按键扫描,这种情况下,CPU 需要不停的工作,来判断GPIO 口是否被拉低或者置高,效率是比较低的。另一种方式为中断控制,中断控制的效率很高,一旦系统IO 口出现上升沿或者下降沿电平就会触发执行中断内的程序。

中断是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器通过一个上下文切换(context switch)来保存执行状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为CPU 指令集中的一个指令,以可编程的方式直接指示这种上下文切换,并将处理导向一段中断处理代码。中断在计算机多任务处理,尤其是实时系统中尤为有用。这样的系统,包括运行于其上的操作系统,也被称为“中断驱动的”。简单的来说就比如某个人正在做某事,突然来了个电话,他就要停下手中的事情去接电话,中断相当于这个电话。触发中断后跳出原来运行的程序去执行中断处理。首先这里我们先来学习软件中断:GPIO 中断处理。以后再其他功能中在探讨其他事件中断。

4.32 硬件设计:
中断处理电路十分简单,下图就是我们在Hanker 开发板上设计的用户中断按键。采用的是五向按键,方面设置多种控制状态,如图所示:

电路设计的时候都是按键接一个上拉电阻,提供给驱动能力因为我们设置按键端口是输入功能,考虑到输入功能的驱动能力,电路设计的时候一般加上拉电阻。

4.33 软件设计:
学习TM4C123 系列中断时,我们可以一边回想单片机中断系统一边学习。这里的思路就与单片机类似:当按下按键时,电平变动,使用上升或下降沿触发中断,然后执行中断处理事件,控制翻转LED 的亮灭,我们这里可以通过实现这个简单是功能来对TM4C123 中断进行入门。

对于单片机来说,很简单,开中断即可。但TM4C123 却有所不同。LM4F 系列中断需要设置具体中断的类型或触发方式,不同片内外设具体中断的类型或触发方式也各不相同。在使能中断之前,必须对其进行正确的设置。以GPIO 为例,分为边沿触发、电平触发两大类,共5 种.

那么首先我们建立工程项目如下图所示:

下面介绍下几个加入文件,其中lcd_320X240_ili932x.c 文件为液晶触摸屏的驱动文件,如果不使用液晶屏的话就可以不加入,要使用的时候还必须结合图形驱动库文件一起使用。

Main 函数就是我们用户编写的代码,由于我们使用了库函数编写,所以要加入外设驱动库封装.lib 文件,这里面封装了所有的外设驱动,下面我们在下面文件夹找到
Gpio.c 文件查找下面几个要使用的函数:

1.GPIOIntTypeSet( )设置指定管脚的中断类型。

函数原型:
  1. void
  2. GPIOIntTypeSet(unsigned long ulPort,
  3. unsigned char ucPins,
  4. unsigned long ulIntType)
复制代码
参数:
ulPort 是GPIO 端口的基址。
ucPins 是特定管脚的位组合(bit-packed)表示。
ulIntType 指定中断触发机制的类型。

描述:
这个函数为所选GPIO 端口上特定的管脚设置不同的中断触发机制。
参数ulIntType 是一个枚举数据类型,它可以是下面其中的一个值:
  1. GPIO_FALLING_EDGE;
  2. GPIO_RISING_EDGE;
  3. GPIO_BOTH_EDGES;
  4. GPIO_LOW_LEVEL;
  5. GPIO_HIGH_LEVEL。
复制代码
在上面的值中,不同的值描述了中断检测机制(边沿或电平)和特定的触发事件(边沿检测的上升沿、下降沿或上升/下降沿,电平检测的低电平或高电平)。
管脚用一个位组合(bit-packed)的字节来指定,这里的每个字节,置位的位用来识别被访问的管脚,字节的位0 代表GPIO 端口管脚0、位1 代表GPIO 端口管脚1 等等。

2.IntMasterEnable( )使能处理器中断
原型
  1. tBoolean IntMasterEnable(void)
复制代码
参数

返回
如果在调用该函数之前处理器中断是使能的,则返回false
如果在调用该函数之前处理器中断是禁止的,则返回true
3.IntEnable( )使能一个片内外设的中断
原型
  1. void IntEnable(unsigned long ulInterrupt)
复制代码
参数
ulInterrupt:指定被使能的片内外设中断,
知道上面三个函数,我们就可以来编程了,对于Stellaris 系列ARM,使能一个片内外设
的具体中断,通常要采取分3 步走的方法:
  1. 1 调用片内外设具体中断的使能函数
  2. 2 调用函数IntEnable( ),使能片内外设的总中断
  3. 3 调用函数IntMasterEnable( ),使能处理器总中断
  4. 按照上面三个步骤我们介绍上一节关于GPIO 的编程方法,通过调用相应库函数来编
  5. 写程序,
  6. 这里面需要详细介绍下:
  7. 01. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. 02. /-----------------------------------------------------------------------------
  9. 03. // 文件名: int.c
  10. 04. // 作者: 青风
  11. 05. // ARM 内核: Cortex-M4
  12. 06. // 使用芯片: LM4F232H5QD
  13. 07. // 开发环境: KEIL
  14. 08. // 版本记录: V1.00 2011-12-26 14:30
  15. 09. // 功能说明:
  16. 10. //-----------------------------------------------------------------------------
  17. 11. #include "inc/hw_types.h" //定义常用的宏
  18. 12. #include "inc/hw_memmap.h" //定义功能存储映射
  19. 13. #include "grlib/grlib.h" //
  20. 14. #include "drivers/lcd_320x240_ili932x.h"
  21. 15. #include "driverlib/sysctl.h" //
  22. 16. #include "driverlib/gpio.h" //
  23. 17. #include "driverlib/pin_map.h" //
  24. 18. #include "driverlib/fpu.h" //
  25. 19. #include "inc/hw_ints.h" //定义中断分配数
  26. 20. #include "driverlib/interrupt.h" //
  27. 21. //-----------------------------------------------------------------------------
  28. 22. // 子函数功能说明: 扫描按键,中断翻转LED
  29. 23. // 输入参数: 无
  30. 24. // 返回参数: 无
  31. 25. //-----------------------------------------------------------------------------
  32. 26. void GPIO_INT_G(void)
  33. 27. {
  34. 28. unsigned char ucVal;
  35. 29. unsigned long ulStatus;
  36. 30. ulStatus = GPIOPinIntStatus(GPIO_PORTG_BASE, true); // 读取中断状态
  37. 31. GPIOPinIntClear(GPIO_PORTG_BASE, ulStatus); // 清除中断状态,重要
  38. 32. if (ulStatus & GPIO_PIN_0) // 如果KEY 的中断状态有效
  39. 33. {
  40. 34. ucVal = GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7); // 翻转LED
  41. 35. GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, ~ucVal);
  42. 36. SysCtlDelay(10*(SysCtlClockGet()/ 3000)); // 延时约10ms,消除按键抖动
  43. 37. while (GPIOPinRead(GPIO_PORTG_BASE, GPIO_PIN_0) == 0x00); // 等待KEY
  44. 抬起
  45. 38. SysCtlDelay(10*(SysCtlClockGet()/ 3000)); // 延时约10ms,消除松键抖动
  46. 39. }
  47. 40. }
  48. 41.
  49. 42. //-----------------------------------------------------------------------------
  50. 43. // 主函数
  51. 44. // 函数功能: 按下按键产生中断,使led 灯来回翻转亮灭。PF5 接按键,PH4 接led 灯
  52. 45. // 输入参数: 无
  53. 46. // 返回参数: 无
  54. 47. //-----------------------------------------------------------------------------
  55. 48. int main (void)
  56. 49. {
  57. 50. tContext sContext;
  58. 51. tRectangle sRect;
  59. 52. FPUEnable(); //FPU 使能
  60. 53. FPULazyStackingEnable(); //使能FPU 堆栈
  61. 54. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ |
  62. 55. SYSCTL_OSC_MAIN); //系统时钟设置
  63. 56. lcd_ili932x_init(); //初始化LCD 驱动
  64. 57. GrContextInit(&sContext, &g_sLcdDisplay);//初始化图形库
  65. 58. lcd_backlight_on();
  66. 59. lcd_ili932x_flush(&sContext);
  67. 60. sRect.sXMin = 0;
  68. 61. sRect.sYMin = 0;
  69. 62. sRect.sXMax = GrContextDpyWidthGet(&sContext) - 1;
  70. 63. sRect.sYMax = 23;
  71. 64. GrContextForegroundSet(&sContext, ClrDarkBlue);
  72. 65. GrRectFill(&sContext, &sRect); // 填充蓝色方块
  73. 66. GrContextForegroundSet(&sContext, ClrWhite);
  74. 67. GrRectDraw(&sContext, &sRect); // 加白色框框
  75. 68. GrContextFontSet(&sContext, &g_sFontCm20);
  76. 69. GrStringDrawCentered(&sContext, "key int", -1,
  77. 70. GrContextDpyWidthGet(&sContext) / 2, 10, 0); // 显示KEY 中断实验标志
  78. 71. GrContextFontSet(&sContext, &g_sFontCm40);
  79. 72. GrStringDrawCentered(&sContext, "key int START!", -1,
  80. 73. GrContextDpyWidthGet(&sContext) / 2,
  81. 74. ((GrContextDpyHeightGet(&sContext) - 24) / 2) + 10,
  82. 75. 0); // 显示提示实验开始
  83. 76. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); // 使能外设GPIOH
  84. 77. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); // 使能外设GPIOF
  85. 78. GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7,
  86. 79. GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
  87. 80. // 设置PH4 为2MA,
  88. 81. GPIOPadConfigSet(GPIO_PORTG_BASE,GPIO_PIN_0,
  89. 82. GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
  90. 83. // 设置PB4 为2MA,上拉输入
  91. 84. GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_OUT);
  92. //PH4 设为输出
  93. 85. GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_DIR_MODE_IN);
  94. 86. //PF5 设为输入
  95. 87. GPIOIntTypeSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_LOW_LEVEL);
  96. // 按键中断设为低电平触发
  97. 88. GPIOPinIntEnable(GPIO_PORTG_BASE, GPIO_PIN_0);
  98. 89. // 使能KEY 所在管脚的中断
  99. 90. IntEnable(INT_GPIOG); // 使能GPIOF 端口中断
  100. 91. IntMasterEnable(); // 使能处理器中断
  101. 92. for(;;) // 等待KEY 中断
  102. 93. {
  103. 94. };
  104. 95. }
  105. 96.
复制代码
在主函数里面我们使用了一个中断函数GPIO_INT_G,这个函数必须在启动文件
Startup.s 里进行声明,并且修改如下内容,加入声明:

定义中断:

这样,一个简单的GPIO 中断函数就编写完成了,包括按键控制。按键控制和单片机一样加入延迟进行消抖,这里面使用了一个库函数定义过的函数:SysCtlDelay 在函数文件:sysctl.c 函数中通过汇编语言定义的一个延迟函数。The SysClock 的大小,大家可以提前定义。这个设置在以后系统设置中详细讲述。

下载成功后出现下面现象:按下按键后led 灯翻转。

2.jpg (23.98 KB, 下载次数: 4)

2.jpg

最新回复

好的,谢谢。  详情 回复 发表于 2016-7-20 14:32
 
点赞 关注(2)

回复
举报

9

帖子

1

TA的资源

一粒金砂(中级)

沙发
 
先睹为快,楼主好人
 
 

回复

191

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
长知识了
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(中级)

4
 
正需要,有问题再来请教哈
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(中级)

5
 
液晶屏是怎样接在上面的啊
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(中级)

6
 
大侠,
GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_OUT);

GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_7);
有没有区别呢?

点评

楼主很久没有逛论坛了,建议重新开贴提问。  详情 回复 发表于 2016-7-20 10:56
 
 
 

回复

6066

帖子

92

TA的资源

裸片初长成(初级)

7
 
阿龙online 发表于 2016-7-20 10:53
大侠,
GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_OUT);

GPIOPinTypeGPIOOutput(G ...

楼主很久没有逛论坛了,建议重新开贴提问。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(中级)

8
 
maylove 发表于 2016-7-20 10:56
楼主很久没有逛论坛了,建议重新开贴提问。

好的,谢谢。
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表