矩阵键盘扫描代码(C语言)
矩阵键盘扫描子程序

;键盘扫描子程序的功能
;扫描结果保存在累加器A中
;A=0 表示无键按下,否则表示有键盘按下
KEY_SCAN:MOV P1,#0FH ;设置P10~3为输入,P14~7为低电平
MOV A,P1 ;读取键盘状态
CJNE A,#0FH,SCAN_03 ;A不等于0FH就表明有键按下
CLR A ;按键无效标志设置A=0
RET
SCAN_03: MOV P1,#0EFH ;设置P10~3为输入,P1.4为低电平
MOV A,P1 ;读取键盘状态
CJNE A,#0EFH,END_SCAN;A不等于0EFH就表明(0,1,2,3)键按下
;A=E7 0号键A=EB 1号键A=ED 2号键A=EE 3号键
MOV P1,#0DFH ;设置P10~3为输入,P1.5为低电平
MOV A,P1 ;读取键盘状态
CJNE A,#0DFH,END_SCAN;A不等于0DFH就表明(4,5,6,7)键按下
;A=D7 4号键A=DB 5号键A=DD 6号键A=DE 7号键
MOV P1,#0BFH ;设置P10~3为输入,P1.6为低电平
MOV A,P1 ;读取键盘状态
CJNE A,#0BFH,END_SCAN;A不等于0BFH就表明(8,9,A,B)键按下
;A=B7 8号键A=BB 9号键A=BD A号键A=BE B号键
MOV P1,#7FH ;设置P10~3为输入,P1.7为低电平
MOV A,P1 ;读取键盘状态
CJNE A,#07FH,END_SCAN;A不等于07FH就表明(C,D,E,F)键按下
;A=77 C号键A=7B D号键A=7D E号键A=7E F号键CLR A
END_SCAN:RET
END。
4_4矩阵键盘扫描

//4*4矩阵式键盘扫描程序module keyscan(row, col, clk, key_buf);input [3:0] col; //列线定义input clk; //150MHZoutput [3:0] row; //行线定义output [7:0] key_buf; //键值输出口reg [3:0] row;reg [7:0] key_buf; //键值输出缓冲寄存器reg [7:0] key_buf1; //键值暂存器reg [3:0] count1;reg [14:0] count2;reg [3:0] state;reg [3:0] state_temp;reg sec, en;/*********************产生5MHZ方波****************/ always@(posedge clk )beginif(count1 == 4'd15)beginsec <= ~sec;count1 <= 4'd0;endelsecount1 <= count1+1'b1;endalways@(negedge sec)beginif(en)begincase(state)/******************** 准备进入行扫描状态*************/4'd0://KEY //开始扫描beginrow[3:0] <= 4'b0000; //行线全部置零state_temp = 4'd1;state = 4'd9; //5ms消抖end/*********************扫描第一行**********************/4'd1://KEYTEMPbeginif(col[3:0] == 4'b1111) //判断是否有键按下?state = 4'd0; //没有就重新扫描elsebeginrow[3:0] <= 4'b1110;state_temp = 4'd2;state = 4'd9; //如果有就延时去抖endend/********************检测第一行键值*******************/4'd2://ROW1begincase({row[3:0],col[3:0]}) //第一行判断8'b1110_1111: //无键按下beginkey_buf1 <= 8'b1111_1111;state = 4'd3; //进入第二行扫描end8'b1110_1110: //键值1beginkey_buf1 <= 8'b1111_1110; //键值放入key_buf1state = 4'd10; //等待弹起end8'b1110_1101: //键值2beginkey_buf1 <= 8'b1111_1101;state = 4'd10;end8'b1110_1011: //键值3beginkey_buf1 <= 8'b1111_1011;state = 4'd10;end8'b1110_0111: //键值4beginkey_buf1 <= 8'b1111_0111;state = 4'd10;enddefault:beginkey_buf1 <= 8'b1111_1111;state = 4'd3; //进入第二行扫描endendcaseend/*********************第二行扫描*********************/4'd3://ROW2TEMPbeginrow[3:0] <= 4'b1101;state_temp = 4'd4;state = 4'd9;end/***********************检测第二行键值***************/4'd4://ROW2begincase({row[3:0], col[3:0]})8'b1101_1111: //若无键按下beginkey_buf1 <= 8'b1111_1111;state = 4'd5; //进入第三行扫描end8'b1101_1110: //键值5beginkey_buf1 <= 8'b1110_1111;state = 4'd10; //等待弹起end8'b1101_1101: //键值6beginkey_buf1 <= 8'b1101_1111;state = 4'd10;end8'b1101_1011: //键值7beginkey_buf1 <= 8'b1011_1111;state = 4'd10;end8'b1101_0111: //键值8beginkey_buf1 <= 8'b0111_1111;state = 4'd10;enddefault:beginkey_buf1 <= 8'b1111_1111;state = 4'd5; //进入第三行扫描endendcaseend/**********************第三行扫描********************/4'd5://ROW3TEMPbeginrow[3:0] <= 4'b1011;state_temp = 4'd6;state = 4'd9;end/*********************检测第三行键值*****************/4'd6://ROW3begincase({row[3:0], col[3:0]})8'b1011_1111: //若无键按下beginkey_buf1 <= 8'b1111_1111;state = 4'd7; //进入第四行扫描end8'b1011_1110: //键值9beginkey_buf1 <= 8'b1111_1110;state = 4'd10; //等待弹起end8'b1011_1101: //键值10beginkey_buf1 <= 8'b1111_1100;state = 4'd10;end8'b1011_1011: //键值11beginkey_buf1 <= 8'b1111_1000;state = 4'd10;end8'b1011_0111: //键值12beginkey_buf1 <= 8'b1111_0000;state = 4'd10;enddefault:beginkey_buf1 <= 8'b1111_1111;state = 4'd7; //进入第四行扫描endendcaseend/********************第四行扫描**********************/4'd7://ROW4TEMPbeginrow[3:0] <= 4'b0111;state_temp = 4'd8;state = 4'd9;end/*********************检测第四行键值******************/ 4'd8://ROW4begincase({row[3:0], col[3:0]})8'b0111_1111: //若无键按下beginkey_buf1 <= 8'b1111_1111;state = 4'd0; //重新进入扫描end8'b0111_1110: //键值13beginkey_buf1 <= 8'b1110_0000;state = 4'd10; //等待弹起end8'b0111_1101: //键值14beginkey_buf1 <= 8'b1100_0000;state = 4'd10;end8'b0111_1011: //键值15beginkey_buf1 <= 8'b1000_0000;state = 4'd10;end8'b0111_0111: //键值16beginkey_buf1 <= 8'b0000_0000;state = 4'd10;enddefault:beginkey_buf1 <= 8'b1111_1111;state = 4'd0; //重新进入扫描endendcaseend/***********************去抖延时********************/ 4'd9://DELAYbeginif(count2 ==15'd25000)beginstate = state_temp;count2 <= 0;endelsecount2 <= count2+1'b1;end/************************等待弹起******************/ 4'd10://WAITbeginif(col[3:0] == 4'b1111)beginkey_buf <= key_buf1;state <= 4'd0;endelsestate = 4'd10;endendcaseend/*******************否则,变量初始化****************/ elsebeginstate = 4'd0;count2 <= 0;key_buf <= 8'b0000_0000;row[3:0] <= 4'b0000;en <= 1;endendendmodule附:程序配套的4*4矩阵键盘电路图其中:P2.3 ~P2.0对应row[3:0];P3.7 ~P3.4对应line[3:0]。
c语言键盘扫描码大全

c语言键盘扫描码大全对程序进行键盘控制时,往往要用到一些键的扫描码,以前每次用时都得先扫下试试,实在麻烦,今天又搞了个小程序,用到了扫描码,索性整了个测试程序,把所有键的扫描码全存入一个文件啦,以便以后编程时使用.在此跟大家分享一下,c语言键盘扫描码 扫描码键 0x011bESC 0x3b00F1 0x3c00F2 0x3d00F3 0x3e00F4 0x3f00F5 0x4000F6 0x4100F7 0x4200F8 0x4300F9 0x4400F10 主键盘区: 0x2960~ 0x02311 0x03322 0x04333 0x05344 0x06355 0x07366 0x08377 0x09388 0x0a399 0x0b300 0x0c2d- 0x0d3d= 0x2b5c\ 0x0e08退格键 0x0f09Tab 0x1071q 0x1177w 0x1265e 0x1372r 0x1474t 0x1579y 0x1675u 0x1769i 0x186fo 0x1970p 0x1a5b[ 0x1b5d] 0x1e61a 0x1f73s 0x2064d 0x2166f 0x2267g 0x2368h 0x246aj 0x256bk 0x266cl 0x273b; 0x2827’ 0x1c0d回车 0x2c7az 0x2d78x 0x2e63c 0x2f76v 0x3062b 0x316en 0x326dm 0x332c, 0x342e. 0x352f/ 0x3920空格键 右边数字键盘: 0x5200Insert 0x4700Home 0x4900Page UP 0x5300Delete 0x4f00End 0x5100PageDown 0x4800上箭头 0x4b00左箭头 0x5000下箭头 0x4d00右箭头 0x352f/ 0x372a* 0x4a2d- (注意,这是数字键盘的) 0x47377 0x48388 0x49399 0x4b344 0x4c355 0x4d366 0x4e2b+ 0x4f311 0x50322 0x51333 0x52300 0x532eDel 以上就是由为您提供的c语言键盘扫描码,希望给您带来帮助! 。
矩阵键盘扫描函数

南京工程学院 高祥 2012 年 6 月 28 日
unsigned char KeyData; unsigned char KeyNum; XX=0xfe;//检测第一行 KeyData=XX; KeyData=KeyData&0xf0; if(KeyData!=0xf0) {
Delay_Key(); // if(KeyData!=0xf0) {
KeyData=XX; switch(KeyData) {
//你要做的修改就是将 Pi 中的 i 改成 0 或 1,2,3
#include<reg52.h>
#define XX Pi //i=0,1,2,3 根据你自己的键盘接口改动
void Delay_Key() {
unsigned int i; for(i=200;i>0;i--); }
unsigned char KeyScan() {
矩阵键盘扫描函数
2012 年 6 月 28 日
/*使用说明:本文档为 4X4 键盘检测函数,你只要将该文件添加到你的工程当中, 在主函数需要检测的地方加上 KeyScan();即可完成扫描。 扫描键盘的结果是以 KeyNum 的值为标准,KeyNum 返还的值就代表哪个键被按
下*/
//在你的主程序开头加上 extern unsigned char KeyScan();
具体操作步骤: 第一步: 打开你的工程,在工程中新建一个.C 文件,命名为 KeyScan.c 并保存到你的工 程目录下,而后将其添加到你的工程中:
44矩阵键盘扫描C程序(C51)

#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar dis_buf; //显示缓存uchar temp;uchar key; //键顺序吗void delay0(uchar x); //x*0.14MS#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};// 此表为LED 的字模0 1 2 3 4 5 6 7 89 a b c d e funsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};/*************************************************************//* *//* 延时子程序*//* *//*************************************************************/void delay(uchar x){ uchar j;while((x--)!=0){ for(j=0;j<125;j++){;}}}/*************************************************************//* *//* 键扫描子程序(4*4 的矩阵) P2.4 P2.5 P2.6 P2.7为行*//* P2.0 P2.1 P2.2 P2.3为列*//* *//*************************************************************/void keyscan(void){ temp = 0;P2=0xF0; //高四位输入行为高电平列为低电平delay(1);temp=P2; //读P2口temp=temp&0xF0; //屏蔽低四位temp=~((temp>>4)|0xF0);if(temp==1) // p2.4 被拉低key=0;else if(temp==2) // p2.5 被拉低key=1;else if(temp==4) // p2.6 被拉低key=2;else if(temp==8) // p2.7 被拉低key=3;elsekey=16;P2=0x0F; //低四位输入列为高电平行为低电平delay(1);temp=P2; //读P2口temp=temp&0x0F;temp=~(temp|0xF0);if(temp==1) // p2.0 被拉低key=key+0;else if(temp==2) // p2.1 被拉低key=key+4;else if(temp==4) // p2.2 被拉低key=key+8;else if(temp==8) // p2.3 被拉低key=key+12;elsekey=16;dis_buf = key; //键值入显示缓存//dis_buf = dis_buf & 0x0f;}/*************************************************************/ /* */ /*判断键是否按下*/ /* */ /*************************************************************/void keydown(void){P2=0xF0;if(P2!=0xF0) //判断按键是否按下如果按钮按下会拉低P2其中的一个端口{keyscan(); //调用按键扫描程序}}/*************************************************************//* *//* 主程序*//* *//*************************************************************/main(){P0=0xFF; //关段码P1=0x10; //开位码delay(10); //延时while(1){keydown(); //调用按键判断检测程序P0 = LED7Code[dis_buf]; //显示按键的数值}}/************************************************************/。
矩阵键盘扫描

键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。
即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。
/***************************************************File Name :LED Debug*Autor :HR*Version :V1.0*Data :*Descrption :none*********************************************************************************************************/#include "include.h"JOB Job_Data; ----------1SYS_TimeHandler SYS_Time; ---------2MSG Msg_Key; /* 按键任务使用的结构体消息*/ ---------3uint16 test_a; ---------4uint16 TX_Buff_Byte[25]; ---------4uint8 TX_Buff_ASIC[25]; ---------4/************************************************主程序************************************************/int main(){BSP_Init(); ---------5SYSTEM_LogShow (); ---------6for(;;) {SYS_100US_handler(); ---------7SYS_10MS_handler(); ---------8SYS_100MS_handler(); ---------9SYS_200MS_handler(); ---------10}}1,JOB Job_Data;typedef struct WELD /* 任务用的焊接数据包(结构体数据类型) */ {// 临时标记uint8 FgWeldRunEn; // 焊接输出标记uint8 FgGasRunEn; // 焊接气体输出标记uint8 FgPowerRunEn; // 系统工作标记uint8 FgMotorRunEn; // 送丝机系统工作标记uint8 FgLcmFlickerEn; // 显示闪烁工作标记uint8 FgRoughMachiningEn; // 粗调节有效uint8 FgCURRENTIndicateLedEn; // 输出正常电流指示LEDuint8 FgMotorCheckEn; // 送丝机系统检测标记uint8 FgEepromSaveEn; // 数据记忆标记uint8 FgLcmHoldEn; // 冻结显示内容uint8 FgVRDReset; // VRD复位辅助标记uint8 LockState; // 4T焊接辅助指令uint8 Fg_RXFinish; // 串口接收数据完成标记uint8 Fg_ShowLog; // 开机LOG辅助标记uint8 Fg_UsartConnect; // USART连接标记uint8 FgACVoltageState; // 网压状态标记uint8 FgSystemFault; // 系统故障标记uint8 FgFactoryTest; // 工厂调试标记uint8 FgDisChannel; // 公英制切换uint8 RunVolatgeTest; // 关机检测状态// 临时数据处理uint16 FaultOrderSet; /* 设备故障指令数据缓存*/uint16 SystemOrderSet; /* 传递系统指令数据缓存*/uint16 LcmOrderSet; /* 传递LCM显示指令数据缓存*/uint16 DriveOrderSet; /* 传递驱动组件指令数据缓存*/uint16 WorkOrderSet; /* 焊接工作指令数据缓存*/uint16 MainMenu; /* 主目录数据缓存*/uint16 CheckOrderSet;uint16 LcmVoltageData; /* 焊接显示电压数据缓存*/uint16 LcmCurrentData; /* 焊接显示电流数据缓存*/uint16 LcmVoltageDataDis; /* 焊接显示电压数据缓存*/uint16 LcmCurrentDataDis; /* 焊接显示电流数据缓存*/uint16 LcmMotorData; /* 焊接显示电机数据缓存*/uint16 LcmTempData; /* 焊接显示温度数据缓存*/uint16 LcmACSupplyState; /* 网压显示数据缓存*/uint16 LCMDataBuff_2; /* LCM2显示数据缓存*/uint16 SystemVoltageData; /* 焊接实际电压数据缓存*/uint16 SystemCurrentData; /* 焊接实际电流数据缓存*/uint16 SystemCurrentBuff;// 设备数据处理(需要记忆) //uint16 WeldWorkSetMode; // 焊接类型选择:MMA,TIG,MIGuint16 WeldRunSetVRD; // VRD setuint16 WeldRunSetMode; // 焊接方式选择:2T,4T// MMA //uint16 MMASetCurrent; // MMA手工焊电流设置// TIG //uint16 TIGSetCurrent; // TIG焊接电流// MIG //uint16 MIGSetVoltage; // MIG焊接电压uint16 MIGSetMotorSpeed; // MIG送丝速度uint16 MIGSetInductance; // MIG电子电抗uint16 MIGSetVoltageFine; // MIG焊接电压微调uint8 MIGSetVoltageCorrect; // 系统给定焊接电压修正uint8 MIGDisVoltageCorrect; // 系统显示焊接电压修正uint8 MIGSetCurrentCorrect; // 系统给定焊接电流修正uint8 MIGDisCurrentCorrect; // 系统显示焊接电流修正//外置MIG //uint16 Ext_MIGSetVoltage; // MIG焊接电压// 已更改uint16 Ext_MIGSetMotorSpeed; // MIG送丝速度// 已更改uint16 Ext_MIGSetInductance; // MIG电子电抗// 已更改uint16 Ext_MIGSetVoltageFine; // MIG焊接电压微调// 已更改uint8 Ext_MIGSetVoltageCorrect; // 系统给定焊接电压修正// 已更改uint8 Ext_MIGDisVoltageCorrect; // 系统显示焊接电压修正// 已更改uint8 Ext_MIGSetCurrentCorrect; // 系统给定焊接电流修正// 已更改uint8 Ext_MIGDisCurrentCorrect; // 系统显示焊接电流修正// 已更改uint8 CheckW_VRD_RunI_2T4T;int16 V_Set_Value_08;} JOB;2,SYS_TimeHandler SYS_Time; typedef struct {uint16 TimHandler_100uS;uint16 TimHandler_10mS;uint16 TimHandler_100mS;uint16 TimHandler_200mS;} SYS_TimeHandler;3,MSG Msg_Key;typedef struct TMSG /* 任务用的消息信息数据包(结构体数据类型) */ {uint8 message; /* 传递消息值的任务,用于识别消息的来源*/ uint8 WParam; /* 消息附加信息1 */uint8 IParam; /* 消息附加信息2 */uint8 SParam; /* 消息附加信息3 */uint8 TParam; /* 消息附加信息4 */uint8 errWParam; /* 任务错误消息代码*/uint8 errIParam; /* 错误消息附加信息*/uint16 databuff; /* 消息附加信息数据*/uint32 dataTime; /* 消息的时间戳*/} MSG;4,uint16 test_a;4,uint16 TX_Buff_Byte[25];4,uint8 TX_Buff_ASIC[25];extern uint16 TX_Buff_Byte[];extern uint8 TX_Buff_ASIC[];void USART_SendCodeTest(uint16 Bata){static uint8 i = 0;TX_Buff_Byte[0] = Job_Data.WeldWorkSetMode;TX_Buff_Byte[1] = Job_Data.LcmOrderSet;TX_Buff_Byte[2] = Job_Data.MainMenu;TX_Buff_Byte[3] = Job_Data.MIGSetInductance;TX_Buff_Byte[4] = Job_Data.MMASetCurrent;TX_Buff_Byte[5] = Job_Data.MIGSetVoltage;TX_Buff_Byte[6] = Job_Data.MIGSetMotorSpeed;TX_Buff_Byte[7] = Job_Data.TIGSetCurrent;TX_Buff_Byte[8] = Job_Data.LcmVoltageData;TX_Buff_Byte[9] = Job_Data.LcmCurrentData;TX_Buff_Byte[10] = Job_Data.CheckW_VRD_RunI_2T4T;TX_Buff_Byte[11] = RobotCheckSum(TX_Buff_Byte,10);RobotUsartByteToHexAsicii(TX_Buff_Byte,11,TX_Buff_ASIC);if (USART_GetFlagStatus(USART1, USART_FLAG_TC) == 1){USART_SendData(USART1, TX_Buff_ASIC[i]);i++;if(i>23) i = 0;}}5,BSP_Init(); void BSP_Init(void){RCC_Configuration();GPIO_Configuration();USART_Configuration();NVIC_Configuration();TIM2_Configuration();SysTick_Configuration();}6,SYSTEM_LogShow ();void SYSTEM_LogShow (void){Delay_Ms (500);Job_Data.Fg_ShowLog = ENABLE;// Job_Data.LcmOrderSet = DIR_AC_SupplyCheck_Msg;Job_Data.LcmOrderSet = DIR_StarLcmLogo_Msg;}7,SYS_100US_handler();void SYS_100US_handler(void){static uint16 TimCount = 0;if (SYS_Time.TimHandler_100uS == SET){SYS_Time.TimHandler_100uS = RESET;TimCount++;if (TimCount > 9){TimCount = 0;KEY_Encoder(GPIO_EncoderKey ());LCM_ScanLED();LCM_DisMenuCase(Job_Data.LcmOrderSet);USART_DecodeData();}}}8,SYS_10MS_handler();void SYS_10MS_handler(void){if (SYS_Time.TimHandler_10mS == SET){SYS_Time.TimHandler_10mS = RESET;if (Job_Data.Fg_ShowLog == DISABLE){COMMOND_OrderChang(Job_Data.WeldWorkSetMode, Job_Data.MainMenu);USART_SendCode();}}}9,SYS_100MS_handler(); void SYS_100MS_handler(void){if (SYS_Time.TimHandler_100mS == SET){SYS_Time.TimHandler_100mS = RESET}}10,SYS_200MS_handler();void SYS_200MS_handler(void){static uint16 Tim;if (SYS_Time.TimHandler_200mS == SET){SYS_Time.TimHandler_200mS = RESET;if(Job_Data.Fg_ShowLog == ENABLE){Tim++;if (Tim > 15){Job_Data.Fg_ShowLog = DISABLE;}}Job_Data.LcmVoltageDataDis = Job_Data.LcmVoltageData;Job_Data.LcmCurrentDataDis = Job_Data.LcmCurrentData;}}。
经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序查找哪个按键被按下的方法为:一个一个地查找。
先第一行输出0,检查列线是否非全高;否则第二行输出0,检查列线是否非全高;否则第三行输出0,检查列线是否非全高;如果某行输出0时,查到列线非全高,则该行有按键按下;根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。
下面是具体程序:void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。
4*4矩阵键盘扫描程序/*设置行线为输入线,列线为输出线*/uchar KeyScan(); //按键扫描子程序void delay10ms(); //延时程序uchar key_free(); //等待按键释放程序void key_deal(); //键处理程序//主程序void main(){while(1){KeyScan();key_free();key_deal();}}//按键扫描子程序uchar KyeScan(){unsigned char key,temp;P1=0xF0;if(P1&0xF0!=0xF0){delay10ms(); //延时去抖动if(P1&0xF0!=0xF0){P1=0xFE; //扫描第一列temp=P1;temp=temp&0xF0;if(temp!=0xF0) //如果本列有键按下{switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=4;break;case 0xB0: //第三行有键按下key=8;break;case 0x70: //第四行有键按下key=12;break;}}P1=0xFD; //扫描第二列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=5;break;case 0xB0: //第三行有键按下key=9;break;case 0x70: //第四行有键按下key=13;break;}}P1=0xFb; //扫描第三列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=2;break;case 0xD0: //第二行有键按下key=6;break;case 0xB0: //第三行有键按下key=10;break;case 0x70: //第四行有键按下key=14;break;}}P1=0xF7; //扫描第四列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=3;break;case 0xD0: //第二行有键按下key=7;break;case 0xB0: //第三行有键按下key=11;break;case 0x70: //第四行有键按下key=15;break;}}}return(key);}}//延时程序void delay10ms(){unsigned char i,j;for(i=0;i<10;b++)for(j=0;j<120;j++)//延时1ms{}}//等待按键释放程序uchar key_free(){key=key_scan(); //取扫描到的键值P1=0xF0;//置行线全为高电平,列线全为低电平wheile(P1&0xF0!=0xF0) //如果仍有键按下{}return(key);//返回键值}51单片机矩阵键盘扫描、数码管显示键值实验/***********************************************程序名称:矩阵键盘扫描显示键值简要说明:P1口接矩阵键盘:低四位列,高四位行使用共阳型数码管:P0口输出数码管段码,P2口输出数码管位码编写:***********************************************/#include <AT89x52.h>#define uchar unsigned char;uchar key_val=0; //定义键值,初始默认为0uchar code TAB[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8 e}; //0~F共阳数码管显示段码/*****按键扫描*****/void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列{key_val = row*4 +col; // 获取键值,识别按键return; // 退出循环}tmp2*=2; // tmp2左移一位}}}}/*****主函数,显示键值*****/void main(){P2=0x00; //位码,这里全部置低,点亮8位数码管(见视频效果)while(1){Check_Key();P0=TAB[key_val]; //显示}}实验7 矩阵按键识别技术矩阵按键部分由16个轻触按键按照4行4列排列,连接到JP50端口。
单片机矩阵键盘行列扫描程序

//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍#include <>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=dofly[1];break;//1case 0x7b:P0=dofly[2];break;//2case 0x77:P0=dofly[3];break;//3case 0xbe:P0=dofly[4];break;//4case 0xbd:P0=dofly[5];break;//5case 0xbb:P0=dofly[6];break;//6case 0xb7:P0=dofly[7];break;//7case 0xde:P0=dofly[8];break;//8case 0xdd:P0=dofly[9];break;//9case 0xdb:P0=dofly[10];break;//acase 0xd7:P0=dofly[11];break;//bcase 0xee:P0=dofly[12];break;//ccase 0xed:P0=dofly[13];break;//dcase 0xeb:P0=dofly[14];break;//ecase 0xe7:P0=dofly[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖if(cord_h!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值 }}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。