自己写的按键单片机程序
基于51单片机的数码管及键盘程序
/*本程序功能:4*4按键,其中四个按键组成独立键盘,有加一减一和定时功能;另外十二个按键组成矩阵键盘,显示相应的编号。
*/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};/*sbit key7=P3^7;sbit key6=P3^6;sbit key5=P3^5;sbit key4=P3^4;sbit key3=P3^3;sbit key2=P3^2;sbit key1=P3^1;sbit key0=P3^0;*/uchar temp,num,shi,ge;void delay(uint tms){uint i,j;for(i=tms;i>0;i--)for(j=110;j>0;j--);}void display(){shi=num/10;ge=num%10;P2=wei[2];P0=~duan[shi];P2=wei[3];P0=~duan[ge];delay(2);}/*void keyscan() //法①{key0=0;if(key4==0)P0=~duan[0];else if(key5==0)P0=~duan[4];else if(key6==0)P0=~duan[8];else if(key7==0)P0=~duan[12];delay(2);key0=1;key1=0;if(key4==0)P0=~duan[1];else if(key5==0)P0=~duan[5];else if(key6==0)P0=~duan[9];else if(key7==0)P0=~duan[13];delay(2);key1=1;if(key4==0)P0=~duan[2];else if(key5==0)P0=~duan[6];else if(key6==0)P0=~duan[10];else if(key7==0)P0=~duan[14];delay(2);key2=1;key3=0;if(key4==0)P0=~duan[3];else if(key5==0)P0=~duan[7];else if(key6==0)P0=~duan[11];else if(key7==0)P0=~duan[15];delay(2);key3=1;//这一句很重要,不要漏写}*/void init_t0()//法二{TMOD=0x01;TH0=(65536-46083)/256;TL0=(65536-46083)%256;EA=1;ET0=1;//TR0=1;}void timer0() interrupt 1{uchar count;TH0=(65536-46083)/256;TL0=(65536-46083)%256;count++;if(count==20){count=0;num++;if(num==60)num=0;}}void keyscan(){P1=0xfe;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;temp=temp&0xf0;delay(10);if(temp!=0xf0){temp=P1;switch(temp){case 0xee:num++;/* while(temp==0xee){temp=P1;}*/ //这几条语句也可用于检测按键是否释放;若没有temp=P1,则不正确break;case 0xde:if(num==0)num=60;num--;// while(temp!=0xde);break;case 0xbe:num=0;// while(temp!=0xbe);break;case 0x7e:TR0=~TR0;// while(temp==0x7e);break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xed:num=1;break;case 0xdd:num=5;break;case 0xbd:num=9;break;case 0x7d:num=13;break;}}P1=0xfb;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xeb:num=2;break;case 0xdb:num=6;break;case 0xbb:num=10;break;case 0x7b:num=14;break; }}P1=0xf7;temp=P1;temp=temp&0xf0;if(temp!=0xf0){temp=P1;switch(temp){case 0xe7:num=3;break;case 0xd7:num=7;break;case 0xb7:num=11;break;case 0x77:num=15;break; }}}void main(){init_t0();while(1){keyscan();display();}}。
单片机按键程序的编写
一般情况下,如果多个按键每个都直接接在单片机的 I/O 上的话会占用很多的 I/O 资源。比 较合理的一种做法是,按照行列接成矩阵的形式。按键接在每一个的行列的相交处。这样对 于 m 行 n 列的矩阵,可以接的按键总数是 m*n。这里我们以常见的 4*4 矩阵键盘来讲解矩阵 键盘的编程。
/******************************************
* 此模块所需相关支持库
*
******************************************/
#include"regx52.h"
#define uint8 unsigned char
#define uint16 unsigned int
bit bdata StartScan = 0 ;//此变量需放在定时中断中置位
else
{
//SHOW_ICON
}
}
}
每次执行读键盘函数时,只是对一些标志进行判断,然后退出。因此能够充分的利用 CPU 的资源。同时可以处理连发按键。此按键扫描按键函数可以直接放在主函数中。如果感觉按 键太过灵敏或者迟钝则改一下相关消抖动的宏定义即可。此函数也可以通过中断标志位进行 定时的扫描。此时,需要添加一个定时标志位,并将相关消抖动的和连击时间的宏定义改小 即可。然后在主程序类似下面这样写即可
这个流程是好多教科书上的做法。可惜,误导了好多人。为什么呢。因为它根本就没有考虑 实际情况。我们根据这幅流程图来写它的代码看看。
unsigned char v_ReadKey_f( void )
{
unsigned char KeyPress ;
51单片机使用状态机的键盘程序
}
default://其它
{
step = _Key1_up;//单键抬起消抖
#define Key_Down 0x3D //下箭头
#define Key_Add 0x3B //加
#define Key_Sub 0x37 //减
#define Key_Enter 0x2F //回车
传入参数:无
返回参数:无
设 计:莫汉伟 amo73@
修改日期:2007-10-12
备 注:详细功能和处理算法请参照本文件相关的流程图和文档
**************************************************************************/
#define KeyBuffLen 8 //定义键值环形缓冲区长度为8(缓冲区大小可自由定义,只要大于0即可)
//定义一个键盘缓冲区结构体
struct Struct_KeyBoardBuff
{
u8 buff[KeyBuffLen];//键值环形缓冲区
u8 in; //写键值指示(定时器中断写)
u8 Read_Key(void)
{
u8 Value;
if(Key.out != Key.in)
{
Value=Key.buff[Key.out++];//"读"还没有追上"写",缓冲区有键值,读之
if(Key.out >= KeyBuffLen) //如果"读"跑到了队列尾部,则重新跳回原点
u8 out; //读键值指示(用户读)
stc单片机范例程序
stc单片机范例程序STC单片机范例程序STC单片机是一种常用的嵌入式系统开发工具,它具有体积小、功耗低、功能强大等特点,被广泛应用于各种电子设备中。
在使用STC单片机开发项目时,范例程序是非常重要的参考资料。
本文将介绍一些常见的STC单片机范例程序,以帮助读者更好地理解和应用STC单片机。
一、LED闪烁程序以下是一个简单的LED闪烁程序范例:```c#include <reg52.h>sbit LED = P1^0;void main(){while(1){LED = 0; // LED亮delay(500); // 延时500msLED = 1; // LED灭delay(500); // 延时500ms}}void delay(unsigned int count){unsigned int i, j;for(i = 0; i < count; i++)for(j = 0; j < 120; j++);}```该程序使用了P1口的第0位作为控制LED的引脚,通过不断改变LED的状态来实现LED的闪烁效果。
其中的delay函数用于延时一定的时间,以控制LED的亮灭频率。
二、按键检测程序以下是一个简单的按键检测程序范例:```c#include <reg52.h>sbit KEY = P2^0;sbit LED = P1^0;void main(){while(1){if(KEY == 0) // 检测按键是否按下{LED = 0; // LED亮}else{LED = 1; // LED灭}}}```该程序使用了P2口的第0位作为检测按键的引脚,当按键被按下时,LED亮起;当按键松开时,LED熄灭。
三、数码管显示程序以下是一个简单的数码管显示程序范例:```c#include <reg52.h>unsigned char code ledChar[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};sbit digit1 = P2^0;sbit digit2 = P2^1;sbit digit3 = P2^2;sbit digit4 = P2^3;void main(){unsigned char i = 0;while(1){P0 = ledChar[i]; // 在数码管上显示数字digit1 = 1; // 第1位数码管亮digit2 = 0; // 第2位数码管灭digit3 = 0; // 第3位数码管灭digit4 = 0; // 第4位数码管灭delay(10);P0 = ledChar[i]; // 在数码管上显示数字digit1 = 0; // 第1位数码管灭digit2 = 1; // 第2位数码管亮digit3 = 0; // 第3位数码管灭digit4 = 0; // 第4位数码管灭delay(10);P0 = ledChar[i]; // 在数码管上显示数字 digit1 = 0; // 第1位数码管灭digit2 = 0; // 第2位数码管灭digit3 = 1; // 第3位数码管亮digit4 = 0; // 第4位数码管灭delay(10);P0 = ledChar[i]; // 在数码管上显示数字 digit1 = 0; // 第1位数码管灭digit2 = 0; // 第2位数码管灭digit3 = 0; // 第3位数码管灭digit4 = 1; // 第4位数码管亮delay(10);i++;if(i == 10){i = 0;}}}void delay(unsigned int count){unsigned int i, j;for(i = 0; i < count; i++)for(j = 0; j < 120; j++);}```该程序使用了P0口作为数码管的控制引脚,通过改变P0口的输出来控制数码管显示不同的数字。
单片机2个按键互锁c语言程序,单片机按键点动互锁程序源程序
单片机2个按键互锁c语言程序,单片机按键点动互锁程序源程序如何编写一个单片机按键点动互锁的C语言程序?单片机按键点动互锁是一种常见的应用场景,通过编写相关的C语言程序可以实现按键的互锁功能。
在这篇文章中,我将一步一步地回答如何编写这样一个程序。
首先,我们需要了解一些基本概念和原理。
单片机是一种集成电路,可以实现各种功能。
按键是一种输入设备,通常用于接收用户的输入信号。
点动是指按下按钮后立即释放按钮。
互锁是指两个或多个按键之间的相互作用,在某一个按键按下的同时,其他按键是不能按下的。
接下来,我们就可以开始编写程序了。
第一步,我们需要定义端口和引脚的初始状态。
在单片机中,端口是一组相邻的IO引脚,我们可以将某个引脚设为输入或输出。
在这个程序中,我们需要将两个按键连接到单片机的两个不同的引脚上,并将这两个引脚设为输入。
C#include <reg51.h>sbit button1 = P1^0;sbit button2 = P1^1;其中,sbit关键字用于定义一个特殊的数据类型,表示单片机的一个引脚。
第二步,我们需要实现一个延时函数,用于保证按键被稳定地读取。
由于单片机的执行速度非常快,如果没有延时函数,可能会导致按键抖动。
Cvoid delay(unsigned int k){unsigned int i, j;for(i = 0; i < k; i++)for(j = 0; j < 123; j++);}第三步,我们需要编写一个函数用于检测按键的状态。
在这个函数中,我们将使用一个while循环来检测按键是否被按下。
Cunsigned char button_pressed(){while(1){if(button1 == 0){delay(10); 延时10msif(button1 == 0){while(button1 == 0); 等待按键释放return 1; 返回按键1被按下的状态}}if(button2 == 0){delay(10); 延时10msif(button2 == 0){while(button2 == 0); 等待按键释放return 2; 返回按键2被按下的状态}}}}在这个函数中,我们首先检测按键1的状态,如果按键1被按下,延时一段时间后再次检测按键1的状态,如果按键1仍然被按下,则返回按键1被按下的状态。
单片机程序设计范文
单片机程序设计范文单片机程序设计是指利用单片机进行程序编程开发,实现各种功能或控制操作的过程。
单片机是一种微型计算机系统,它具有CPU、内存、输入输出接口等基本组成部分,并且集成在一个芯片上。
单片机程序设计是利用这种芯片进行软件开发,从而实现各种应用需求。
在进行单片机程序设计时,需要掌握一些基本的知识和技巧。
首先,需要了解硬件系统的基本结构和功能,包括CPU、存储器、输入输出接口等。
其次,需要熟悉单片机的指令集和编程语言,如汇编语言或C语言等。
此外,还需要了解各种外设的接口和控制方法,如LED灯、数码管、按键等。
单片机程序设计的流程主要包括以下几个步骤:分析需求、设计框架、编写代码、调试测试和优化改进。
首先,要对需求进行分析,明确所需实现的功能和控制要求。
然后,根据需求设计单片机系统的框架,包括硬件连接和软件模块划分。
接着,根据设计完成编程工作,编写相应的代码。
编写代码时,需要考虑到系统的实时性、稳定性和可扩展性等方面。
编写完成后,需要进行调试测试,确保系统正常运行和实现预期功能。
最后,还需要对系统进行优化改进,提高性能和稳定性。
在实际的单片机程序设计中,有很多经典的案例和实践经验可以借鉴。
例如,LED灯的闪烁控制、数码管的显示操作、按键的响应等。
通过学习这些案例,可以更好地理解和掌握单片机程序设计的基本思路和方法。
此外,还可以通过参加单片机比赛、实践项目等方式提升编程能力和设计水平。
单片机程序设计具有很广泛的应用领域。
例如,工业控制领域中,可以利用单片机实现各种自动化控制系统。
在家电领域中,可以运用单片机实现智能化、联网化的产品功能。
在通信领域中,可以使用单片机实现各种数据处理和通信控制功能。
此外,还可以利用单片机设计各种嵌入式系统、物联网设备等。
总之,单片机程序设计是一项重要的技术和领域,对于电子工程师和计算机科学家来说具有重要的意义和价值。
通过系统学习和实践,可以掌握单片机程序设计的基本理论和实践技巧,进而应用到实际项目中,为社会和经济发展做出贡献。
单片机经典长短按程序
新型的按键扫描程序不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。
我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为C语言强大的可移植性。
同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点。
对于老鸟,我建议直接看那两个表达式,然后自己想想就会懂的了,也不需要听我后面的自吹自擂了,我可没有班门弄斧的意思,hoho~~但是对于新手,我建议将全文看完。
因为这是实际项目中总结出来的经验,学校里面学不到的东西。
以下假设你懂C语言,因为纯粹的C语言描述,所以和处理器平台无关,你可以在MCS-51,AVR,PIC,甚至是ARM平台上面测试这个程序性能。
当然,我自己也是在多个项目用过,效果非常好的。
好了,工程人员的习惯,废话就应该少说,开始吧。
以下我以AVR的MEGA8作为平台讲解,没有其它原因,因为我手头上只有AVR的板子而已没有51的。
用51也可以,只是芯片初始化部分不同,还有寄存器名字不同而已。
核心算法:unsigned char Trg;unsigned char Cont;void KeyRead( void ){unsigned char ReadData = PINB^0xff; // 1Trg = ReadData & (ReadData ^ Cont); // 2Cont = ReadData; // 3}完了。
有没有一种不可思议的感觉?当然,没有想懂之前会那样,想懂之后就会惊叹于这算法的精妙!!下面是程序解释:Trg(triger)代表的是触发,Cont(continue)代表的是连续按下。
1:读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来。
2:算法1,用来计算触发变量的。
一个位与操作,一个异或操作,我想学过C 语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。
按键程序
作者:hexiaoxiao栏目:单片机
我用C51做的键盘程序,望大家批砖
该程序没有被仿真过,可能有一些错误.不过编译是;intrins.h>
#include<reg51.h>
#define uCHAR unsigned CHAR
if(state!=0x0F) //Óмü°´ÏÂ
{
SWITCH(state)
{
case 0x0E:
key=(0x4-i)*0x4+0x1;
break;
case 0x0D:
key=(0x4-i)*0x4+0x2;
break;
case 0x0B:
{
delayms();
if((P0&0x0f)!=0x0f) //确认有键按下
{
for(i=0;i<4;i++) //扫描4行
{
P0=m; //从P0.4=0(第一行)开始扫描
if(KEY_A==0) //列1有效
{
h=h+1; //算出列1键盘值
flag0=1;
while(KEY_A==0) //等待按键松开
11楼:>>参与讨论
作者:fushaobing于2005-4-15 17:32:00发布:
--------------------------------------------------------------------------------
TO xwj:
你的意思是不是这样:把键盘扫描放在定时中断子程序中(定时周期约10ms),可以用两次中断的时间间隔来去抖动,可以引入“键龄”的概念来实现连击的处理(在中断中使键龄减1)。例如,如果设“键龄=25”,则每25*10=250ms操作一次按键。
单片机按键处理技巧及C语言编程方式
单片机按键处理技巧及编程方式在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。
输入可以分很多种情况,譬如有的系统支持PS2键盘的接口,有的系统输入是基于编码器,有的系统输入是基于串口或者USB或者其它输入通道等等。
在各种输入途径中,更常见的是,基于单个按键或者由单个键盘按照一定排列构成的矩阵键盘(行列键盘)。
我们这一篇章主要讨论的对象就是基于单个按键的程序设计,以及矩阵键盘的程序编写。
按键检测的原理: 它们和我们的单片机系统的I/O口连接一般如下:对于单片机I/O内部有上拉电阻的微控制器而言,还可以省掉外部的那个上拉电阻。
简单分析一下按键检测的原理。
当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC,我们在程序中读取该I/O的电平的时候,其值为1(高电平); 当按键S按下的时候,该I/O被短接到GND,在程序中读取该I/O的电平的时候,其值为0(低电平) 。
这样,按键的按下与否,就和与该按键相连的I/O的电平的变化相对应起来。
结论:我们在程序中通过检测到该I/O 口电平的变化与否,即可以知道按键是否被按下,从而做出相应的响应。
一切看起来很美好,是这样的吗?在我们通过上面的按键检测原理得出上述的结论的时候,那就是现实中按键按下时候的电平变化状态。
我们的结论是基于理想的情况得出来的,而实际中,由于按键的弹片接触的时候,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于我们执行时间以us为计算单位的微控制器来说,它太漫长了。
因而,实际的波形图应该如下面这幅示意图一样。
这样便存在这样一个问题。
假设我们的系统有这样功能需求:在检测到按键按下的时候,将某个I/O的状态取反。
由于这种抖动的存在,使得我们的微控制器误以为是多次按键的按下,从而将某个I/O的状态不断取反,这并不是我们想要的效果,假如该I/O控制着系统中某个重要的执行的部件,那结果更不是我们所期待的。
用PIC单片机驱动按键控制8个数码管的显示的C程序
用PIC16F877A单片机驱动按键控制8个数码管的显示的C程序经典按键控制数码管C程序#include <htc.h>#define HC595_SER RB7#define HC595_SCK RB6#define HC595_RCK RB5#define key_164_data RB3#define key_164_clk RB2#define key_com1 RB1#define key_com0 RB0#define TURE 1bit key_finish; //定义的位变量,这是PICmate仿真软件环境的特有的地方unsigned int sample_key;unsigned int sample_keyBuf[2];unsigned int key_value;unsigned char key_row_sel;unsigned char key_number;//键号unsigned int T100ms;unsigned char disbuf[8];const unsigned char seven_seg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5 e,0x79,0x71};//----------------------------------------------void disbuf_update(void){if(key_number>=16){disbuf[0]=0xff;disbuf[1]=0xff;disbuf[2]=0xff;disbuf[3]=0xff;disbuf[4]=0xff;disbuf[5]=0xff;disbuf[6]=0xff;disbuf[7]=0xff;return;}disbuf[0]=seven_seg[key_number];disbuf[1]=seven_seg[key_number];disbuf[2]=seven_seg[key_number];disbuf[3]=seven_seg[key_number];disbuf[4]=seven_seg[key_number];disbuf[5]=seven_seg[key_number];disbuf[6]=seven_seg[key_number];disbuf[7]=seven_seg[key_number];}//----------------------------------------------void inite_time0(void) //对timer0中断进行初始化{PSA=0;T0CS=0;T0IF=0;GIE=1;T0IE=1;TMR0=0xf0;PS0=1;PS1=1;PS2=1;}//----------------------------------------------//发送一个字节void s_pData(unsigned char key) //形参key对应着实参disbuf[i]{unsigned char i;for(i=0;i<8;i++){if(0x80&(key<<i))HC595_SER=1;else HC595_SER=0;HC595_SCK=0;HC595_SCK=1;}}//----------------------------------------------//发送一个字节void Key_s_pData(unsigned char key){unsigned char i;for(i=0;i<8;i++){if(0x80&(key<<i))key_164_data=1;elsekey_164_data=0;key_164_clk=0;key_164_clk=1;}}//---------------------------------------------- void display (void){unsigned char i;for(i=0;i<8;i++)s_pData(disbuf[i]);HC595_RCK=0;HC595_RCK=1;}//---------------------------------------------- void key_process(void){unsigned char i;for(i=0;i<16;i++){if( (key_value&(0x0001<<i)) ){key_number=i;return;}}}//---------------------------------------------- //主程序int main(void){PORTB=0;TRISB=0x03;inite_time0();key_number=0xff;while(1){if(key_finish==TURE){//按键扫描成功key_process();key_finish=0;}if(T100ms<10)continue;T100ms=0;disbuf_update();display();}}//---------------------------------------------- void scan_key(void){sample_key =sample_key<<1;if(key_com1)sample_key |=0x0001;sample_key =sample_key<<1;if(key_com0)sample_key |=0x0001;key_row_sel++;if(key_row_sel<8){Key_s_pData(1<<key_row_sel);return;}key_row_sel=0;Key_s_pData(1<<key_row_sel);sample_keyBuf[0]=sample_key;if(sample_keyBuf[1]!=sample_keyBuf[0]){sample_keyBuf[1]=sample_keyBuf[0];return;}key_value=sample_keyBuf[0];if(key_value!=0)key_finish=TURE;}//-------------------------------------------- //2ms中断interruptvoid time_int(void){if(T0IF==1){T0IF=0;TMR0=0xf0;T100ms++;scan_key();}}它的电路图可以参考用PIC16F877A单片机驱动按键控制8个数码管的显示电路图.。
单片机菜单程序设计
单片机菜单程序设计一、引言单片机是一种集成电路,具有微处理器、内存、输入/输出接口等功能模块的芯片。
它广泛应用于各种电子设备中,如家电、汽车电子、工业控制等领域。
而单片机菜单程序设计是利用单片机的功能实现一个具有菜单界面的程序,使用户能够通过菜单选择功能,并进行相应的操作。
本文将介绍单片机菜单程序设计的基本原理和实现方法。
二、菜单程序设计的基本原理菜单程序设计的基本原理是通过使用单片机的输入/输出接口,结合按键和显示屏等外部设备,实现菜单的显示和选择。
具体包括以下几个步骤:1. 初始化:包括对单片机和外部设备的初始化操作,如设置输入/输出引脚、初始化显示屏等。
2. 菜单显示:通过控制显示屏显示菜单的选项,包括菜单标题和各个选项的名称。
3. 按键检测:利用单片机的输入引脚检测按键的状态,判断用户是否按下了某个按键。
4. 选项选择:根据用户按下的按键,判断用户选择了哪个菜单选项。
5. 功能实现:根据用户选择的菜单选项,执行相应的功能操作。
6. 返回菜单:功能操作完成后,返回上一级菜单或回到主菜单。
三、菜单程序设计的实现方法菜单程序设计可以采用多种实现方法,常用的有层级菜单和状态机两种。
1. 层级菜单:层级菜单是通过多级菜单选项的嵌套实现的。
每个菜单选项可以再包含子菜单,用户通过按键选择菜单选项,进入下一级子菜单或执行相应的功能操作。
2. 状态机:状态机是通过定义不同的状态和状态转移条件实现的。
每个菜单选项可以对应一个状态,用户通过按键触发状态转移,实现不同功能的切换。
实现菜单程序时,需要注意以下几点:1. 菜单的设计要简洁明了,选项名称要清晰易懂,避免歧义。
2. 菜单的显示要美观大方,可以使用不同字体、颜色和布局等方式进行设计。
3. 按键的检测要准确可靠,避免误触发或按键失灵的情况。
4. 功能操作要严谨可靠,避免因程序错误导致系统崩溃或数据丢失。
5. 菜单的返回要灵活方便,用户可以随时返回上一级菜单或回到主菜单。
基于51单片机按键 长按短按效果 源程序
基于51单片机按键长按短按效果源程序[复制链接] *实验名称:多位数按键加减**晶振:12MHZ*内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描**并区别长按短按效果,完全可以应用的实际生产中** ---------------------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,//头文件包含特殊功能寄存器的定义sbit KEY_ADD=P3^3; //定义按键输入端口S17sbit KEY_DEC=P3^2; //S18#define DataPort P1 //定义数据端口程序中遇到DataPort则用P1替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;//位锁存sbit P35 = P3^5;//这是为了关闭开发板上的点阵实际应用去掉unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//显示段码值89unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量void DelayUs2x(unsigned char t);//函数声明void DelayMs(unsigned char t);void Init_Timer0(void);void Display(unsigned char FirstBit,unsigned char Num);/*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned char num=0,key_press_num;P35=0; //这是为了关闭开发板上的点阵实际应用去掉KEY_ADD=1; //按键输入端口电平置高KEY_DEC=1;Init_Timer0();while(1) //主循环{if(!KEY_ADD) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_ADD) //再次确认按键是否按下,没有按下则退出{while(!KEY_ADD){key_press_num++;DelayMs(10); //10x200=2000ms=2sif(key_press_num==200) //大约2s{key_press_num=0; //如果达到长按键标准//则进入长按键动作while(!KEY_ADD) //这里用于识别是否按//键还在按下,如果按//下执行相关动作,否则退出{if(num<99) //加操作num++;//即时把显示数据处理,如果去掉下面2//句处理信息,实际上看不到渐变效果,//而是看到跳变效果//用户可以自行屏蔽测试//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作//的速度,可以自行调整此值以便达到最佳效果}}}key_press_num=0;//防止累加造成错误识别if(num<99) //加操作num++;}}if(!KEY_DEC) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_DEC) //再次确认按键是否按下,没有//按下则退出{while(!KEY_DEC){key_press_num++;DelayMs(10);if(key_press_num==200) //大约2s{key_press_num=0;while(!KEY_DEC){if(num>0) //减操作num--;//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编,大致延时xx如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}显示函数,用于动态扫描数码管输入参数FirstBit表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
51单片机独立按键控制八路LED亮灭程序代码
//51单片机独立按键控制八路LED灯亮灭程序代码//#include <reg51.h> //调用头文件unsigned int count,count1; //定义两个int类型的变量sbit key=P3^5; //定义按键接入串口sbit key1=P3^4; //定义按键接入串口//以下是一个延时函数,便于后面程序按键的消抖,除了这个用途外,延时函数还有很多用途......//void delay(unsigned int ms){while(ms--);}//以下是一个声明的按键检测函数,在这个函数中通过count及count1两个变量的值来确定按键按下LED的亮灭,我这用了两个按键,不同按键控制LED从不同方向一次点亮,函数中采用了if语句与switch语句相结合,这是关键所在。
//void keysan(){if(key==0){delay(10);if(key==0){count++;switch(count){case 0:P1=0xff;break;case 1:P1=0xfe;break;case 2:P1=0xfd;break;case 3:P1=0xfb;break;case 4:P1=0xf7;break;case 5:P1=0xef;break;case 6:P1=0xdf;break;case 7:P1=0xbf;break;case 8:P1=0x7f;break;case 9:P1=0xff;break;}if(count>=9){count=0;}while(!key);}}delay(10);if(key1==0){delay(10);if(key1==0){count1++;switch(count1){case 0:P1=0xff;break; case 1:P1=0x7f;break; case 2:P1=0xbf;break; case 3:P1=0xdf;break; case 4:P1=0xef;break; case 5:P1=0xf7;break; case 6:P1=0xfb;break; case 7:P1=0xfd;break; case 8:P1=0xfe;break; case 9:P1=0xff;break; }if(count1>=9){count1=0;}while(!key1);}}}void main(){while(1){keysan();}}。
实验二独立按键试验实验报告
实验二独立按键试验实验报告
一、实验目的
独立按键试验是为了验证按键与单片机的连接是否正常,并测试按键
功能是否正常,通过实验掌握按键接口的使用和按键的原理。
二、实验原理
在实际应用中,常常需要使用按键来实现硬件的控制。
按键的原理是:当按键关闭时,两个按键引脚之间短接,按键关闭。
当按键打开时,两个
按键引脚之间断开,按键打开。
三、实验仪器
1.单片机开发板
2.按键
3.面包板和杜邦线
4.电源线
四、实验步骤
1.将按键连接到单片机开发板上的按键接口,并接通电源。
2.编写程序,监测按键是否被按下,并通过串口输出按键的状态。
3.烧录程序到单片机,运行程序。
4.进行按键试验。
五、实验结果与分析
按下按键后,通过监测按键引脚的电平变化,可以判断按键是否被按下。
根据不同的按键连接方式,可能需要使用上拉电阻或下拉电阻来连接按键。
六、实验结论
通过独立按键试验,我们验证了按键与单片机的连接是否正确,并测试了按键的功能。
在实际应用中,可以根据需要使用按键来实现硬件的控制。
七、实验心得
通过本次实验,我掌握了按键接口的使用方法和按键的原理。
在实际应用中,按键是一个常用的控制元件,有了这次实验的经验,以后在使用按键时会更加得心应手。
单片机按键去抖动程序设计思路
单片机按键去抖动程序设计思路
1.去抖动原理:按键在按下和松开的瞬间会产生震动,导致按键信号在短时间内出现多次转换,给程序带来困扰。
为了解决这个问题,需要对按键信号进行去抖动处理,即在按键按下和松开时,只记录一次按键状态变化。
2.软件去抖动方法:软件去抖动方法主要通过软件延时来判断按键信号是否稳定。
具体来说,可以通过以下步骤实现软件去抖动:-初始化按键引脚为输入模式,并使能内部上拉电阻;
-设定一个延时时间阈值t,用于判断按键是否稳定;
-读取按键引脚的电平,如果为低电平,说明按键按下;
-进入一个循环,每次循环读取一次按键引脚的电平,并与前一次读取的电平进行比较;
-如果连续读取到的电平与前一次相同,说明按键信号稳定;
-如果连续读取到的电平与前一次不同,则说明按键信号还在抖动,继续读取直到连续读取到的电平与前一次相同;
-当稳定的电平持续时间超过延时时间阈值t时,认为按键信号已稳定,可以进行相应的处理。
3. 硬件去抖动方法:硬件去抖动方法主要通过电路设计来实现。
常见的硬件去抖动电路包括RC滤波电路和Schmitt触发器电路。
其中,RC 滤波电路利用电容和电阻的特性,对按键信号进行平滑处理;Schmitt触发器电路则通过正反馈的方式,将不稳定的信号转换为稳定的信号。
这两种方法可以根据实际需求选择。
总结:
按键去抖动程序设计可以通过软件去抖动和硬件去抖动两种方式实现。
软件去抖动主要通过软件延时判断按键信号是否稳定,而硬件去抖动则通
过电路设计实现。
根据具体的应用场景和需求,可以选择适合的方法来设
计按键去抖动程序。
单片机抢答器设计程序
单片机抢答器设计程序以下是一个简单的单片机抢答器设计程序示例。
```c#include <reg51.h>sbit KEY1=P1^0; // 定义按键1引脚sbit KEY2=P1^1; // 定义按键2引脚sbit KEY3=P1^2; // 定义按键3引脚sbit KEY4=P1^3; // 定义按键4引脚unsigned char code ANSWER[4] = {0x01, 0x02, 0x04, 0x08}; // 定义答案编号unsigned char code LED[4] = {0xFE, 0xFD, 0xFB, 0xF7}; // 定义LED显示编号unsigned char answer_index = 0; // 答案编号索引void main(){unsigned char key_value;while (1){key_value = 0x00;// 检测按键是否按下if (KEY1 == 0){key_value = 0x01;}else if (KEY2 == 0){key_value = 0x02;}else if (KEY3 == 0){key_value = 0x03;}else if (KEY4 == 0){key_value = 0x04;}// 检测按键是否按下并且答案编号匹配if (key_value != 0x00 && key_value ==ANSWER[answer_index]){P2 = LED[answer_index]; // 显示答题编号的LED亮起 answer_index++;}}}```这个程序设计了一个简单的抢答器系统。
通过按下不同的按键来抢答,按键的编号与预设的答案进行匹配。
如果按键编号与答案匹配,对应的LED灯亮起,并且答案编号索引加一,以准备下一题。
这个程序可以根据实际需求进行修改和优化。
单片机按键-长按-短按-连发-双击-抬起-按下
/******************************************************************************** 功能:获取按键状态 参数:无 返回值:按键状态 STAT_DOWN 按键按下
/* 每个按键都包括自己的属性 */ /*按键属性定义*/
typedef struct {
StatEnum_TypeDefstat; unsigned char KeyNum; unsigned short CountMs; unsigned short ShakeTimeMs; unsigned short LongClickTimeMs; unsigned short ContinueSendTimeMs; unsigned short DoubleClickTimeMs; unsigned char (*GetKeyStat)(void); }KeyAttribute_TypeDef;
void KeyAttributeZeroInit(void); void RefreshKeyStat_1_Ms(KeyAttribute_TypeDef *pKeyAttribute); unsigned short GetKeyVal(void);
#endif
/****************************************************************************************************************************** keyfunc.c
STAT_UP 按键未按下 说明:每个按键必须包括一个此类型的函数[unsigned char (*)(void)]然后用按键属性中的
单片机八个按键控制八个led灯程序
#include <reg51。
h>#include <intrins。
h>void delay(void){unsigned char a,b;for(a=0;a〈200;a++)for(b=0;b<200;b++);}unsigned char Key_Scan();void main(void){unsigned char ledValue, keyNum;ledValue = 0x01;while (1){keyNum = Key_Scan();switch (keyNum){case(0xFE):ledValue = 0x01;break;case(0xFD) ://返回按键K2的数据ledValue = 0x02;break;case(0xFB) ://返回按键K3的数据ledValue = 0x04;break;case(0xF7)://返回按键K4的数据ledValue = 0x08;break;case(0xEF) ://返回按键K5的数据ledValue = 0x10;break;case(0xDF)://返回按键K6的数据ledValue = 0x20;break;case(0xBF)://返回按键K7的数据ledValue = 0x40;break;case(0x7F) ://返回按键K8的数据ledValue = 0x80;break;default:break;}P0 = ledValue;//点亮LED灯}}/********************************************************************************函数名: Key_Scan()* 函数功能:扫描键盘*输入: 无* 输出:读取到的键值*******************************************************************************/unsigned char Key_Scan(){unsigned char keyValue = 0 ,i;//保存键值//--检测按键1-—//if (P1 != 0xFF)//检测按键K1是否按下{void delay(void){unsigned char a,b;for(a=0;a〈200;a++)for(b=0;b〈200;b++);}if (P1 != 0xFF)//再次检测按键是否按下{keyValue = P1;i = 0;while ((i〈50)&&(P1 != 0xFF))//检测按键是否松开{Delay10ms(1);i++;}}}return keyValue;//将读取到键值的值返回}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
自己写的按键单片机程序
用4个按键来控制数码管显示的内容#include#define duan P0//段选#define wei P2//位选unsigned char code wei1[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选控制查表的方法控制unsigned char code duan1[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0 x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char ge,shi,bai,a,b;sbit key1=P1;sbit key2=P1 ;sbit key3=P1 ;sbit key4=P1 ;void keys();//按键函数void s(unsigned char xms);//延时函数void DigDisplay(); //动态显示函数void init(); //初始化函数void main(void){init(); while(1){DigDisplay();keys();} }void DigDisplay(){unsigned char i;unsigned int j;bai=a/100;shi=a%100/10;ge=a%10;i=0;wei = wei1[i];//发送位选duan = duan1[bai]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐i++;wei = wei1[i];//发送位选duan = duan1[shi]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐i++;wei = wei1[i];//发送位选duan = duan1[ge]; //发送段码j = 10;//扫描间隔时间设定while(j--);duan = 0x00; //消隐}void init() {key1=1;key2=1;key3=1;key4=1;TMOD=0X01;TH0=(65536-
45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;}void s(unsigned char xms){unsigned char x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}void times() interrupt 1{TH0=(65536-45872)/256;TL0=(65536-45872)%256;b++;if(b==20){b=0;a++;if(a==256){a=0;}}}void
keys(){if(key1==0){s(10);if(key1==0){a++;TR0=0;if(a==256)a=0;while(!key1)Dig Display();}}if(key2==0){s(10);if(key2==0){TR0=0;if(a==0)a=256;a--。