矩阵键盘

本文介绍了一个基于瑞萨R5F211B4单片机的16键矩阵键盘扫描程序的设计与实现。该程序通过P1端口实现了16个按键的识别,并在按下按键时通过蜂鸣器反馈声音信号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/***********************************************************************/
/*                                                                     */
/*  FILE        :Matrix16Key.c                                         */
/*  DATE        :Fri, May 31, 2013                                     */
/*  DESCRIPTION :main program file.                                    */
/*  CPU GROUP   :1B                                                    */
/*                                                                     */
/*  This file is generated by Renesas Project Generator (Ver.4.8).     */
/*                                                                     */
/***********************************************************************/
/***********************************************************************                                 
硬件资源:瑞萨R5F211B4
程序编制:林华电子商行
淘宝店网址:http://shop70189212.taobao.com	
功能:P1端口P1_0---P1_7组成4x4矩阵键盘(共16个键)分别设置键值=0-F共16个数
上电蜂鸣器响1声(0.15秒),当按键有效蜂鸣器响1声(0.15秒)
本程序设定按键值与学习板按键值相同的
硬件连接
	学习板			芯片IO口		芯片管脚数
	p10				p1_0(input)			18pin
	p11				p1_1(input)			17pin
	p12				p1_2(input)			15pin
	p13				p1_3(input)			14pin
	p14				p1_4(output)		13pin
	p15				p1_5(output)		12pin
	p16				p1_6(output)		11pin
	p17				p1_7(output)		10pin
	BUZ				p3_3(驱动蜂鸣器)	19pin
晶振:12MHZ
/***********************************************************************/
#include "sfr_R81B.h"  //Definition of R8C/1B SFR
#include "asmmacro.h" //汇编宏文件
#define	_Disableint	asm("Fclr I")   //I标志位为0,则禁止所有的可屏蔽中断
#define	_Enableint	asm("Fset I")   //I标志位置1,表示打开总中断控制
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define	LOW		((_Bool) 0)
#define	HIGH	((_Bool) 1)
#define	Clock	p3_5
#define	Data	p3_4

#define PORT2_KEY p1		//按键扫描端口
#define buzzer 	p3_3	//定义蜂鸣器驱动端口	
_Bool key_bit0;//按键侦测
_Bool key_bit1;//按键可靠
_Bool buzzer_bit0;//蜂鸣器开关标志
uint key_delay0;//按键去抖计时
uint count0;//蜂鸣器响计时
uchar key_code;//按键代码值
uchar column;//按键值左移位数+1

uchar far display0[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};


void InitClock(void);//初始化时钟
void Init_IO(void);//初始化IO口
void InitTimerX(void);//初始化X定时器
void key_scan(void);//按键扫描
void send_data(uchar data_164);

void main(void)
{
	_Disableint;  //禁止全局中断                        
	InitClock();  //外部部高速振荡器
	Init_IO();    //IO口初始化
 	InitTimerX();//初始化X定时器
	_Enableint; //允许全局中断 
	buzzer_bit0 = 1;//上电蜂鸣器响1声              
	while(1)
	{
		asm("NOP\nNOP\nNOP\nNOP");		
		key_scan();//按键扫描子程序
	 }	
}
/************************************************************************
程序名称:系统时钟初始化 选主时钟 1分频
************************************************************************/
void InitClock(void)
{
        prcr=0x01;                          //关闭和时钟相关的保护寄存器,允许修改时钟 
		cm13=1; 						    //XIN-XOUT引脚
		cm15 =1;					     	//XIN-XOUT引脚使用高驱动能力
		cm05=0;					    	    //开始振荡
		asm("NOP\nNOP\nNOP\nNOP");
		asm("NOP\nNOP\nNOP\nNOP");
		ocd2=0x00;					    	//使用主时钟作为系统时钟 
 		cm16=0;cm17=0;cm06=0;           	//f1
		prcr=0;                             //打开保护寄存器
}
/************************************************************************
*函数原型: Init_IO
*功能 :定义每个IO端口方向
************************************************************************/
void Init_IO()
{		                		
	pd1 = 0xf0;	//低四位输入 高四位输出 /设定输入模式 1 输出模式  0 输入模式
	pd3_3 = 1;//置pd3_3输出 
	pd3_4 = 1;
	pd3_5 = 1;	
	buzzer = 0;//关蜂鸣器	
}
/************************************************************************
 定时器X:定时0.5ms初始化设置
************************************************************************/
void InitTimerX(void)
{
	txs=0;                                 //定时器X停止计数
	txmr=0x00;                             //定时器X寄存器txmr写0
	txck1=0;txck0=0;                       //分频系数f1
	prex=120-1;                            //t=((50*120)/12M)s
	tx=50-1;								//定时0.5ms中断
	txic=6;                                //中断优先级6
	txs=1;                                 //定时器开始计数
 }
/**************************************************************************
 程序名称:定时器X中断处理
 **************************************************************************/
#pragma INTERRUPT TimerXInt(vect=22)
void TimerXInt(void)
{
	ir_txic=0;      //清中断请求标志		
	if(buzzer_bit0 == 1)//开蜂鸣器标志=1吗
	{
		count0 += 1;
		buzzer = ~buzzer;	//输出方波信号驱动蜂鸣器 频率:2K
		if(count0 > 300) //是的 计时次数到吗
		{
			count0 = 0;	//中断1次计时+1
			buzzer_bit0 = 0;//关蜂鸣器标志清零
			buzzer = 0;//关闭蜂鸣器
		}
	}
		
}
/***********************************************************************
程序名称:4x4=16按键 功能描述:P1低四位输入 高四位输出 读低四位其中一位是否
=0, 如果=0 则认为有按键并蜂鸣器响1声
输入变量: key_delay0 按键防抖动延时  输出变量:key_code 按键代码
影响标志位:key_bit0 按键侦测标志0 key_bit1 按键确认标志1
************************************************************************/
void key_scan(void)
{
	uchar key0, key1, key2;//定义子程序使用变量
	key0 = PORT2_KEY; //保存按键值	
	key0 &= 0x0f;//取按键值低四位
	if(!key_bit1) //有可靠键标志吗
	{
		if(!key_bit0) //否 有按键侦测吗?
		{
			if(key0 != 0x0f)//否 有按键值吗?
			{
				key_bit0 = 1;//是的 置按键侦测标志
			}
			else
			{
				PORT2_KEY = sha_b(1, PORT2_KEY);//无按键则左移一位
				column++; //扫描计数+1
				if(column > 3) //扫描大于3吗
				{
					column = 0;//是的 计数清零
					PORT2_KEY = 0xef;//重新扫描赋初值
				}
			}
		}
		else
		{
			key_delay0 += 1; //延时去抖动计时+1
			if(key0 == 0x0f) //有抖动键吗
			{
				key_bit0 = 0;//是的,抖动键 按键侦测标志key_bit0 =0;
			}
			else
			{
				if(key_delay0 > 5000) //延时到吗
				{
					key_delay0 = 0; //是 抖动延时清零
					key_bit1 = 1;//置按键可靠标志1
					buzzer_bit0 = 1;//开蜂鸣器响1声
				}
			}
		} 
	}
	else
	{
		key1 = PORT2_KEY;//保存按键值
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");	
		switch(key1)
		{		
			case 0x7e:							
				key_code = 0xF;//'F'; //根据不同键值确定不同功能 (学习板按键值相同)
				break;
			case 0x7d:
				key_code = 0xE;//'E';//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0x7b:
				key_code = 0xD;//'D';//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0x77:
				key_code = 0xC;//'C';//根据不同键值确定不同功能(学习板按键值相同)
				break;	
			case 0xb7:
				key_code = 8;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xbb:
				key_code = 9;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xbd:
				key_code = 0xA;//'A';//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xbe:
				key_code = 0xB;//'B';//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xd7:
				key_code = 4;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xdb:
				key_code = 5;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xdd:
				key_code = 6;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xde:
				key_code = 7;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xe7:
				key_code = 0;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xeb:
				key_code = 1;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xed:
				key_code = 2;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			case 0xee:
				key_code = 3;//根据不同键值确定不同功能(学习板按键值相同)
				break;
			default:
				asm("NOP\nNOP\nNOP\nNOP");
				break;
			}
			send_data(display0[key_code]);
		}			
		key2 = PORT2_KEY; //保存按键值
		key2 &= 0x0f;//取低四位
		if((key_bit1 == 1) && (key2 == 0x0f))//等待按键释放(松手)
		{
			key_bit0 = 0; //清按键侦测标志0 重新开始
			key_bit1 = 0; //清按键可靠标志1 重新开始
		}				
}					
 
		
 /*******************************************************************************
程序名称: 164发送一个字节, 功能描述:上升沿锁存数据
输入变量:  data 发送数据  输出变量:无
影响标志位:无
********************************************************************************/
void send_data(uchar data_164)
{   
	uchar i;	   
	for(i = 0;i < 8;i++) //连续发送0-7位
	{
		if(data_164 & 0x80)//判断BYTE.7是高电平还是低电平 
		{
			Data = HIGH;//高电平=1
		}
		else
		{
			Data = LOW;//低电平=0
		}
		data_164 <<= 1;//数据左移1位
		Clock = LOW;//置时钟低电平
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");	
		Clock = HIGH;//置时钟高电平
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");	
		asm("NOP");
		asm("NOP");			
	}	
}		

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值