一、介绍

在这篇文章中,我们以按键作为输入器件对飞思卡尔XEP100单片机的GPIO的输入功能进行测试。对应的硬件电路如下图所示。

当按键未按下时,由于有上拉电阻R39~R312的作用,单片机检测到的电平为高电平;当按键按下时,单片机引脚与地短接,单片机检测到引脚为低电平。

当按键按下时,按键输出端的原始电平如下图所示:

由图中可以看出,在按键按下和松开时,按键的电平信号存在波动,一般为10~15ms,这样有可能导致误判。为了消除抖动,可行的方法有:硬件去抖和软件去抖两种方法。本文的电路上使用的方法为硬件去抖,即在按键的两端加了一个去抖电容。软件去抖的方法是在检测到按键按下后,延时10~15ms,跳过抖动的这段信号,再进行检测,如果是低电平则判断按键按下。

本文的硬件电路的按键与单片机引脚的连接关系如下:

PTH3——KEY1

PTH2——KEY2

PTH1——KEY3

PTH0——KEY4

单片机的PH口是有中断功能的I/O口,因此对按键状态的读入有查询和中断两种方式。

所谓查询方式是指,单片机以一定的时间间隔按时对输入口的电平进行读取。中断是指计算机在执行程序的过程中,当出现异常情况或特殊请求时,计算机停止现在执行的程序,转向对这些异常情况或特殊请求的处理,处理结束后再返回之前的程序的间断处,继续执行原程序。中断时单片机实时处理内部事件或外部事件的一种机制,当某种内部事件或外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序转而去执行中断事件,中断事件处理完毕后,再返回被中断的程序处,继续执行下去。中断机制如下图所示。

在程序中使用中断具有以下优点:

(1)提高了CPU的效率。CPU与外围设备的工作方式有查询和中断两种方式,查询方法是无论外围设备是否需要服务,CPU每隔一段时间都要依次查询一遍,这种方法CPU需要花费时间做查询工作。而中断则是在外围设备需要服务时主动告诉CPU,CPU则停下当前的工作去处理中断程序,从而可以提高CPU的效率。

(2)可以实现实时处理。外围设备任何时刻都可以发出请求中断信号,CPU接到请求后及时处理,以满足实时的需求。

(3)可以及时处理故障。单片机系统运行过程中难免会出现故障,有许多事情是无法预料到的。如:电源掉电、存储器出错、外围设备工作不正常等,这时可以通过中断系统向CPU发送中断请求,由CPU及时转到相应的出错处理程序,从而提高了系统的可靠性。

产生中断时,中断服务程序执行完毕后恢复单片机状态,单片机从被中断打断的地方继续执行。当某一中断事件发生,与该事件相对应的标志将被置位。如果该中断未使能,那么单片机不会对该中断作出反应。CCR寄存器中的全局中断屏蔽位I在复位之后为1,屏蔽掉所有中断事件。在用户程序完成堆栈指针和其他设置之后,清除I,允许单片机响应中断事件,程序中的 “EnableInterrupts;”语句就是实现使能中断的功能。当单片机接收到一个有效的中断请求,在响应之前,它会执行完当前运行的指令,然后逐周期执行以下过程:

保存CPU寄存器到堆栈中
        设置CCR寄存器中的I=1,禁止全局中断
        获取当前所有挂起的待处理中断事件中最高优先级中断向量
        预取中断向量的地址排列到指令队列中
当单片机响应中断后,I自动置为1,避免中断嵌套。通常,ISR执行完毕后,I恢复为0(CCR从堆栈弹出)。如果在ISR中,清除I(即设置I=0),那么MCU有可能在当前中断事件未完成之前响应其他中断事件,即中断嵌套。中断嵌套可能对用户程序调试带来麻烦。

当ISR执行到RTI指令,CCR,A,X,PC从堆栈恢复。

用户可在自己的中断服务程序一开始将I清零,从而使能全局中断。那么当前运行的中断服务程序可以被其他中断打断,MCU运行新的中断服务程序,从而形成中断嵌套。用户在使用中断嵌套时会对调试带来不便,故建议避免使用中断嵌套。在中断服务程序的开始,用户程序应清掉产生该中断的标志位,其目的是同一中断源产生另外一个中断事件能够被记录,并在完成当前中断服务程序之后能够得到MCU的响应。

每一个中断对应一个中断向量。这个向量指向这个中断的服务程序。用CodeWarrior编程时,在工程的“Project Settings\Linker Files”文件夹下的“Project.prm”文件中设置相应中断的中断向量。

二、查询方式读取按键

在这个实验中,我们采用查询方式对按键的状态进行读取,主要代码如下,(完整代码可以从本文的资源中下载)

void main(void) {DisableInterrupts;init_led_key();   EnableInterrupts;for(;;) {delay();data=data<<1;         //左移一位if(data==0)data=0x01;if(KEY1==0&&KEY1_last==1)   //按键F1按下mode=1;if(KEY2==0&&KEY2_last==1)   //按键F2按下mode=2;          KEY1_last=KEY1;             //保存F1的状态KEY2_last=KEY2;             //保存F2的状态if(mode==1)LED = ~data;elseLED = data;}
}

在这段代码中,发光二极管以流水灯的方式进行闪烁,每个周期经过delay();函数延时之后,读取KEY1和KEY2的状态,并且与上个周期的转态进行比较,如果上个周期为1(没有按下),这个周期为0(按键按下),则改变灯闪的模式,如果按下按键“KEY2”,则8个灯中只有一个熄灭,并且熄灭的灯循环向右移动。按下按键“KEY1”,则8个灯中只有一个点亮,并且点亮的灯循环向右移动。

三、中断方式读取按键

在这个实验中,我们通过中断来进行按键的读取,为了使能中断功能,首先要对按键进行初始化,代码如下所示。

void init_key(void)
{KEY1_dir =0;       //设置为输入KEY2_dir=0;KEY3_dir=0;KEY4_dir=0;PPSH = 0x00;             //极性选择寄存器,选择下降沿;PIFH = 0x0f;                 //对PIFH的每一位写1来清除标志位;PIEH = 0x0f;             //中断使能寄存器;
}

在这段代码中,首先将每个按键的方向寄存器设置为输入状态,然后通过PPSH寄存器设置PH0~PH3的输入极性为下降沿触发中断。PIFH = 0x0f; 将标志位清除,PIEH=0x0f; 将中断功能使能。

这个程序的主函数代码如下所示。

void main(void) {DisableInterrupts;init_led();init_key();EnableInterrupts;for(;;) {delay(time);if(direction==1){data=data<<1;         //左移一位if(data==0)data=0x01;} else {data=data>>1;         //右移一位if(data==0)data=0x80;}LED = ~data;}
}

这段代码中,初始化了按键和LED,然后主循环中控制LED闪烁,LED的状态根据time和direction进行变化,time决定了延时的长短,进而影响闪烁的快慢,direction影响灯闪烁的方向。

中断的处理函数如下所示

interrupt void PTH_inter(void)
{if(PIFH != 0)     //判断中断标志{PIFH = 0xff;     //清除中断标志if(KEY1 == 0)         //按键1按下{time-=1;if(time==0)time=1;}if(KEY2 == 0) {time+=1;if(time>10)time=10;}if(KEY3 == 0)direction=0;if(KEY4 == 0)direction=1;}
}

由于中断设置的是下降沿触发中断,当有按键按下时,会进入中断函数,在中断函数中,首先确认标志位,判断是否确实有中断发生,然后判断是哪个按键按下,用KEY1和KEY2来改变time的值,用KEY3和KEY4来改变direction的值。

需要注意的是,要设置中断向量,在工程的“Project Settings\Linker Files”文件夹下的“Project.prm”文件中设置,如下所示,

VECTOR ADDRESS 0xffcc PTH_inter

这个实验的现象是,8个LED灯中有一个点亮,并且点亮的灯循环向右移动。按下按键“KEY1”,灯移动的速度加快;按下按键“KEY2”,灯移动的速度减慢;按下按键“KEY3”,灯向左移动;按下按键“KEY4”,灯向右移动。

飞思卡尔16位单片机(四)——GPIO输入功能测试相关推荐

  1. 飞思卡尔16位单片机(十四)—— CAN总线模块测试

    一.CAN模块介绍 这个实验我们来研究XEP100单片机内部的CAN模块. XEP100单片机的CAN的基本特性如下: • 实施CAN协议-2.0A/B版 - 标准和扩展数据帧 - 0-8字节数据长度 ...

  2. 飞思卡尔16位单片机(五)——ADC模数转换模块测试

    一.介绍 ADC模块的作用是将模拟的电压信号转换为CPU可以处理的数字信号.一些低端的单片机上没有ADC模块,必须使用片外的ADC芯片,才能实现模数转换的功能.而飞思卡尔的单片机一般是集成了ADC模块 ...

  3. 飞思卡尔16位单片机(十五)—— 如何批量烧写芯片

    我们在进行飞思卡尔单片机开发时,一般使用CodeWarrior软件和usbdm调试器进行.但是在实际生产过程中,采用这种方式烧写芯片效率比较低,而且很多情况下,程序的源码不希望对生产人员开放,本文就是 ...

  4. 飞思卡尔16位单片机(十)——PIT模块测试

    一.PIT模块介绍 PIT是周期中断定时器模块的简称,XEP100单片机的PIT定时器是一系列24位定时器的阵列.可以用来触发单片机的外围设备,也可以用来产生周期性的中断.XEP100单片机的PIT模 ...

  5. 飞思卡尔16位单片机(十二)—— IIC模块测试

    一.IIC模块介绍 目前市场上很多单片机都已经具有硬件IIC总线控制单元,这类单片机在工作时,IIC总线状态由硬件监测,无需用户介入,操作方便. IIC总线是双线.双向的串行总线,是与其它芯片交换数据 ...

  6. 飞思卡尔mc9s08烧录方法_飞思卡尔8位单片机MC9S08JM60开发板实践教程

    第一章 搭建实验环境 系统时钟设置 #include "App\Include\App.h" #ifndef _MCG_C #define _MCG_C //oscillator  ...

  7. 飞思卡尔mc9s08烧录方法_(整理)飞思卡尔8位单片机MC9S08JM60开发板实践教程

    精品文档 精品文档 第一章 搭建实验环境 系统时钟设置 #include "App\Include\App.h" #ifndef _MCG_C #define _MCG_C //o ...

  8. freescale飞思卡尔 HC9S12 系列单片机 Flash擦写详解(一)之时钟设置

    Flash擦写的内容,个人做HC9S12系列单片机时觉得应该是各模块内容中最难而且是最麻烦的一步了.只有能够对Flash进行擦写以后,所做的Bootloader才有真正手段将串口或者其他通讯手段接收到 ...

  9. 飞思卡尔MC9S12系列单片机地址影射以及分页问题

    对于用MCU的人来说,不一定要明白HCS12(x) memory map的机制和联系.因为如果没有系统地学习操作系统和编译原理之类的课程,确实有些难度.并且,对于DG128 XS128这样的MCU,默 ...

  10. 飞思卡尔MKL系列单片机用jlink烧写程序出现的Kinetis (connect): Timeout while halting CPU. CPU does not stop.问题

    最近用Jlink烧写飞思卡尔MKL16Z128单片机时发现经常出现不能连接成功的情况,用的是SWD接口,排查了好久后来发现问题在单片机的RESET脚上,因为之前用SWD接口的时候只接4线(SWD.SC ...

最新文章

  1. python 变量聚类 proc varclus_使用SAS进行简单的聚类分析讲解
  2. 以Attribute加上Header验证
  3. 中国计算机学会CCF推荐国际学术会议和期刊目录-计算机图形学与多媒体
  4. laravel 队列学习
  5. python的特性是_python的特性
  6. java 反射机制 在structs2_Java面试题之Struts2
  7. hdu 5996 dingyeye loves stone(博弈)
  8. C#给Winform的button等控件添加快捷键三种方法
  9. InnoDB Plugin 1.0.2 for MySQL 5.1.30 (GA) Released
  10. 微信小程序添加使用外部字体
  11. 如何彻底卸载内置McAfee软件
  12. 菲律宾php是啥,投资菲律宾马尼拉房产的本质是什么?
  13. C语言 使用DFT得到信号幅度谱
  14. 给一个年份输出该年是否举办足球世界杯的信息,以及给一个国家的名称输出是否夺得过世界杯冠军
  15. 《Cinema 4D + After Effects动态图形设计案例解析》——1.3 动态图形的应用领域
  16. jQuery遍历对象/数组/集合
  17. (理财六)贷款用途的分类
  18. css3半圆弧线,css3实现画半圆弧线的示例代码
  19. 计算机无法连接蓝牙键盘,Windows10下蓝牙键盘连接后使用不了如何解决
  20. 程序员必读的30本书-转

热门文章

  1. java生成四位数字验证码_简单的随机生成4个数字验证码的实现
  2. OSChina 周三乱弹 ——随风潜入夜,润物细无声,晓看红湿处……
  3. 《计算机操作系统》(第四版)知识点总结
  4. STM32使用HAL库驱动W5500
  5. RIDE加载Selenium2Library总是显示红色的解决办法
  6. 周立功TinyM0开发板1114使用教程
  7. c++标准库iostream
  8. 资源 | NJUPT-Yellow-Page 南邮黄页
  9. 国外英文版云购夺宝网站项目开发制作代码解析
  10. Thinkphp 6.0商城系统,B2C商城系统全新UI