富士通半导体 ( 上海 ) 有限公司应用笔记 MCU-AN-500038-Z-10 F²MC-8FX 家族 8 位微型控制器 MB95200 系列 使用矩阵的键盘开发 应用笔记
修改记录 修改记录 版本日期作者修改记录 1.0 3/5/2009 Benjamin. Yang 初稿 本手册包含 19 页 1. 本文档记载的产品信息及规格说明如有变动, 恕不预先通知 如需最新产品信息和 / 或规格说明, 联系富士通销售代表或富士通授权经销商 2. 基于本文档记载信息或示意图的使用引起的对著作权 工业产权或第三方的其他权利的侵害, 富士通不承担任何责任 3. 未经富士通明文批准, 不得对本文档的记载内容进行转让 拷贝 4. 本文档所介绍的产品并不旨在以下用途 : 需要极高可靠性的设备, 诸如航空航天装置 海底中继器 核控制系统或维系生命的医用设施 5. 本文档介绍的部分产品可能是 外汇及外贸管理法 规定的战略物资 ( 或专门技术 ), 出口该产品或其中部分元件前, 应根据该法获得正式批准 版权 2009 富士通半导体 ( 上海 ) 有限公司 MCU-AN-500038-Z-10- 第 2 页
目录 目录 修改记录... 2 目录... 3 1 概要... 5 2 硬件设计... 6 3 键盘开发... 7 3.1 矩阵电路的功能... 7 3.2 抖动消除... 7 3.3 抖动消除示例... 7 4 资源使用... 8 4.1 寄存器介绍... 8 4.1.1 端口数据寄存器 (PDR)... 8 4.1.2 数据方向寄存器 (DDR)... 8 4.1.3 上拉控制寄存器 (PUL)... 8 4.1.4 输入电平选择寄存器 (ILSR)... 9 4.2 简介... 9 4.2.1 如何设置输入引脚... 9 4.2.2 如何设置输出引脚... 9 4.2.3 上拉寄存器... 10 5 软件设计... 11 5.1 软件设计... 11 6 代码示例... 13 7 性能评估... 17 8 更多信息... 18 MCU-AN-500038-Z-10 - 第 3 页
目录 9 附录... 19 MCU-AN-500038-Z-10- 第 4 页
第 1 章概要 1 概要 使用 MB95200 系列 MCU 设计键盘功能的方法一共有三种 : 外部中断,AD 以及矩阵 本文档描述了如何使用矩阵法设计键盘功能, 并以实例阐述了该方法 MCU-AN-500038-Z-10 - 第 5 页
第 2 章硬件设计 2 硬件设计 本章介绍了如何运用矩阵法使用硬件电路设计键盘功能 目前有两种方法可用于消除抖动 : 软件法和硬件法 要使用硬件法, 必须在电路中增加一个电容 图 2-1: 使用矩阵设计键盘的电路 如上图所示,P04~P07 用作输出引脚,P00~P03 用作输入引脚, 用于扫描键盘状态 MCU-AN-500038-Z-10- 第 6 页
第 3 章键盘开发 3 键盘开发 本章介绍了如何使用矩阵开发键盘 3.1 矩阵电路的功能键盘是输入系统的一个重要工具 本设计指出如何用精简的 I/O 本设计采用了检测键盘状态的实时监控法 检测周期是一个固定值, 这意味着任何比该值慢的动作都将被监控软件捕捉, 从而确保了键盘的高响应性 3.2 抖动消除 抖动是键盘设计中存在的一个问题, 有二种方法可以解决这个问题 一种是在硬件电路中增加一个电容, 另一种是通过使用 8/16 位多功能定时器增加延时 3.3 抖动消除示例 以下时序图是消除抖动的一个示例 该示例采用矩阵法设计一个 4x4 的键盘 X0 X1 X2 和 X3 依次扫描键盘 50ms, 扫描整个键盘需要大约 200ms 图 3-1: 抖动消除的时序图 MCU-AN-500038-Z-10 - 第 7 页
第 4 章资源使用 4 资源使用 本章介绍了正常运行状态下的评估步骤 要监控键盘状态, 必须使用 I/O 引脚 本章将介绍 I/O 端口的使用 参见 MB95200 系列硬件 手册的第 9 章了解关于寄存器设置的更多信息 4.1 寄存器介绍 4.1.1 端口数据寄存器 (PDR) 该寄存器包含对应输入或输出引脚的位信息 如果端口方向寄存器设置为输出模式, 则输出该寄值 注意 : 资源输出控制位重写 PDR 位值 PDRx_yz Pin 功能 0 Pin state low (VSS) 1 Pin state high (VDD) 4.1.2 数据方向寄存器 (DDR) 如果引脚用作输入或输出, 该寄存器包含对应引脚的位信息 DDRx_yz 外围功能输出 引脚功能 0 禁用 端口输入 1 禁用 端口输出 invalid 启用 外围功能输出 4.1.3 上拉控制寄存器 (PUL) 该寄存器连接一个内部上拉电阻至端口引脚 PULx_yz 上拉电阻 0 禁用 1 启用 参见数据表了解关于电阻值的更多信息 MCU-AN-500038-Z-10- 第 8 页
第 4 章资源使用 4.1.4 输入电平选择寄存器 (ILSR) 该寄存器可以选择以下输入电平 ILSR 输入电平 VIL VIH 0x04 CMOS 0.3 VCC 0.7 VCC 0x00 迟滞 0.3 VCC 0.7 VCC 注意 : 只有 PDR0_P04 有此功能 4.2 简介 本系统的 I/O 引脚可以分为两类 : 输出引脚和输入引脚 输出引脚用于输出高电压, 输入引脚用于扫描键盘状态 4.2.1 如何设置输入引脚如果引脚用作输入端口, 数据方向寄存器的对应位应设置为 0 要设置外部连接源至高 Z 状态, 请使用外部上拉或下拉电阻器或者设置上拉寄存器的对应位 输入模式有三种类型 : 数字输入 ADC 输入以及外围功能输入 数字输入表示该端口用作通用 I/O ADC 输入表示该端口仅用作模拟输入 外围功能输入表示该端口被外围功能用作输入, 例如外部中断输入 4.2.2 如何设置输出引脚输出模式有两种类型 : 数字输出和外围功能输出 数字输出表示该端口用作通用 I/O 外围功能输出表示该端口用作外围资源输出, 例如 8/16 位多功能定时器的输出 MCU-AN-500038-Z-10 - 第 9 页
第 4 章资源使用 4.2.3 上拉寄存器在输入模式下,P0 和 PG 端口可通过编程上拉寄存器 (2.2.3) 启用内部上拉电阻 ( 大约 50KΩ, 参见数据表了解其具体取值 ) 初始值 0 断开与内部上拉电阻的连接 烧写 1 至 PULx 寄存器的对应位启用电阻 如果端口用作输出端口, 寄存器位的值没有意义, 上拉电阻被禁用 ( 例外 : 对于 I 2 C 引脚 SDA 和 SCL, 设置保留 对于 UART 输出 SOT, 如果不是由线路驱动器提供, 则可以使用内部上拉电阻 ) 微型控制器处于停止或定时器模式下时, 上拉电阻被禁用 如果引脚用作 ADC 输入, 电阻也被禁用 如果外部引脚被外部总线接口使用, 则不能使用内部上拉寄存器 MCU-AN-500038-Z-10- 第 10 页
第 5 章软件设计 5 软件设计 本章描述了如何使用矩阵设计键盘 5.1 软件设计要实现此功能, 首先初始化 I/O 寄存器, 并禁用 AD 输入, 然后启用定时器中断消除抖动 输出 I/O 引脚输出高电压,MCU 等待输入信号 参见硬件电路, 如果按键被按下,MCU 将扫描该信息, 并执行对应的按键功能 流程图如下所示 MCU-AN-500038-Z-10 - 第 11 页
第 5 章软件设计 图 5-1: 使用矩阵设计键盘的流程图 MCU-AN-500038-Z-10- 第 12 页
第 6 章代码示例 6 代码示例 本章描述了使用矩阵开发键盘的代码示例 以下代码基于 MB2146-410-01 说明了如何使用 I/O 端口开发键盘功能 端口 0 用于检测按键 状态 输入默认级别为高 /* THIS SAMPLE CODE IS PROVIDED AS IS AND IS SUBJECT TO ALTERATIONS. */ /* FUJITSU SEMICONDUCTOR ACCEPTS NO RESPONSIBILITY OR LIABILITY */ /* FOR ANY ERRORS OR ELIGIBILITY FOR ANY PURPOSES. */ /* (C) Fujitsu Semiconductor (Shanghai) Co., LTD. */ /*-------------------------------------------------------------------- */ /* Give a example for basic I/O matrix */ #include "../MB95200_IO/mb95200.h" void timer_init(void) T01DR = 0x13; // 5000us T00DR = 0x88; TMCR0 = 0x10; // 16-bit T00CR0 = 0x81; // interval timer with continuous mode T00CR1 = 0xA0; // disable output, start timer /*P04 SCAN*/ void IO_restart(void) // PDR0 restart PDR0 = 0xFF; void P04_low(void) // Pin P04 begin to scan PDR0_P04 = 0; void Port_Value1(void) // Read and store PDR0 in value 1 port_value1 = PDR0; void Row_one_process(void) // key judge port_value2 = PDR0; // Read and store PDR0 in value 2 if(port_value2 == port_value1) switch(port_value2) case 0xEE: SW1(); case 0xED: SW2(); case 0xEB: SW3(); case 0xE7: SW4(); /* P05 scan*/ void P05_low(void) // Pin P05 begin to scan PDR0_P05=0; MCU-AN-500038-Z-10 - 第 13 页
第 6 章代码示例 void Row_two_process(void) // key judge port_value2 = PDR0; if(port_value2 == port_value1) switch(port_value2) case 0xDE: SW5(); case 0xDD: SW6(); case 0xDB: SW7(); case 0xD7: SW8(); /* P06 scan*/ void P06_low(void) // Pin P06 begin to scan PDR0_P06=0; void Row_three_process(void) // key judge port_value2 = PDR0; if(port_value2 == port_value1) switch(port_value2) case 0xBE: SW9(); case 0xBD: SW10(); case 0xBB: SW11(); case 0xB7: SW12(); /* P07 scan*/ void P07_low(void) // Pin P07 begin to scan PDR0_P07=0; void Row_four_process(void) // key judge port_value2 = PDR0; if(port_value2 ==port_value1) switch(port_value2) case 0x7E: SW13(); case 0x7D: SW14(); case 0x7B: SW15(); case 0x77: SW16(); MCU-AN-500038-Z-10- 第 14 页
第 6 章代码示例 void SW1(void) // Key Process......... void SW16(void)...... interrupt void Timer_Interrupt (void) //key scan process T00CR1_IF=0; timer_counter++; if(timer_counter==0) // PDR0 restart IO_restart(); if(timer_counter==4) // P04 begin to scan P04_low(); if(timer_counter==5) // Read and store PDR0 Port_Value1(); if(timer_counter ==9) // Read and store PDR0 and judge keypressed Row_one_process(); if(timer_counter==10) // PDR0 restart IO_restart(); if(timer_counter==14) // P05 begin to scan P05_low(); if(timer_counter==15) // Read and store PDR0 Port_Value1(); if(timer_counter==19) // Read and store PDR0 and judge keypressed Row_two_process(); if(timer_counter==20) // PDR0 restart IO_restart(); if(timer_counter==24) // P06 begin to scan P06_low(); if(timer_counter==25) // Read and store PDR0 Port_Value1(); MCU-AN-500038-Z-10 - 第 15 页
第 6 章代码示例 if(timer_counter==29) // Read and store PDR0 and judge keypressed Row_three_process(); if(timer_counter==30) // PDR0 restart IO_restart(); if(timer_counter==34) // P07 begin to scan P07_low(); if(timer_counter==35) // Read and store PDR0 Port_Value1(); if(timer_counter==39) // Read and store PDR0 and judge keypressed Row_four_process(); if(timer_counter==40) // PDR0 restart IO_restart(); if(timer_counter>=41) // Timer_counter restart timer_counter=0; void clock_select(void) SYCC = 0x00; WATR = 0x00; STBC = 0x01; SYCC2= 0xF4; void main(void) InitIrqLevels(); EI(); timer_counter =0; DDR0 = 0xF0; //P00~P03= in P04~P07=out AIDRL = 0xFF; //Port input enable clock_select(); //Main clock select timer_init(); //Timer initialize while(1); MCU-AN-500038-Z-10- 第 16 页
第 7 章性能评估 7 性能评估 如上所述, 消除抖动的方法有两种 : 硬件法和软件法 尽管硬件法的代码非常简单, 仅使用定时器计时器的效果并不好, 因为系统不能扫描沿 比较起来, 软件方法更加有用 MCU-AN-500038-Z-10 - 第 17 页
第 8 章更多信息 8 更多信息 关于富士通半导体更多的产品信息, 请访问以下网站 : 英文版本地址 : http://www.fujitsu.com/cn/fsp/services/mcu/mb95/application_notes.html 中文版本地址 : http://www.fujitsu.com/cn/fss/services/mcu/mb95/application_notes.html MCU-AN-500038-Z-10- 第 18 页
第 9 章附录 9 附录 图 2-1: 使用矩阵设计键盘的电路... 6 图 3-1: 抖动消除的时序图... 7 图 5-1: 使用矩阵设计键盘的流程图... 12 MCU-AN-500038-Z-10 - 第 19 页