按键处理C语言源程序
单片机C语言程序设计:用计数器中断实现100以内的按键计数
while(1) { P0=DSY_CODE[Count/10]; P2=DSY_CODE[Count%10]; } } //T0 计数器中断函数 voidKey_Counter()interrupt1 { Count=(Count+1)%100;//因为只有两位数码管,计数控制在 100 以内 (00~99) }
P0=0x00; P2=0x00; TMOD=0x06; //计数器 T0 方式 2 TH0=TL0=256-1; //计数值为 1 ET0=1; //允许 T0 中断 EX0=1; //允许 INT0 中断 EA=1; //允许 CPU 中断 IP=0x02; //设置优先级,T0 高于 INT0 IT0=1; //INT0 中断触发方式为下降沿触发 TR0=1; //启动 T0
#include #defineucharunsignedchar #defineuintunsignedint //段码 uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; ucharCount=0; //主程序 voidmain() {
单片机 C 语言程序设计:用计数器中断实现 100 以
内的按键计数
/* 名称: 计数器中断实现按键技术,由于计数寄存器初值为 1,因 此 P3.4 引脚的每次负跳变都会触发 T0 中断,实现计数值累加。 计数器的清零用外部中断 0 控制。 */
//INT0 中断函数 voidClear_Counter()interrupt0 { Count=0; } 扩展阅读:10s 的秒表程序
单片机c语言按下按钮灯亮,松开后还会亮一会在熄灭
单片机c语言按下按钮灯亮,松开后还会亮一会在熄灭要实现这个功能,你需要使用一个单片机(例如Arduino或51单片机)以及一些基本的电子元件,如按钮和LED。
下面是一个简单的Arduino代码示例,实现了你所描述的功能:```cconst int buttonPin = 2; // 按钮连接到数字2const int ledPin = 13; // LED连接到数字13int buttonState = 0; // 初始按钮状态为0int lastButtonState = 0; // 上次按钮状态unsigned long buttonDebounce = 0; // 消抖延时unsigned long buttonHoldDebounce = 0; // 保持延时void setup() {pinMode(buttonPin, INPUT);pinMode(ledPin, OUTPUT);(9600);}void loop() {buttonState = digitalRead(buttonPin); // 读取按钮状态if (millis() - buttonDebounce > 200) { // 如果消抖时间超过200ms if (buttonState != lastButtonState) { // 如果按钮状态改变lastButtonState = buttonState; // 更新上次按钮状态if (buttonState == HIGH) { // 如果按钮被按下if (millis() - buttonHoldDebounce > 1000) { // 如果保持时间超过1sdigitalWrite(ledPin, HIGH); // 点亮LED} else {buttonDebounce = millis(); // 重置消抖时间}} else { // 如果按钮被松开buttonDebounce = millis(); // 重置消抖时间if (millis() - buttonHoldDebounce > 500) { // 如果保持时间超过500msdigitalWrite(ledPin, LOW); // 熄灭LED} else {buttonHoldDebounce = millis(); // 重置保持时间}}}}}```这个代码使用了消抖和保持两个延时来处理按钮的按下和松开事件。
按任意键结束_c语言总结(5篇)
按任意键结束_c语言总结(5篇)第一篇:按任意键结束_c语言总结1、按Esc键结束程序让一个C语言的循环程序不是在等待输入,而是正在运行中,在这期间按任意键就能跳出循环,请问高手们如何实现? #include #define Esc 0x11b /*这两句加在程序头部*/ int key;/*定义key 变量*/ if(bioskey(1))/*以下加在循环语句中*/ {key=bioskey(0);if(key==Esc)break;}2、Windows下特殊系统函数pause法只是按任意键结束,Windows下。
#include “stdio.h” int main(){ printf(“Hello World”);system(“pause”);return 0;}3、Kbhit()函数检测是否有键按下,需要调用kbhit()库函数。
kbhit的原数原型: int kbhit(void);kbhit函数功能:检测是否有键按下,如果有,则返回非0值(即真),否则返回0(即假)。
调用kbhit()函数的源程序必须包含函数名: kbhit功能: 检查当前按下的键用法: int kbhit(void);程序例:#includeconio.h文件。
int main(void){cprintf(“Press any key to continue:”);while(!kbhit())/* do nothing */;cprintf(“rnA key was pressed...rn”);return 0;}4、最原始方法#include “stdio.h” int main(){printf(“Hello World!n”);getchar();return 0;}第二篇:c语言总结注意函数的参数传递。
1.求一位数组a中(或若干整数)所有元素的平均值。
(注意数组作函数参数的情况)2.求一位数组a中的最大/最小元素及下标。
用C语言编写程序实现通过按键使LED灯周期闪烁
用C语言编写程序实现通过按键使LED灯周期闪烁(2010-02-24 21:12:44)标签:循环闪烁周期led灯按键杂谈一、设计题目二、程序功能:开机复位后,LED0到LED7全部点亮,所有LEDPort持续2S后熄灭,然后等待按键,按0键LED7以0.8S周期闪烁,按1键LEDPort以1S周期闪烁。
三、总体设计思想用中断方式实现定时器的定时,然后通过键盘中断程序实现通过对按键的操作来实现相应的周期闪烁。
在我编写的实验程序中我用到了定时器中断和外部中断。
程序共分为两个模块,一个为定时器模块,一个为键盘中断程序模块,在主函数中,首先实现所有LEDPort点亮,然后通过中断方式实现定时2S,在定时器num==20时,设定全局变量为标志位flag=1,然后再主函数中设定条件,通过标志位的变化实现所有LEDPort持续2S后熄灭。
然后进入循环,等待按键,在按键中断服务程序中使用switch语句实现通过改变num1的值来实现LED7的闪烁周期。
设定标志位b=0,在主函数中使用if语句通过判断b的值来改变LED7的亮灭情况,同时相应的b值会取反。
四、程序具体实现实验要求开机复位后,LED0到LED7全部点亮2S后熄灭。
在主函数中使用LEDPort=0x00;这条语句实现所有灯都亮,使用中断方式实现定时器定时2S,因为实验要求20ms溢出,所以设定num=100,在定时器中断服务程序中使用if语句判断条件,当num加到100,也就是说2S时间到时,执行flag=1;语句(先设定全局变量flag=0)。
然后在主函数中使用while语句规定只有在flag=0时才执行所有LEDPort点亮的操作。
2S时间到后,所有灯熄灭。
然后进入while循环,等待用户按键。
用户按键后,通过使用switch语句,实验按0键,num1=20,按1键,num1=50,。
而在主函数中,当按下0键或者1键时,num1就有了固定的值,通过if语句判断是否到达所要求的时间后,执行相应操作。
按键处理程序C语言单片机
按键处理程序C语言单片机分享一种按键处理程序(用C)//头文件定义:Ustruct KEY{Uchar Val;#define Key_Model_C 0 //按键1值#define Key_AddVal_C 1 //按键2值Uint ScanOnTime;Uchar LongKeyState;Uchar LongKeyRestState;Uchar SetInRn;Uchar Model; //按键状态(模式)#define Off_C 0 //之前未按下#define On_C 1 //现按下#define Delay_C 2 //按键处理后标志}Key;//----------------定义两个IO输入口为按键入口--------------------//#define KeyMo_Bin (GPIOB->IDR.Bit.B5)#define KeyAdd_Bin (GPIOB->IDR.Bit.B6)/*===================================== ==========================*/GPIO_Init(GPIO_Pin_5|GPIO_Pin_6,GPIO_Mode_In_PU_No_IT); //初始化为上拉输入无中断/*===================================== ==========================*///主程序大循环中每1毫秒扫描1次void KeyScan(void){if(Key.LongKeyRestState == 1) //长按键标志(复位处理长按键){if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1)) //当两按键均抬起{if(++Key.ScanOnTime >= 130) //延时后复位{Key.LongKeyRestState=0;Key.Model=Delay_C;}}elseKey.ScanOnTime=0;return;}if(Key.Model == Off_C) //如果当前按键状态为未按下“Off_C”{if((KeyMo_Bin == 0) || (KeyAdd_Bin == 0))//按键1或按键2已按下(低有效){if(++Key.ScanOnTime >= 10) //当按下后自加1,加够10次即1ms*10=10ms去抖动{Key.ScanOnTime=0;if(KeyMo_Bin == 0) //如果按键1为0即按下{Key.Val=Key_Model_C; //付当键1值(看头文件定义)Key.Model=On_C; //置按键已按下标志}else if(KeyAdd_Bin == 0) //如果按键2为0即按下{Key.Val=Key_AddVal_C; //付当键2值(看头文件定义)Key.Model=On_C; //置按键已按下标志}BellOn(200); //蜂鸣器响}}elseKey.ScanOnTime=0; //清去抖延时计数值}else if(Key.Model == Delay_C) //如果当前按键状态为已按下且已处理“Delay_C”{if((KeyMo_Bin == 1) && (KeyAdd_Bin == 1))//如果两按键均抬起{if(++Key.ScanOnTime >= 100) //延时100ms后复位按键状态为“Off_C”{Key.SetInRn=0;Key.ScanOnTime=0;Key.Model=Off_C;}}else //如果按键没有被抬起,对应上面if{if(++Key.ScanOnTime >= 1000) //延时1000ms后再复位按键状态为“Off_C”(为长按处理){Key.ScanOnTime=0;Key.Model=Off_C;}}}}//===================================== ========================================= ========void LoadCheckKeyRest(void){Key.LongKeyRestState=1;Key.ScanOnTime=0;}//===================================== ========================================= ========//处理相应按键(可250ms才调用一次)长按if(Key.Model == On_C) //按键状态为已按下{if(Key.Val == Key_Model_C) //是键1按下(看头文件定义){if(++Key.SetInRn >= 3) //连计3次数3秒后为长按键(对应上面,如果按下未抬起的话会延时1000ms){Key.SetInRn=0;LoadCheckKeyRest(); //调清长按处理BellOn(600); //蜂鸣器响//-----------长按需处理的内容-----下-----------//WorkStateBit.Bit.SettingMo=1;SetOverTime=0;SetMoRn=0;SetBak[0]=Rtc_InitDate.RTC_Year;SetBak[1]=Rtc_InitDate.RTC_Month;SetBak[2]=Rtc_InitDate.RTC_Date;SetBak[3]=Rtc_InitDate.RTC_WeekDay;SetBak[4]=Rtc_InitTime.RTC_Hours;SetBak[5]=Rtc_InitTime.RTC_Minutes;//-----------长按需处理的内容------上----------//Key.Model=Delay_C; //置按键模式为:已处理按键(看头文件定义)return;}}elseKey.SetInRn=0;Key.Model=Delay_C;}。
极其简单好用的按键扫描程序(C语言)
不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为C语言强大的可移植性。
同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点。
原理么?可能你也会想到,对于点触开关,按照上面的办法处理一次按下和长按,对于开关型,我们只需要处理Cont就OK了,为什么?很简单嘛,把它当成是一个长按键,这样就找到了共同点,屏蔽了所有的细节。程序就不给了,完全就是应用2的内容,在这里提为了就是说明原理~~
好了,这个好用的按键处理算是说完了。可能会有朋友会问,为什么不说延时消抖问题?哈哈,被看穿了。果然不能偷懒。下面谈谈这个问题,顺便也就非常简单的谈谈我自己用时间片轮办法,以及是如何消抖的。
}
完了。有没有一种不可思议的感觉?当然,没有想懂之前会那样,想懂之后就会惊叹于这算法的精妙!!
下面是程序解释:
Trg(triger) 代表的是触发,Cont(continue)代表的是连续按下。
1:读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来。
2:算法1,用来计算触发变量的。一个位与操作,一个异或操作,我想学过C语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。
{
SysInit();
while(1) // 每20ms 执行一次大循环
{
KeyRead(); // 将每个子程序都扫描一遍
KeyProc();
Func1();
(1) 没有按键的时候
端口为0xff,ReadData读端口并且取反,很显然,就是 0x00 了。
单片机c语言程序设计---矩阵式键盘实验报告
单片机c语言程序设计---矩阵式键盘实验报告课程名称:单片机c语言设计实验类型:设计型实验实验项目名称:矩阵式键盘实验一、实验目的和要求1.掌握矩阵式键盘结构2.掌握矩阵式键盘工作原理3.掌握矩阵式键盘的两种常用编程方法,即扫描法和反转法二、实验内容和原理实验1.矩阵式键盘实验功能:用数码管显示4*4矩阵式键盘的按键值,当K1按下后,数码管显示数字0,当K2按下后,显示为1,以此类推,当按下K16,显示F。
(1)硬件设计电路原理图如下仿真所需元器件(2)proteus仿真通过Keil编译后,利用protues软件进行仿真。
在protues ISIS 编译环境中绘制仿真电路图,将编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
操作方完成矩阵式键盘实验。
具体包括绘制仿真电路图、编写c源程序(反转法和扫描法)、进行仿真并观察仿真结果,需要保存原理图截图,保存c源程序,总结观察的仿真结果。
完成思考题。
三、实验方法与实验步骤1.按照硬件设计在protues上按照所给硬件设计绘制电路图。
2.在keil上进行编译后生成“xxx.hex”文件。
3.编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
四、实验结果与分析void Scan_line()//扫描行{Delay(10);//消抖switch ( P1 ){case 0x0e: i=1;break;case 0x0d: i=2;break;case 0x0b: i=3;break;case 0x07: i=4;break;default: i=0;//未按下break;}}void Scan_list()//扫描列{Delay(10);//消抖switch ( P1 ){case 0x70: j=1;break;case 0xb0: j=2;break;case 0xd0: j=3;break;case 0xe0: j=4;break;default: j=0;//未按下break;}}void Show_Key(){if( i != 0 && j != 0 ) P0=table[ ( i - 1 ) * 4 + j - 1 ];else P0=0xff;}五、讨论和心得。
经典按键程序
switch(Key)
{
case _KEY_F2:
if(Times < 200) //长按 2s
{
return _REENTER; //2s内允许长按
}
BYTE KeyDownCallBack2(WORD Key, WORD Times);
//按键处理数据结构
static struct_KeyInfo g_KeyInfo1 = {0, 0, 0, 0, KeyDownCallBack};
static struct_KeyInfo g_KeyInfo2 = {0, 0, 0, 0, KeyDownCallBack2};
#include "Key.h"
//定时消抖的按键处理函数, 通常在定时中断中调用,
void DitherlessKey(struct_KeyInfo* pInfo)
{
switch(pInfo->KeyState)
{
case _HAS_NO_KEY:
WORD CurKey; //当前检测到的键, 用于处理长按的情况
BYTE (*KeyDownCallBack)(WORD, WORD); //键确认按下的回调函数指针
void (*KeyUpCallBack)(WORD); //键抬起的回调函数指针
WORD PreDownKey; //上次检测到的键
BYTE KeyState; //状态
WORD SameKeyCntr; //同一键检测到按下的次数
g_KeyInfo2.CurKey = temp & 0xFF00; //同一个消抖函数处理不同的按键
基于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};// 显示段码值0123456789unsigned 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,则68/10=6 68%10=8 TempData[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,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下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表示从第一个显示。
极其简单好用的按键扫描程序C语言
极其简单好用的按键扫描程序(C语言)不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。
我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为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为全局变量,其它程序可以直接引用。
C语言按键代码
unsigned int Key2Process(){if (KEY2==1){//有按键if (startkey2flag==0){//是新的按键按下startkey2flag=1;key2downtime=G_timebase;shortkey2flag=0;return NOKEY;}else{//已经开始按键计时,当检测按键计时超过长按时间则不管释放没有,直接判断一次长按,并清除标志if (G_timebase-key2downtime>LONGKEYTIME){//大于长按时间,判断为长按startkey2flag=0;return LONGKEY;}else{//判断是否是双击第二次按下if (key2doubleflag==2){if (G_timebase-key2doublewaittime<WAITDOUBLETIME){//在没有超过双击等待时间内检测到再次按键,把标志改为1,并设置时间等待释放key2doubleflag=1;key2downtime=G_timebase;return NOKEY;}else{//超了时间,属于新的一次按键startkey2flag=1;key2doubleflag=0;key2downtime=G_timebase;shortkey2flag=0;return NOKEY;}}else{//没事做return NOKEY;}}}}else{//无按键,或是按键抖动或是按键释放if (startkey2flag==1){//当前有按键待决if (G_timebase-key2downtime>LONGKEYTIME){//大于长按时间,判断为长按startkey2flag=0;return LONGKEY;}else{//不到长按时间,可能是短按或是长按的抖动if (G_timebase-key2downtime>SHORTKEYTIME){//大于短按时间,下面开始计时,判断是抖动还是真正释放if (shortkey2flag==1){if (G_timebase-key2uptime>JITTERTIME){//大于抖动时间,判断是真正的短按释放if (key2doubleflag==1){//有双击标志,说明是双击的第二次释放key2doubleflag=0;startkey2flag=0;shortkey2flag=0;return DOUBLEKEY;}else{//没有双击标志,看时间是否超过双击等待间隔if (G_timebase-key2uptime>WAITDOUBLETIME){//大于双击间隔,说明是单击startkey2flag=0;key2doubleflag=0;shortkey2flag=0;return SHORTKEY;}else{//可能是双击第一次释放,也可能是单击释放,先做2标志,表示待定,如果在规定时间又按下,说明是双击key2doubleflag=2;key2doublewaittime=G_timebase;return NOKEY;}}}else{//时间短,是抖动,继续检测,啥事都不做return NOKEY;}}else{//第一次碰到释放,做标志,开始记录释放时间shortkey2flag=1;key2uptime=G_timebase;return NOKEY;}}}}else{//当前没有按键,啥事都不做return NOKEY;}}return NOKEY;}。
单片机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被按下的状态。
按键程序
作者: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语言按键代码
C语言按键代码unsigned int Key2Process() if (KEY2==1)// 有按键if (startkey2flag==0)// 是新的按键按下startkey2flag=1;key2downtime=G_timebase;shortkey2flag=0;return NOKEY;else// 已经开始按键计时, 当检测按键计时超过长按时间则不管释放没有,直接判断一次长按, 并清除标志if (G_timebase-key2downtime>LONGKEYTIME)// 大于长按时间, 判断为长按startkey2flag=0;return LONGKEY;else// 判断是否是双击第二次按下if (key2doubleflag==2) if (G_timebase-key2doublewaittime<WAITDOUBLETIME)// 在没有超过双击等待时间内检测到再次按键,把标志改为1,并设置时间等待释放key2doubleflag=1;key2downtime=G_timebase;return NOKEY;else// 超了时间,属于新的一次按键startkey2flag=1;key2doubleflag=0;key2downtime=G_timebase;return NOKEY;shortkey2flag=0;}else// 没事做return NOKEY;else// 无按键, 或是按键抖动或是按键释放if (startkey2flag==1)// 当前有按键待决if (G_timebase-key2downtime>LONGKEYTIME)// 大于长按时间, 判断为长按startkey2flag=0;return LONGKEY;else// 不到长按时间, 可能是短按或是长按的抖动if (G_timebase-key2downtime>SHORTKEYTIME)startkey2flag=0;// 大于短按时间 ,下面开始计时 , 判断是抖动还是真正释放if (shortkey2flag==1) if (G_timebase-key2uptime>JITTERTIME)// 大于抖动时间 , 判断是真正的短按释放 if (key2doubleflag==1)// 有双击标志,说明是双击的第二次释放 key2doubleflag=0;startkey2flag=0;shortkey2flag=0;return DOUBLEKEY;else// 没有双击标志,看时间是否超过双击等待间隔 if (G_timebase-key2uptime>WAITDOUBLETIME) // 大于双击间隔,说明是单击key2doubleflag=0; shortkey2flag=0;return SHORTKEY;else// 可能是双击第一次释放,也可能是单击释放, 先做2 标志,表示待定,如果在规定时间又按下,说明是双击key2doubleflag=2;key2doublewaittime=G_timebase;return NOKEY;else// 时间短, 是抖动,继续检测, 啥事都不做return NOKEY;else// 第一次碰到释放, 做标志, 开始记录释放时间shortkey2flag=1;key2uptime=G_timebase;return NOKEY; shortkey2flag=1;else// 当前没有按键, 啥事都不做return NOKEY;return NOKEY;}。
单片机按键处理技巧及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控制着系统中某个重要的执行的部件,那结果更不是我们所期待的。
单片机键盘输入编程(C语言)
学习过单片机技术的人都知道,单片机的按键输入一般可分为简单的独立式按键输入及行列式键盘输入两种。
图1为简单的独立式键盘输入示意图,独立式键盘输入适合于按键输入不多的情况(<5个按键),具有占用口线较少、软件编写简单容易等特点。
图2为行列式键盘输入示意图,列线接P1.0~P1.3,行线接P1.4~P1.7。
行列式键盘输入适合于按键输入多的情况,如有16个按键输入,用简单按键输入用要占用2个输入口(共16位),而使用行列式键盘输入只需占用一个输入口(8位)。
但行列式键盘输入软件编写较复杂,对初学者而言有一定的难度。
以上略谈了一下按键输入的情况。
在很多状态下,按键输入的值要同时要在LED数码管上显示出来。
如一个按键设计为输入递增(加法)键,可以设计成每点按一下,数值递增加1,同时在LED数码管上显示出来;也可设计成持续按下时,数值以一定时间间隔(如0.3秒)累加。
但是当欲输入值较大时(如三位LED数码管作输入显示时的输入值最大为999),则可能按下键的时间太长(最长达300秒),看来这种方式只适用于一位或至多两位数值(最大99)的输入。
当然你也可多设几个键,每个键只负责一位数值的输入,但这样会占用较多的口线,浪费宝贵的硬件资源。
大家可能见到过,一些进口的温度控制器(如日本RKC INSTRUMENT INC. 生产的REX_C700温控器)的面板设计为:温度测量值用4位LED数码管显示,输入设定值显示也用4位LED数码管,输入按键只有4个,一个为“模式设定键”,一个为“左移键”,另两个为“加法键”、“减法键”。
欲输入设定值(温控值)时,按一下“模式设定键”,程序进入设定状态,此时输入设定值显示的4位LED数码管中,个位显示最亮(稳定显示),而十、百、千位显示较暗(有闪烁感),说明可对个位进行输入。
按下“加法键”或“减法键”,即可输入个位数的值;点按一下“左移键”,变为十位显示最亮,而个、百、千位显示较暗,说明可对十位进行输入。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#i nclude <at89s53.h> #i nclude "4_4KeyScan.c" #i nclude "12864_Driver.c"
//配套键盘扫描程序,获得键码 //临时显示效果使用
#define TIMER0VALUE_H 0xDC //定时器0高位 #define TIMER0VALUE_L 0x00 //定时器0低位 //11.0592晶振定时10ms
unsigned char Font[16]; unsigned char i = 0;
//----------------------------// // 定时器0初始化函数 // //-----------------------------
void Timer0Init (void)
{
TMOD |= 0x01;
{
Key_Backup = Key_Num; //重新记录按键码
Key_Dis_F = 0; //按键标志没有处理
}
}
//区分支持短击和长击的按键处理程序 //占用定时器0,闪烁时间10ms //有效仿抖,时时性较高只能处理单击按键,目前和4*4键盘扫描程序一起使用
//-----------------------------------// 区分支持短击和长击的按键处理程序 // 作者:张子墨 // 最后更新时间:2006/11/21 // 当前版本:0.90 // 测试 MCU:AT89S51 //------------------------------------
//定时器0工作模式1
IE |= 0x82;
//EA = 1;ET0 = 1;
TH0 = TIMER0VALUE_H;
TL0 = TIMER0VALUE_L;
TR0 = 1;
}
#define AN_XD_NUM 2 #define AN_CA_NUM 100
//按键消抖常量,消抖时间大约2*10ms //常按计数器,如果持续按键时间大于100*10MS,判断为长按
unsigned char Key_Num = 0x00; //本次键码 unsigned char Key_Backup = 0x00; //备份键码 unsigned char Key_Cjnum = 0; //长按计数器
TH0 = TIMER0VALUE_H;
TL0 = TIMER0VALUE_L;
TR0 = 1;
}
//----------------------------// // 定时器0中断服务函数 // //-----------------------------
void Timer0SRV (void) interrupt 1 using 2
unsigned char Key_Num = 0x00; //本次键码 unsigned char Key_Backup = 0x00; //备份键码
bit Key_Dis_F = 0; bit Key_Scan_F = 0;
//按键禁止响应 //按键检测使能,中断每10MS 置有效
//----------------------------// //测试程序用的全局变量,对于主功能没有影响 // //----------------------------unsigned char i = 0;
{
TH0 = TIMER0VALUE_H; //重装初值
TL0 = TIMER0VALUE_L;
TR0 = 1;
Key_Scan_F = 1;
//允许扫描键盘
}
//----------------------------// // 临时测试按键效果函数,实际应用修改为散转函数 // //-----------------------------
//----------------------------// // 定时器0初始化函数 // //-----------------------------
void Timer0Init (void)
{
TMOD |= 0x01;
//定时器0工作模式1
IE |= 0x82;
//EA = 1;ET0 = 1;
void ShortKeyAction (void) {
Font[i++] = Key_Num; SentAData(Key_Num); if(i>32) { i = 0; SentAIns (0x01); SentAIns (0x80); } }
//----------------------------// // 按键扫描控制函数 //
#i nclude <at89s53.h> #i nclude "4_4KeyScan.c" #i nclude "12864_Driver.c"
//配套键盘扫描程序,获得键码 //测试用显示功能
#define TIMER0VALUE_H 0xDC //定时器0高位 #define TIMER0VALUE_L 0x00 //定时器0低位 //11.0592晶振定时10ms
按键处理 c 语言源程序 按键处理 c 语言源程序
//一般短按键处理程序 //占用定时器0,闪烁时间10ms //有效仿抖,时时性较高只能处理单击按键,目前和4*4键盘扫描程序一起使用
//-----------------------------------// 单击键盘控制程序 // 作者:张子墨 // 最后更新时/ 测试 MCU:AT89S51 //------------------------------------
if((Key_Num!=0x00)&&(Key_Num == Key_Backup)) //如果有按键并且与上次相同
{
if(!Key_Dis_F) //如果当前按键没有操作
{
ShortKeyAction(); //进入处理散转
Key_Dis_F = 1; //表示按键处理完成
}
}
else
//否则没有按键或者按键变化
bit Key_Dis_F = 0; bit Key_Scan_F = 0;
//按键禁止响应 //按键检测使能,中断每10MS 置有效
//----------------------------// //测试程序用的全局变量,对于主功能没有影响 // //-----------------------------
//-----------------------------
void KeyDeal (void)
{
Key_Scan_F = 0;
//表示10ms 周期内扫描完成,等待新的周期
Key_Num = KeyCodeConvert (GetKeyCode()); //获得最新键盘编码 根据实际情况,使用不同的扫描程序