电子琴C程序代码,四乘四矩阵键盘输入

合集下载

4×4矩阵键盘控制实验

4×4矩阵键盘控制实验

4×4矩阵键盘控制实验一、实验内容摘要设计一个4×4键盘接口控制器,在QuartusII软件上实现基设计,将其与开发板连接,实现电路功能。

当按下某一键时,4位LED上显示对应的键值,以二进制代码形式从0至F显示。

二、实验源代码LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;ENTITY DEBOUNCING ISPORT(clk, key:IN STD_LOGIC ;clr: IN STD_LOGIC;dly_out, dif_out: OUT STD_LOGIC);END DEBOUNCING;ARCHITECTURE a OF DEBOUNCING ISSIGNAL sample,dly,diff: STD_LOGIC;BEGINfree_counter:blocksignal QQ:std_logic_vector(4 downto 0);signal d0:std_logic;beginprocess (CLR,clk)beginif clr='0' thend0<='0';QQ<=(OTHERS=>'0');ELSif clk'event and clk='1' thend0<=QQ(4); --QQ的最高位同时作为d0信号,即d0的周期为2的5次方个clk.QQ<=QQ+1;end if;end process;sample<=not(QQ(4) and (not d0));--当d0为0,QQ(4)为1时,sample产生采样脉冲,低电平时间为1个clkend block free_counter;debunce:blocksignal d0,d1,s,r:std_logic;beginprocess(clk,clr)beginif clr='0' thendly<='0';elsif rising_edge(clk) thenif sample='1' thend1<=d0;d0<=key;s<=d0 and d1;r<=not d0 and not d1;if s<='0' and r<='0' thendly<=dly;elsif s<='0' and r<='1' thendly<='0';elsif s<='1' and r<='0' thendly<='1';elsedly<='0';end if;end if;end if;end process;dly_out<=dly;end block debunce;differential:blocksignal d1,d0:std_logic;beginprocess(clk,clr)beginif clr='0' thend0<='0';d1<='0';elsif rising_edge(clk) thend1<=d0;d0<=dly;end if;diff<=d0 and not d1;end process;dif_out<=diff;end block differential;END a;--****************************************************************** --* 4x4标准键盘板读取并点亮实验箱底板上的L1-L4--* Filename: keyboard4_4--* 扫描键盘,译码并点亮实验箱底板上的L1-L4--* 已加入去抖程序--****************************************************************** library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity keyboard4_4 isport(rst : in std_logic;clk_in : in std_logic;keyin : in std_logic_vector(3 downto 0);scan : out std_logic_vector(3 downto 0);leds : out std_logic_vector(3 downto 0);state : out std_logic;M : out std_logic_vector(3 downto 0));end keyboard4_4;architecture keyboard4_4_arch of keyboard4_4 is----********************************************* component debouncingport( key : IN STD_LOGIC ;clk,clr : IN STD_LOGIC ;dly_out : OUT STD_LOGIC ) ;end component ;--*********************************************--signal clkfrq : std_logic;signal cntscn : std_logic_vector(1 downto 0);signal scnlin : std_logic_vector(3 downto 0);signal cntfrq : std_logic_vector(14 downto 0);signal lednum : std_logic_vector(7 downto 0);signal key_tmp : std_logic_vector(3 downto 0);signal clk : std_logic;signal cntfrq1 : std_logic_vector(5 downto 0); beginM <= "0101"; --键盘功能选择scan <= not scnlin;lednum <= scnlin & (not key_tmp);-- key_tmp <= keyin;--debounuing cktdebounuing : blockbeginU1: debouncing PORT MAP (KEY => keyin(0) ,DLY_OUT => key_tmp(0) ,clr=>rst,clk => CLK);U2: debouncing PORT MAP (KEY => keyin(1) ,dly_out => key_tmp(1) ,clr=>rst,clk => CLK);U3: debouncing PORT MAP (key => keyin(2) ,dly_out => key_tmp(2) ,clr=>rst,clk => CLK);U4: debouncing PORT MAP (key => keyin(3) ,dly_out => key_tmp(3) ,clr=>rst,clk => CLK);END block debounuing ;--******************************************************--process(rst,clk_in) -- 晶振为40MHz,进行40000分频产生去抖时钟(1000Hz)beginif rst = '0' thencntfrq <= (others => '0');elsif rising_edge(clk_in) thenif (cntfrq = "100111000011111" or not (key_tmp="1110" or key_tmp="1101" or key_tmp="1011" or key_tmp="0111") ) then--if (cntfrq = "100111000011111" or key_tmp="1111" ) then--if cntfrq = "1111" thencntfrq <= (others => '0');clk <= not clk;--去抖时钟elsecntfrq <= cntfrq + 1;end if;end if;end process;process(rst,clk) --去抖时钟,50分频,形成扫描时钟beginif rst = '0' thenclkfrq <= '0';cntfrq1 <= (others => '0');elsif rising_edge(clk) thenif cntfrq1 = "11000" thencntfrq1 <= (others => '0');clkfrq <= not clkfrq;elsecntfrq1 <= cntfrq1 + 1;end if;end if;end process;process(rst,clkfrq) -- 根据扫描时钟产生扫描线beginif rst = '0' thencntscn <= "00";elsif rising_edge(clkfrq) thenif cntscn = "11" thencntscn <= "00";elsecntscn <= cntscn+1;end if;case cntscn iswhen "00" => scnlin <= "0001";when "01" => scnlin <= "0010";when "10" => scnlin <= "0100";when "11" => scnlin <= "1000";when others => null;end case;end if;end process;process(rst, clkfrq) -- 根据按键点亮相应的ledsbeginif(rst = '0' ) thenleds <= "0000";elsif clkfrq'event and clkfrq = '0' thencase lednum iswhen "10001000" =>leds <= "0001"; --1when "01001000" =>leds <= "0010"; --2when "00101000" =>leds <= "0011"; --3when "00011000" =>leds <= "1010"; --Awhen "10000100" =>leds <= "0100"; --4when "01000100" =>leds <= "0101"; --5when "00100100" =>leds <= "0110"; --6when "00010100" =>leds <= "1011"; --Bwhen "10000010" =>leds <= "0111"; --7when "01000010" =>leds <= "1000"; --8when "00100010" =>leds <= "1001"; --9when "00010010" =>leds <= "1100"; --Cwhen "10000001" =>leds <= "1110"; --*when "01000001" =>leds <= "0000"; --0when "00100001" =>leds <= "1111"; --#when "00010001" =>leds <= "1101"; --Dwhen others =>null;end case;end if;end process;process(rst,key_tmp)beginif(rst = '0' ) thenstate <= '1';elsif (key_tmp="1110" or key_tmp="1101" or key_tmp="1011" or key_tmp="0111") thenstate <= '0';elsif (key_tmp="1111") thenstate <= '1';end if;end process;end keyboard4_4_arch;三、实验工具软件的选用以及实验过程1、打开QuartusII软件。

电子琴C程序代码,四乘四矩阵键盘输入

电子琴C程序代码,四乘四矩阵键盘输入

电子琴C程序代码,四乘四矩阵键盘输入#include <reg52.h>#define uchar unsigned char #define uint unsigned intsbit duan=P 2八6;sbit wei=P 2八7;sbit bee=P 2八3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar code tablewe[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};uchar disp[16]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; // 在里面输入按下键值为0~15 对应要显示的第一位码值uchar disp1[16]={0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x3f}; // 在里面输入按下键值为0~15 对应要显示的第二位码值unsigned char temp;unsigned char key;unsigned char i,j;unsigned char STH0;unsigned char STL0;unsigned int code tab[]={//63625, 63833, 64019, 64104, 64260, 64400, 64524 ,// 低音区:1 2 3 464580, 64685, 64778, 64820, 64898, 64968, 65030 ,// 中音区:1 2 3 4 5 65058, 65110, 65157, 65178, 65217, 65252, 65283 ,// 高音区:1 2 3 4 565297 ,// 超高音:1 }; // 音调数据表可改void delay(uchar x)uchar y,z;for(y=x;y>0;y--)for(z=0;z<110;z++);void init()TMOD=0x01;ET0=1;EA=1;void display() {for(i=0;i<2;i++)P0=tablewe[i];wei=1;wei=0;if(i==0)P0=disp[key];elseP0=disp1[key]; duan=1;duan=0;delay(4);void main(void) { init();while(1)P3=0xef;temp=P3;temp=temp & 0x0f; if (temp!=0x0f)delay(5);temp=P3;temp=temp & 0x0f; if (temp!=0x0f)temp=P3;temp=temp & 0x0f; switch(temp)case 0x0e:key=0;break;case 0x0d:key=1;break;case 0x0b:key=2;break;case 0x07:key=3;break;temp=P3;STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;temp=temp & 0x0f; while(temp!=0x0f)display();temp=P3;temp=temp & 0x0f;P3=0xdf;temp=P3;temp=temp & 0x0f; if (temp!=0x0f)delay(5);temp=P3;temp=temp & 0x0f; if (temp!=0x0f)temp=P3;temp=temp & 0x0f; switch(temp)key=4;case 0x0e:break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;temp=P3;STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;temp=temp & 0x0f; while(temp!=0x0f)display();temp=P3;temp=temp & 0x0f;}P3=0xbf;temp=P3;temp=temp & 0x0f; if (temp!=0x0f)delay(5);temp=P3;temp=temp & 0x0f; if (temp!=0x0f)temp=P3;temp=temp & 0x0f; switch(temp)case 0x0e:key=8;break;case 0x0d:key=9;break;case 0x0b:key=10;break;case 0x07:key=11;break;temp=P3;STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;temp=temp & 0x0f; while(temp!=0x0f)display();temp=P3;temp=temp & 0x0f;P3=0x7f;temp=P3;temp=temp & 0x0f; if (temp!=0x0f)delay(5);temp=P3;temp=temp & 0x0f; if (temp!=0x0f)temp=P3;temp=temp & 0x0f; switch(temp)case 0x0e:key=12;break;case 0x0d:key=13;break;case 0x0b:key=14;break;case 0x07:key=15;break;temp=P3;STH0=tab[key]/256; STL0=tab[key]%256;TR0=1;temp=temp & 0x0f;while(temp!=0x0f)display();temp=P3;temp=temp & 0x0f;bee=1;TR0=0;display();void t0(void) interrupt 1 using 0TH0=STH0;TL0=STL0;bee=~bee;}。

实验四4×4键盘输入

实验四4×4键盘输入

实验四: 4 × 4键盘输入实验一、实验目的:1.学习非编码键盘的工作原理和键盘的扫描方式。

2.学习键盘的去抖方法和键盘应用程序的设计。

二、实验原理:键盘是单片机应用系统接受用户命令的重要方式。

单片机应用系统一般采用非编码键4*4矩阵盘,需要由软件根据键扫描得到的信息产生键值编码,以识别不同的键。

本板采用键盘,行信号分别为P1.0-P1.3 ,列信号分别为P1.4-P1.7 。

具体电路连接见下图对于键的识别一般采用逐行(列)扫描查询法,判断键盘有无键按下,由单片机I/O口向键盘送全扫描字,然后读入列线状态来判断。

程序及流程图:ORG 0000HAJMP MAINORG 0000HAJMP MAINORG 0030HMAIN:MOV P2,#0F7HMOV P1,#0F0HMOV R7,#100DJNZ R7,$MOV A,P1ANL A,#0F0HXRL A,#0F0HJZ MAINLCALL D10MSMOV A,#00HMOV R0,AMOV R1,AMOV R2,#0FEH SKEY0:MOV A,R2MOVP1,AMOVR7,#10DJNZ R7,$MOVA,P1ANLA,#0F0HXRLA,#0F0HJNZ LKEYINC R0MOVA,R2RL AMOVR2,AMOVA,R0CJNE A,#04H,SKEY0AJMP MAIN LKEY:JNB ACC,4,NEXT1MOVA,#00HMOVR1,AAJMP DKEYNEXT1:JNB ACC.5,NEXT2MOVA,#01HMOVR1,AAJMP DKEYNEXT2:JNB ACC.6,NEXT3MOVA,#02HMOVR1,AAJMP DKEYNEXT3:JNB ACC.7,MAINMOVA,#03HMOVR1,AAJMP DKEY DKEY:MOV A,R0MOVB,#04HMULABADDA,R1AJMP SQRSQR:MOVDPTR,#TABMOVC A,@A+DPTRMOVP0,AAJMP MAINTAB:DB0C0H,0F9H,0A4H,0B0H,99H, 92H, 82H, 0F8H DB 80H, 90H, 88H, 83H, 0C6H,0A1H,86H, 8EH D10MS:MOV R6,#10L1:MOV R5,#248DJNZ R5,$DJNZ R6,L1RETEND流程图:结束三、思考题:总结 FPGA是如何识别按键的?与单片机读取键值有何不同?答:FPGA的所有 I/O 控制块允许每个 I/O 引脚单独配置为输入口 , 不过这种配置是系统自动完成的。

4×4 矩阵式键盘识别技术

4×4 矩阵式键盘识别技术
L A,#0FH XRL A,#0FH JZ NOKEY4 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK13 MOV KEYBUF,#12 LJMP DK4 NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13 LJMP DK4 NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14 LJMP DK4 NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15 LJMP DK4 NK16: NOP DK4: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A
汇编程序设计
MOV A,P3 ANL A,#0FH XRL A,#0FH JZ NOKEY2 MOV A,P3 ANL A,#0FH CJNE A,#0EH,NK5 MOV KEYBUF,#4 LJMP DK2 NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5 LJMP DK2 NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6 LJMP DK2 NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7 LJMP DK2 NK8: NOP DK2: MOV A,KEYBUF MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A
图1 按键序号排列
硬件电路原理图
P3.4 P3.3 P3.5 P3.6 P3.7 图2 P3.2 P3.1 P3.0
硬件设计
在Protues中设计出硬件电路图,连线方法如下: (1)把单片机的P3.0-P3.7 端口连接到“4X4 行列式键盘”区域中的C1-C4 R1-R4 端口 上; (2)把单片机系统的P0.0/AD0-P0.7/AD7 端 口连接到 7段LED的中的a-h 端口上;要求: P0.0/AD0对应着a,P0.1/AD1 对应着b,……, P0.7/AD7 对应着h。

基于51单片机的4×4矩阵键盘电子琴

基于51单片机的4×4矩阵键盘电子琴

基于51单片机的4×4矩阵键盘电子琴基于51单片机的4×4矩阵键盘电子琴前些日子,做而论道写了一篇关于单片机发音的文章,后来,就不断有网友来电询问单片机电子琴的设计方法。

以前制作过一个24键(独立按键)的,程序是用汇编语言写的,估计多数人看不了。

下面,把新设计的16按键的电子琴,公布给网友。

电路图如下:图片链接:/picture/detail/b05f67dd8b5c82da3af4 83a4f974902b5660a0da制作说明:单片机采用51系列的都行,AT89C2051也可;图中没有画出复位和晶振电路,实际制作时,不可省略,晶振可以使用11.0592或12MHz;扬声器应该按照图中给出的附图加上驱动电路;显示器及七段译码器不接,单片机电子琴也可以正常工作。

74LS47 和数码管之间,应该接上“限流电阻”,约470 欧姆即可。

C语言程序如下:/************************************************************* * 程序功能 : 对4×4矩阵键盘进行扫描,显示键值和输出音响**************************************************************/ #include <reg51.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit SPK = P3^7; //P3.7外接扬声器uint FreqTemp;unsigned int code Freqtab[] = { //定时半周期的初始值64021,64103,64260,64400, //低音3 4 5 664524,64580,64684,64777, //低音7,中音1 2 364820,64898,64968,65030, //中音4 5 6 765058,65110,65157,65178}; //高音1 2 3 4//关于半周期的初始值与频率的关系,可见:///do_sermon/item/8cff22baf5142245bb 0e1247/************************************************************* * 函数功能 : 用扫描法读 P1 外接4×4 键盘* 函数返回 : 按下键:返回0~15、如无键按下:返回16**************************************************************/ uchar Keyscan(void){uchar i, j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};for(j = 0; j < 4; j++) { //循环四次,扫描四行P1 = Buffer[j]; //在低四位分别输出一个低电平_nop_();temp = 0x80; //计划先读出P1.7位for(i = 0; i < 4; i++) { //循环四次,检查四列if(!(P1 & temp)) { //从高四位,截取1位return (i + j * 4); //返回取得的按键值}temp >>= 1; //换右边一位} }return 16; //没有键按下就返回16}/************************************************************** * 函数功能 : 将参数分成十位、个位,分别显示到P2* 输入 : k (键盘数值)*************************************************************** /void Display(uchar k){P2 = ((k / 10) << 4) + (k % 10);}/************************************************************** * 主函数*************************************************************** /void Main(void){uchar Key_Value = 16, Key_Temp1, Key_Temp2;//读出的键值TMOD = 0x01; //T0定时方式1ET0 = 1; //允许T0中断EX0 = 1; //允许X0中断EA = 1;while(1) {TR0 = 0; //暂不发音Key_T emp1 = Keyscan(); //读入按键if(Key_Temp1 != 16) { //有键按下Display(Key_Value); //显示键值、延时消抖Key_T emp2 = Keyscan(); //再读一次if (Key_Temp1 == Key_T emp2) {//两次相等Key_Value = Key_T emp1; //就确认下来FreqTemp = Freqtab[Key_Value]; //根据键值,取出定时半周期的初始值Display(Key_Value); //显示TR0 = 1; //启动定时器,发音while (Keyscan() < 16); //等待释放SPK = 1; //停止发音} } } }//===================================== ==========void T0_INT(void) interrupt 1{TL0 = FreqTemp; //载入定时半周期的初始值TH0 = FreqTemp >> 8;SPK = ~SPK; //发音}//===================================== ==========#单片机有关。

4X4矩阵式键盘输入程序

4X4矩阵式键盘输入程序

4*4 键盘程序readkeyboard: orl a,#0f0h mov a, r2begin: acall key_on mov r6,a swap a jnz delay cpl a add a,r3ajmp readkeyboard jz next retdelay:acall delay10ms ajmp key_c key_ccode:push a acall key_on next: mov a,r7 swap ajnz key_num jnb acc.7,error anl a,#0fhajmp begin rl a dec akey_num:acall key_p mov r7,a rl a ; 行号乘anl a,#0FFh ajmp l_loop 4jz begin error:mov a,#00h rl aacall key_ccode ret mov r7,apush a key_c:mov r2,#00h pop akey_off:acall key_on mov r3,#00h anl a,#0fh jnz key_off mov a,r6 dec apop a mov r5,#04h add a,r7ret again1:jnb acc.0,out1retkey_on: mov a,#00h rr a delay10ms: orl a,#0fh inc r2 anl tmod,#0f0h mov p1,a djnz r5, again1 orl tmod,#01h mov a,p1 out1: inc r2 mov th0,#0d8h orl a,#0f0h mov a,r7 mov tl0,#0f0h cpl a mov r5,#04h setb tr0ret again2:jnb acc.4,out2wait:jbc tf0,overkey_p: mov r7,#0efh rr a ajmp waitl_loop:mov a,r7 inc r3 clr tr0 mov p1,amov a,p1 djnz r5,again2out2: inc r3 单片机键盘设计over:ret二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。

4×4矩阵键盘数码管显现按键值程序

4×4矩阵键盘数码管显现按键值程序

4×4矩阵键盘数码管显现按键值程序4;x;4矩阵键盘数码管显现按键值程序//电路阐明如下。

//单片机:运用51系列兼容的即可;//4;x;4矩阵键盘:接在P1口;//两位数码显现器:P0口输出七段码,P2口输出位选码。

//===================================================== =========//C言语程序如下。

/****************************************************** ********文件名:KEY_LED.c*功用:对4;x;4矩阵键盘进行输出,在数码管后两位显现按键值。

******************************************************* *******/#includelt;reg51.h#includelt;intrins.h#defineuintunsignedint#defineucharunsignedchar//ucharcodetable[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x 01,0x09};ucharcodetable[10]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x8 0,0x90};/****************************************************** *********称谓:Delay_1ms()*功用:延时子程序,延时时刻为1ms*x*输入:x(延时一毫秒的个数)*输出:无******************************************************* ********/voidDelay_1ms(uintx){uinti;ucharj;for(i=0;ilt;x;i++)for(j=0;jlt;=148;j++);}/*******************************************************称谓:Keyscan()*功用:P1外接4;x;4按键,依照扫描法读出键值*输出:按键值0~15/如无键按下,回来16******************************************************* ********/ucharKeyscan(void){uchari,j,temp,Buffer[4]={0xef,0xdf,0xbf,0x7f};for(j=0;jlt;4;j++){//循环四次P1=Buffer[j];//在P1高四位别离输出一个低电平temp=0x01;//方案先判别P1.0位for(i=0;ilt;4;i++){//循环四次if(!(P1temp))//从P1低四位,截取1位return(i+j*4);//回来获得的按键值templt;lt;=1;//判别的位,左移一位}}return16;//判别完毕,没有键按下,回来16}//哈哈,实质性的句子不过8行,即是这么简练!/*******************************************************称谓:Display(uchark)*功用:将参数分红十位、个位别离显现*输入:k(键盘数值)*输出:P0口输出七段码,P2口输出位选码******************************************************* ********/voidDisplay(uchark){P2=0;//消隐P0=table[k/10];P2=0x02;Delay_1ms(5);//显现5ms十位P2=0;//消隐P0=table[k%10];P2=0x01;Delay_1ms(5);//显现5ms个位}/****************************************************** *********称谓:Main()*功用:主函数******************************************************* ********/voidMain(void){ucharKey_Value=16,Key_Temp1,Key_Temp2;//两次读出的键值while(1){//---------以下读入按键、消抖、等候按键开释P1=0xff;Key_Temp1=Keyscan();//先读入按键if(Key_Temp1!=16){//假如有键按下//Delay_1ms(10);//延时一下Display(Key_Value);//可用显现替代延时Key_Temp2=Keyscan();//再读一次按键if(Key_Temp1==Key_Temp2){//有必要是两次持平Key_Value=Key_Temp1;//才保留下来,这即是消除颤动while(Keyscan()lt;16)//等候按键开释Display(Key_Value);//等候时期显现键值//---------以下是对按键的处理Display(Key_Value);//显现键值}}Display(Key_Value);//没有按键按下,也显现键值}}//用PROTEUS仿真作业时的屏幕截图如下:。

4乘4矩阵键盘总结

4乘4矩阵键盘总结

|
39 //
|
40 //
|
41 // P X.0 ----------|------|-----|-----|
42 //
43 //************************************************************
44 // 扫描方法二: 06.8.15 添加 4X4 矩阵键盘线翻转识别法函数
0xe7,0xeb,0xed,0xee
58 //
|
|||
59 //
|
|||
60 // P X.3 ----------|
|||
61 //
|||
62 //
|||
63 // P X.2 ----------|------|
|
|
64 //
||
65 //
||
66 // P X.1 ----------|------|-----|
//计算识别码的算法,灵活性很大。
142
return ((~uc_Temp_1)+(~uc_Temp_2)); //返回识别码,识
143 一个按键,一共有 16 个识别码。
144
}
145
else
//否则依次将第二,第三,第四行拉低
146
{
147
uc_Temp_1>>=1;
01111111 00111111
|
67 //
|
68 //
|
69 // P X.0 ----------|------|-----|-----|
70 //
71
72 //*****************************************************************

4×4矩阵按键

4×4矩阵按键
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=13;
break;
case 0xd7:num=14;
break;
case 0xb7:num=15;
DQ = 1; //释放总线
dat>>=1; //移入下一位
}
}
void temperature_read(void)
{
//unsigned int t;
ds18b20_init();
if(presence==0) //器件应答
{
ds18b20_write(0xCC); //跳过读序号列号的操作
ds18b20_write(0x44);//启动温度转换
lcden=1; //开使能
delayms(5); //读取数据
lcden=0;//关闭使能
}
//**********LCD初始化函数开始*********
void lcd_initialize()
{
lcden=0;
write_com(0x38); //设置16x2显示,5x7点阵显示,8位数据接口
{
unsigned char i=0,dat=0;
for (i=8;i>0;i--)
{
DQ = 0; //给脉冲信号
dat>>=1; //移入一位
DQ = 1; //释放总线
if(DQ)
dat|=0x80; //写入1

4×4矩阵键盘扫描

4×4矩阵键盘扫描

矩阵键盘(Verilog)module matrixKeyboard_drive(input i_clk,input i_rst_n,input [3:0] row, // 矩阵键盘行output reg [3:0] col, // 矩阵键盘列output reg [3:0] keyboard_val // 键盘值);//++++++++++++++++++++++++++++++++++++++// 分频部分开始//++++++++++++++++++++++++++++++++++++++reg [19:0] cnt; // 计数子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire key_clk = cnt[19]; // (2^20/50M = 21)ms //--------------------------------------// 分频部分结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 状态机部分开始//++++++++++++++++++++++++++++++++++++++// 状态数较少,独热码编码parameter NO_KEY_PRESSED = 6'b000_001; // 没有按键按下parameter SCAN_COL0 = 6'b000_010; // 扫描第0列parameter SCAN_COL1 = 6'b000_100; // 扫描第1列parameter SCAN_COL2 = 6'b001_000; // 扫描第2列parameter SCAN_COL3 = 6'b010_000; // 扫描第3列parameter KEY_PRESSED = 6'b100_000; // 有按键按下reg [5:0] current_state, next_state; // 现态、次态always @ (posedge key_clk, negedge i_rst_n)if (!i_rst_n)current_state <= NO_KEY_PRESSED;elsecurrent_state <= next_state;// 根据条件转移状态always @ *case (current_state)NO_KEY_PRESSED : // 没有按键按下if (row != 4'hF)next_state = SCAN_COL0;elsenext_state = NO_KEY_PRESSED;SCAN_COL0 : // 扫描第0列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL1;SCAN_COL1 : // 扫描第1列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL2;SCAN_COL2 : // 扫描第2列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL3;SCAN_COL3 : // 扫描第3列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = NO_KEY_PRESSED;KEY_PRESSED : // 有按键按下if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = NO_KEY_PRESSED;endcasereg key_pressed_flag; // 键盘按下标志reg [3:0] col_val, row_val; // 列值、行值// 根据次态,给相应寄存器赋值always @ (posedge key_clk, negedge i_rst_n)if (!i_rst_n)begincol <= 4'h0;key_pressed_flag <= 0;endelsecase (next_state)NO_KEY_PRESSED : // 没有按键按下begincol <= 4'h0;key_pressed_flag <= 0; // 清键盘按下标志endSCAN_COL0 : // 扫描第0列col <= 4'b1110;SCAN_COL1 : // 扫描第1列col <= 4'b1101;SCAN_COL2 : // 扫描第2列col <= 4'b1011;SCAN_COL3 : // 扫描第3列col <= 4'b0111;KEY_PRESSED : // 有按键按下begincol_val <= col; // 锁存列值row_val <= row; // 锁存行值 key_pressed_flag <= 1; // 置键盘按下标志endendcase//--------------------------------------// 状态机部分结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 扫描行列值部分开始//++++++++++++++++++++++++++++++++++++++always @ (posedge key_clk, negedge i_rst_n)if (!i_rst_n)keyboard_val <= 4'h0;elseif (key_pressed_flag)case ({col_val, row_val})8'b1110_1110 : keyboard_val <= 4'h0;8'b1110_1101 : keyboard_val <= 4'h4;8'b1110_1011 : keyboard_val <= 4'h8;8'b1110_0111 : keyboard_val <= 4'hC;8'b1101_1110 : keyboard_val <= 4'h1;8'b1101_1101 : keyboard_val <= 4'h5;8'b1101_1011 : keyboard_val <= 4'h9;8'b1101_0111 : keyboard_val <= 4'hD;8'b1011_1110 : keyboard_val <= 4'h2;8'b1011_1101 : keyboard_val <= 4'h6;8'b1011_1011 : keyboard_val <= 4'hA;8'b1011_0111 : keyboard_val <= 4'hE;8'b0111_1110 : keyboard_val <= 4'h3;8'b0111_1101 : keyboard_val <= 4'h7;8'b0111_1011 : keyboard_val <= 4'hB;8'b0111_0111 : keyboard_val <= 4'hF;endcase//--------------------------------------// 扫描行列值部分结束//--------------------------------------endmodule。

4×4键盘扫描程序

4×4键盘扫描程序

键盘程序假设P2.0-P2.3为H0-H3,P2.4-P2.7为L0-L3 (列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先,行为P2口的低四位,而列为高四位。

P0口为数码管输出口。

第一种思路就是逐行逐列判断法。

#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar code table[17] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//八段数码管对应0-F值. uchar temp;void Delay_1ms(uint i)//1ms延时{uint x, j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}void delay()//消除按键抖动延时{int i,j;for(i=0; i<=10; i++)for(j=0; j<=2; j++);}uchar Keyscan(void){uchar i,j,row,col;temp=P2&0xf0;for(i=0; i<4; i++){if(!(temp&(0x10<<i)))row=i;}P2=0x0f;temp=P2&0x0f;for(j=0; j<4; j++){if(!(temp&(0x01<<j)))col=j;}return (row+col*4);}void Main(void){uchar Key_Value=16; //读出的键值uchar i=0;while(1){P2 = 0xf0;temp=P2;if(temp != 0xf0){Delay_1ms(80); //按键消抖if(temp != 0xf0){Key_Value = Keyscan();}Delay_1ms(350); //按键消抖}P0 = table[Key_Value];//P0口输出数据到数码管}次读取结果组合起来就可以得到当前按键的特征编码。

4乘4矩阵键盘检测

4乘4矩阵键盘检测
#include <reg51.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int
sbit p2_7 = P2^7 ;
unsigned char const table[]={
0x06,0x5b,0x3f,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
{
uchar cord_h,cord_l;//行列值
P1=0x0f; //行线输出全为0
cord_h=P1&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P1&0x0f; //读入列线值
temp=table[13];
break;//d
case 0xeb:
temp=table[14];
break;//e
case 0xe7:
temp=table[15];
break;//f
}
if (p2_7==0)//确认键
{
P0 = temp;
}
}
}
uchar keyscan(void)//键盘扫描函数
0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F
uchar temp;
uchar keyscan(void);
void delay(uint i);
void main()
{
uchar key;
P0=0x049;//1数码管亮按相应的按键,会显示按键上的字符

单片机-4x4个矩阵按键控制数码管显示数字程序

单片机-4x4个矩阵按键控制数码管显示数字程序

单⽚机-4x4个矩阵按键控制数码管显⽰数字程序1 #include "8051.h"2 typedef unsigned char u8;3 typedef unsigned int u16;4 u8 smgduan[]= {5/*0 1 2 3 4 5 6 7 */60x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,7/*8 9 A B C D E F */80x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};910// P0⼝为数码管的位选的8位输⼊引脚11// P0 = 0x00;121314void Delayms(u16 ms);15void shumaguan(u8 n);16void DigDisplay();17void KeyTest();18void smg(u8 n, u8 m);19void key_4x4();2021void main()22 {23while(1)24 {25 key_4x4();26 }27 }2829// 不精确的延时函数30void Delayms(u16 ms)31 {32 unsigned int i, j;33for(i = ms; i > 0; i--)34for(j = 110; j > 0; j--);35return;36 }3738// 数码管根据74HC138译码器选择对应的段(选择哪个数码管显⽰)39void shumaguan(u8 n)40 {41switch(n)42 {43case0:44 LSA = 0;LSB = 0;LSC = 0;break;45case1:46 LSA = 1;LSB = 0;LSC = 0;break;47case2:48 LSA = 0;LSB = 1;LSC = 0;break;49case3:50 LSA = 1;LSB = 1;LSC = 0;break;51case4:52 LSA = 0;LSB = 0;LSC = 1;break;53case5:54 LSA = 1;LSB = 0;LSC = 1;break;55case6:56 LSA = 0;LSB = 1;LSC = 1;break;57case7:58 LSA = 1;LSB = 1;LSC = 1;break;59 }60 }6162// 数码管显⽰数字,并以⼗进制递增63void DigDisplay()64 {65 u8 i1 = 0;66 u8 i2 = 0;67 u8 i3 = 0;68 u8 i4 = 0;69 u8 i5 = 0;70 u8 i6 = 0;71 u8 i7 = 0;72 u8 i8 = 0;7374757677for (i8 = 0; i8 < 10; i8++)78for (i7 = 0; i7 < 10; i7++)79for (i6 = 0; i6 < 10; i7++)80for (i5 = 0; i5 < 10; i5++)81for (i4 = 0; i4 < 10; i4++)82for (i3 = 0; i3 < 10; i3++)83for (i2 = 0; i2 < 10; i2++)84for (i1 = 0; i1 < 10; i1++)85 {86 u16 cnt = 10;87while (cnt--)88 {89 shumaguan(0); //选中第⼀个数码管90 P0 = smgduan[i1]; //给他送⼀个数字91 Delayms(1); //稍微延时⼀下下92 shumaguan(1); //然后切换到第⼆个数码管。

4x4键盘(任意同时按键按下有效)扫程序-数码管显示键值

4x4键盘(任意同时按键按下有效)扫程序-数码管显示键值
case 16:if(col3==0) key=15;n=1;break;
}
}
void main()
{
unsigned char i, key_key[16];
while(1)
{
for(i=0;i<16;i++)
{
key_4x4();
duan_xuan();_xuan();
}
}
for(i=x;i>0;--i)
for(j=114;j>0;--j);
}
void duan_xuan()
{
wr=0; //时钟输入端WR置低电平
cs1=0;//cs1为低电平选通段码锁存IC
wr=1; //时钟输入端WR置高电平,WR得到上升沿
cs1=1;//cs1为高电平,段码锁存IC锁存输出保持不变
case 4:if(col3==0) key=3;n=5;break;
case 5:row1=0;row0=1;if(col0==0) key=4;n=6;break;
case 6:if(col1==0) key=5;n=7;break;
case 7:if(col2==0) key=6;n=8;break;
{
static unsigned char n=1;
// P2=0XFF;
switch(n)
{
case 1:row0=0;row3=1;if(col0==0) key=0;n=2;break;
case 2:if(col1==0) key=1;n=3;break;
case 3:if(col2==0) key=2;n=4;break;

4X4键盘多功能电子琴

4X4键盘多功能电子琴
for(i=0;i<16;i++)
{
send_data(shu[i]);
//delay(10);
}
}
if(sound_add==40 )
{
send_command(0x80);
{
uint i;
US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
for( i=0;i<US;i++);
}
/************************************************
*函数名称: void Delayms(uint16 MS)
0x2b,0x4a,0x28,0x28,0x69,0x29,0x49,0x29,0x28,
0x46,0xc6, 0x87,0x67,0x26,0x45,0x4d,0x4c,0x29,0x29,
0x6b,0x2b,0x4b,0x2a,0x29,0xfc,
0x00};
#define TI 64522 //988
#define DO_H 64578 //1046
#define RE_H 64683 //1174
#define MI_H 64776 //1318
#define FA_H 64819 //1397
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04; //timer interrupt sources
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

电子琴C程序代码,四乘四矩阵键盘输入#include <reg52.h>
#define uchar unsigned char #define uint unsigned int
sbit duan=P2^6;
sbit wei=P2^7;
sbit bee=P2^3;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code tablewe[]={
0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe};
uchar disp[16]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}; // 在里面输入按下键值为0~15对应要显示的第一位码值 uchar disp1[16]={0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x3f}; // 在里面输入按下键值为0~15对应要显示的第二位码值 unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char STH0;
unsigned char STL0;
unsigned int code tab[]={
//63625, 63833, 64019, 64104, 64260, 64400, 64524 ,//低音区:1 2 3 4 5 6 7
64580, 64685, 64778, 64820, 64898, 64968, 65030 ,//中音区:1 2 3 4 5 6 7
65058, 65110, 65157, 65178, 65217, 65252, 65283 ,//高音区:1 2 3 4 5 6 7
65297 ,//超高音:1 }; //音调数据表可改
void delay(uchar x)
{
uchar y,z;
for(y=x;y>0;y--)
for(z=0;z<110;z++);
}
void init()
{
TMOD=0x01;
ET0=1;
EA=1;
}
void display() {
for(i=0;i<2;i++)
{
P0=tablewe[i]; wei=1;
wei=0;
if(i==0)
P0=disp[key]; else
P0=disp1[key]; duan=1;
duan=0;
delay(4);
}
}
void main(void) { init();
while(1)
{
P3=0xef;
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
delay(5);
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
temp=P3;
temp=temp & 0x0f; switch(temp)
{
case 0x0e:
key=0;
break;
case 0x0d:
key=1;
break;
case 0x0b:
key=2;
break;
case 0x07:
key=3;
break;
}
temp=P3;
STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;
temp=temp & 0x0f; while(temp!=0x0f) {
display();
temp=P3;
temp=temp & 0x0f; }
}
}
P3=0xdf;
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
delay(5);
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
temp=P3;
temp=temp & 0x0f; switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=6;
break;
case 0x07:
key=7;
break;
}
temp=P3;
STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;
temp=temp & 0x0f; while(temp!=0x0f) {
display();
temp=P3;
temp=temp & 0x0f; }
}
}
P3=0xbf;
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
delay(5);
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
temp=P3;
temp=temp & 0x0f; switch(temp)
{
case 0x0e:
key=8;
break;
case 0x0d:
key=9;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=11;
break;
}
temp=P3;
STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;
temp=temp & 0x0f; while(temp!=0x0f) {
display();
temp=P3;
temp=temp & 0x0f; }
}
}
P3=0x7f;
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
delay(5);
temp=P3;
temp=temp & 0x0f; if (temp!=0x0f) {
temp=P3;
temp=temp & 0x0f; switch(temp)
{
case 0x0e:
key=12;
break;
case 0x0d:
key=13;
break;
case 0x0b:
key=14;
break;
case 0x07:
key=15;
break;
}
temp=P3;
STH0=tab[key]/256; STL0=tab[key]%256; TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
display();
temp=P3;
temp=temp & 0x0f;
}
}
}
bee=1;
TR0=0;
display();
}
}
void t0(void) interrupt 1 using 0 {
TH0=STH0;
TL0=STL0;
bee=~bee;
}。

相关文档
最新文档