C语言按键代码
俄罗斯方块C语言代码
>include <>include <>include <>__cplusplusdefine __CPPARGS ...elsedefine __CPPARGSdefine MINBOXSIZE 15 / 最小方块的尺寸 /define BGCOLOR 7 / 背景着色 /define GX 200define GY 10define SJNUM 10000 / 每当玩家打到一万分等级加一级/ / 按键码/define VK_LEFT 0x4b00define VK_RIGHT 0x4d00define VK_DOWN 0x5000define VK_UP 0x4800define VK_HOME 0x4700define VK_END 0x4f00define VK_SPACE 0x3920define VK_ESC 0x011bdefine VK_ENTER 0x1c0d/ 定义俄罗斯方块的方向我定义他为4种/define F_DONG 0define F_NAN 1define F_XI 2define F_BEI 3define NEXTCOL 20 / 要出的下一个方块的纵坐标/ define NEXTROW 12 / 要出的下一个方块的横从标/ define MAXROW 14 / 游戏屏幕大小/define MAXCOL 20define SCCOL 100 /游戏屏幕大显示器上的相对位置/ define SCROW 60int gril2216; / 游戏屏幕坐标/int col=1,row=7; / 当前方块的横纵坐标/int boxfx=0,boxgs=0; / 当前寺块的形壮和方向/int nextboxfx=0,nextboxgs=0,maxcol=22;/下一个方块的形壮和方向/ int minboxcolor=6,nextminboxcolor=6;int num=0; /游戏分/int dj=0,gamedj10={18,16,14,12,10,8,6,4,2,1};/ 游戏等级// 以下我用了一个3组来纪录方块的最初形状和方向/int boxstr7416={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0}, {0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}}, {{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0}, {1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0}, {1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}}, {{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}}, {{1,1,0,0,1,1,0,0,0,0,0,,0,0,0}, {1,1,0,0,1,1,0,0,0,0,0,,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/ 随机得到当前方块和下一个方块的形状和方向/void boxrad{minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random14+1;ifnextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8 nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random7;}/初始化图形模试/void initint gdrive,int gmode{int errorcode;initgraph&gdrive,&gmode,"e:\\tc";errorcode=graphresult;iferrorcode=grOk{printf"error of: %s",grapherrormsgerrorcode; exit1;}}/ 在图形模式下的清屏 /void cls{setfillstyleSOLID_FILL,0;setcolor0;bar0,0,640,480;}/在图形模式下的高级清屏/void clscrint a,int b,int c,int d,int color{ setfillstyleSOLID_FILL,color;setcolorcolor;bara,b,c,d;}/最小方块的绘制/void minboxint asc,int bsc,int color,int bdcolor{int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscra+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color; ifcolor=BGCOLOR{setcolorbdcolor;linea+1,b+1,a-1+MINBOXSIZE,b+1;linea+1,b+1,a+1,b-1+MINBOXSIZE;linea-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE; linea+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE;}}/游戏中出现的文字/void txtint a,int b,char txt,int font,int color{ setcolorcolor;settextstyle0,0,font;outtextxya,b,txt;}/windows 绘制/void winint a,int b,int c,int d,int bgcolor,int bordercolor{ clscra,b,c,d,bgcolor;setcolorbordercolor;linea,b,c,b;linea,b,a,d;linea,d,c,d;linec,b,c,d;}/ 当前方块的绘制/void funboxint a,int b,int color,int bdcolor{int i,j;int boxz44;fori=0;i<16;i++boxzi/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifboxzij==1minboxj+row+aMINBOXSIZE,i+col+bMINBOXSIZE,color,bdcolor; }/下一个方块的绘制/void nextfunboxint a,int b,int color,int bdcolor{int i,j;int boxz44;fori=0;i<16;i++boxzi/4i%4=boxstrnextboxgsnextboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifboxzij==1minboxj+aMINBOXSIZE,i+bMINBOXSIZE,color,bdcolor; }/时间中断定义/define TIMER 0x1cint TimerCounter=0;void interrupt oldhandler__CPPARGS;void interrupt newhandler__CPPARGS{ TimerCounter++;oldhandler;}void SetTimervoid interrupt IntProc__CPPARGS{ oldhandler=getvectTIMER;disable;setvectTIMER,IntProc;enable;}/由于游戏的规则,消掉都有最小方块的一行/void delcolint a{int i,j;fori=a;i>1;i--forj=1;j<15;j++{minboxjMINBOXSIZE,iMINBOXSIZE,BGCOLOR,BGCOLOR; grilij=grili-1j;ifgrilij==1minboxjMINBOXSIZE,iMINBOXSIZE,minboxcolor,0; }}/消掉所有都有最小方块的行/void delete{int i,j,zero,delgx=0;char nm="00000";fori=1;i<21;i++{zero=0;forj=1;j<15;j++ifgrilj==0zero=1;ifzero==0{delcoli;delgx++;}}num=num+delgxdelgx10;dj=num/10000; sprintfnm,"%d",num;clscr456,173,500,200,4;txt456,173,"Number:",1,15; txt456,193,nm,1,15;}/时间中断结束/void KillTimer{disable;setvectTIMER,oldhandler; enable;}/ 测试当前方块是否可以向下落/ int downok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+i+1row+jk=0;returnk;}/ 测试当前方块是否可以向左行/ int leftok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+irow+j-1k=0;returnk;}/ 测试当前方块是否可以向右行/ int rightok{int i,j,k=1,a44;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifaj && grilcol+irow+j+1k=0;returnk;}/ 测试当前方块是否可以变形/ int upok{int i,j,k=1,a44;fori=0;i<4;i++fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfx+1i;fori=3;i>=0;i--forj=3;j>=0;j--ifaj && grilcol+irow+jk=0;returnk;}/当前方块落下之后,给屏幕坐标作标记/ void setgril{int i,j,a44;funbox0,0,minboxcolor,0;fori=0;i<16;i++ai/4i%4=boxstrboxgsboxfxi;fori=0;i<4;i++forj=0;j<4;j++ifajgrilcol+irow+j=1;col=1;row=7;}/游戏结束/void gameover{int i,j;fori=20;i>0;i--forj=1;j<15;j++ minboxjMINBOXSIZE,iMINBOXSIZE,2,0;txt103,203,"",3,10;}/按键的设置/void call_keyint keyx{switchkeyx{case VK_DOWN: { /下方向键,横坐标加一;/ ifdownok{col++;funbox0,0,minboxcolor,0;}else{funbox0,0,minboxcolor,0;setgril;nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; delete;}break;}case VK_UP: { /上方向键,方向形状旋转90度/ ifupokboxfx++;ifboxfx>3boxfx=0;funbox0,0,minboxcolor,0;break;}case VK_LEFT:{ /左方向键,纵坐标减一/ifleftokrow--;funbox0,0,minboxcolor,0;break;}case VK_RIGHT:{ /右方向键,纵坐标加一/ ifrightokrow++;funbox0,0,minboxcolor,0;break;}case VK_SPACE: /,直接落到最后可以落到的们置/ whiledownokcol++;funbox0,0,minboxcolor,0;setgril;nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; delete;break;default:{txt423,53,"worng key",1,4;txt428,80,"Plese Enter Anly Key AG",1,4;;clscr420,50,622,97,BGCOLOR;}}}/时间中断开始/void timezdvoid{int key;SetTimernewhandler;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; for;;{ifbioskey1{key=bioskey0;funbox0,0,BGCOLOR,BGCOLOR;ifkey==VK_ESCbreak;call_keykey;}ifTimerCounter>gamedjdj{TimerCounter=0;ifdownok{funbox0,0,BGCOLOR,BGCOLOR;col++;funbox0,0,minboxcolor,0;}else {ifcol==1{gameover;;break;}setgril;delete;funbox0,0,minboxcolor,0;col=1;row=7;funbox0,0,BGCOLOR,BGCOLOR; nextfunboxNEXTCOL,NEXTROW,4,4;boxrad;nextfunboxNEXTCOL,NEXTROW,nextminboxcolor,0; }}}}/主程序开始/void mainvoid{int i,j;char nm="00000"; initVGA,VGAHI;cls;/屏幕坐标初始化/fori=0;i<=MAXCOL+1;i++ forj=0;j<=MAXROW+1;j++ grilij=0;fori=0;i<=MAXCOL+1;i++ { grili0=1;grili15=1;}forj=1;j<=MAXROW;j++{ gril0j=1;gril21j=1;}clscr0,0,640,480,15;win1,1,639,479,4,15;winSCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15MINBOXSIZE+2,SCROW+21MINBOXSI ZE+2,BGCOLOR,0;nextboxgs=random8;nextboxfx=random4;sprintfnm,"%d",num;txt456,173,"Number:",1,15;txt456,193,nm,1,15;txt456,243,"Next Box:",1,15;timezd;KillTimer;closegraph;;}。
用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语言强大的可移植性。
同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点。
原理么?可能你也会想到,对于点触开关,按照上面的办法处理一次按下和长按,对于开关型,我们只需要处理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语言代码
#include <stdio.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <stdlib.h>#ifdef__cplusplus#define __CPPARGS ...#else#define __CPPARGS#endif#define MINBOXSIZE 15 /* 最小方块的尺寸*/#define BGCOLOR 7 /* 背景着色*/#define GX 200#define GY 10#define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_HOME 0x4700#define VK_END 0x4f00#define VK_SPACE 0x3920#define VK_ESC 0x011b#define VK_ENTER 0x1c0d/* 定义俄罗斯方块的方向(我定义他为4种)*/#define F_DONG 0#define F_NAN 1#define F_XI 2#define F_BEI 3#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/#define NEXTROW 12 /* 要出的下一个方块的横从标*/#define MAXROW 14 /* 游戏屏幕大小*/#define MAXCOL 20#define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/#define SCROW 60int gril[22][16]; /* 游戏屏幕坐标*/int col=1,row=7; /* 当前方块的横纵坐标*/int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6;int num=0; /*游戏分*/int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*//* 以下我用了一个3维数组来纪录方块的最初形状和方向*/int boxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}};/* 随机得到当前方块和下一个方块的形状和方向*/void boxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9;nextboxfx=F_DONG;nextboxgs=random(7);}/*初始化图形模试*/void init(int gdrive,int gmode){int errorcode;initgraph(&gdrive,&gmode,"e:\\tc");errorcode=graphresult();if(errorcode!=grOk){printf("error of: %s",grapherrormsg(errorcode));exit(1);}}/* 在图形模式下的清屏*/void cls(){setfillstyle(SOLID_FILL,0);setcolor(0);bar(0,0,640,480);}/*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color){setfillstyle(SOLID_FILL,color);setcolor(color);bar(a,b,c,d);}/*最小方块的绘制*/void minbox(int asc,int bsc,int color,int bdcolor){int a=0,b=0;a=SCCOL+asc;b=SCROW+bsc;clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color);if(color!=BGCOLOR){setcolor(bdcolor);line(a+1,b+1,a-1+MINBOXSIZE,b+1);line(a+1,b+1,a+1,b-1+MINBOXSIZE);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); }}/*游戏中出现的文字*/void txt(int a,int b,char *txt,int font,int color){setcolor(color);settextstyle(0,0,font);outtextxy(a,b,txt);}/*windows 绘制*/void win(int a,int b,int c,int d,int bgcolor,int bordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/* 当前方块的绘制*/void funbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); }/*下一个方块的绘制*/void nextfunbox(int a,int b,int color,int bdcolor){int i,j;int boxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor);}/*时间中断定义*/#define TIMER 0x1cint TimerCounter=0;void interrupt ( *oldhandler)(__CPPARGS);void interrupt newhandler(__CPPARGS){TimerCounter++;oldhandler();}void SetTimer(void interrupt (*IntProc)(__CPPARGS)){oldhandler=getvect(TIMER);disable();setvect(TIMER,IntProc);enable();}/*由于游戏的规则,消掉都有最小方块的一行*/void delcol(int a){int i,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR);gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0);}/*消掉所有都有最小方块的行*/ void delete(){int i,j,zero,delgx=0;char *nm="00000";for(i=1;i<21;i++){zero=0;for(j=1;j<15;j++)if(gril[j]==0)zero=1;if(zero==0){delcol(i);delgx++;}}num=num+delgx*delgx*10;dj=num/10000;sprintf(nm,"%d",num);clscr(456,173,500,200,4);txt(456,173,"Number:",1,15);txt(456,193,nm,1,15);}/*时间中断结束*/void KillTimer(){disable();setvect(TIMER,oldhandler); enable();}/* 测试当前方块是否可以向下落*/ int downok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i+1][row+j])k=0;return(k);/* 测试当前方块是否可以向左行*/int leftok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j-1])k=0;return(k);}/* 测试当前方块是否可以向右行*/int rightok(){int i,j,k=1,a[4][4];for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j] && gril[col+i][row+j+1])k=0;return(k);}/* 测试当前方块是否可以变形*/int upok(){int i,j,k=1,a[4][4];for(i=0;i<4;i++)for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx+1][i];for(i=3;i>=0;i--)for(j=3;j>=0;j--)if(a[j] && gril[col+i][row+j])k=0;return(k);}/*当前方块落下之后,给屏幕坐标作标记*/ void setgril(){int i,j,a[4][4];funbox(0,0,minboxcolor,0);for(i=0;i<16;i++)a[i/4][i%4]=boxstr[boxgs][boxfx][i];for(i=0;i<4;i++)for(j=0;j<4;j++)if(a[j])gril[col+i][row+j]=1;col=1;row=7;}/*游戏结束*/void gameover(){int i,j;for(i=20;i>0;i--)for(j=1;j<15;j++)minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0);txt(103,203,"Game Over",3,10);}/*按键的设置*/void call_key(int keyx){switch(keyx){case VK_DOWN: { /*下方向键,横坐标加一。
T8:编制并运行按键测试程序
int main(void) { int buttons_fd; char buttons[6] = {'0', '0', '0', '0', '0', '0'}; buttons_fd = open("/dev/buttons", 0); if (buttons_fd < 0) { perror("open device buttons"); exit(1); }
}
3 Linux read函数说明
功能描述: 从文件读取数据。 用法: #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 参数: fd:将要读取数据的文件句柄。 buf:存放读取到的数据的内存缓冲区。 count:需要读取的数据量。 返回说明: 成功执行时,返回所读取的数据量;失败返回-1。
5.1 makefile介绍
详细介绍见文档“gcc,gdb,makefile.pdf”
5.2 buttons_test.c Makefile
代码清单: CROSS=arm-linux all: buttons buttons: buttons_test.c $(CROSS)gcc -o buttons buttons_test.c clean: @rm -vf buttons *.o *~ 要编译buttons_test.c,可以执行以下命令: make 要删除目标文件和中间文件,则执行以下命令: make clean
misc /dev/buttons /opt/FriendlyARM/mini2440/exa mples/buttons
ds1302+ds18b20+闹钟按键可调万年历c语言程序
#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuint nian,yue,ri,week,shi,fen,miao,shuju,naoshi,naofen;uchar ds1302_addr,ds1302_data,temp,temp1,bz=0,shanshuo=0;uchar r0,r1,nh,nl,yh,yl,rh,rl,sh,sl,fh,fl,mh,ml,wh,wl,nsh,nsl,nfh,nfl; uchar moshibz,jiabz,jianbz,kaishibz,naobz,speek;uchartab[11]={0Xc0,0Xf9,0Xa4,0Xb0,0X99,0X92,0X82,0Xf8,0X80,0X90,0xff}; sbit rst=P1^0;sbit clk=P1^1;sbit io=P1^2;sbit DQ=P1^3;sbit zz=P1^7;sbit moshi=P1^6;sbit jia=P1^5;sbit jian=P1^4;sbit kaishi=P3^1;sbit nao=P3^0;sbit led=P2^7;sbit ACC0=ACC^0;sbit ACC7=ACC^7;/*****************延时函数*********************/void d elay(uchar k) //延时程序,约0.1ms{uchar n,m;for(n=0;n<k;n++){for(m=0;m<120;m++);}}/*****************写地址子函数*********************/void w rit_addr(uchar ds1302_addr) //读ds1302 函数{ACC=ds1302_addr;rst=1;for(r1=8;r1>0;r1--){io=ACC0;clk=0;clk=1;ACC=ACC>>1;}}/*****************写数据子函数*********************/void w rit_data(uchar ds1302_data){ACC=ds1302_data;rst=1;for(r1=8;r1>0;r1--){io=ACC0;clk=0;clk=1;ACC=ACC>>1;}rst=0;}/*****************写入ds1302函数*********************/ void write(uchar add,ss) {clk=0;_nop_();rst=0;_nop_();rst=1;_nop_();writ_addr(add);_nop_();writ_data(ss);_nop_();clk=1;_nop_();rst=0;_nop_();}uchar read_data(void) {for(r1=8;r1>0;r1--){ACC7=io;clk=1;clk=0;ACC=ACC>>1;}return ACC;}/*****************读ds1302函数*********************/ void read(uchar addc) { uchar kk;clk=0;_nop_();_nop_();rst=1;_nop_();writ_addr(addc);_nop_();kk=read_data();_nop_();clk=1;_nop_();rst=0;_nop_();ds1302_data=(kk/16)*10+(kk%16); }/*****************//读ds1302 函数*********************/void r ed_dsl302(void){read(0x8d);nian=ds1302_data;read(0x8b);week=ds1302_data;read(0x89);yue=ds1302_data;read(0x87);ri=ds1302_data;read(0x85);shi=ds1302_data;read(0x83);fen=ds1302_data;read(0x81);miao=ds1302_data;}/*****************//写ds1302函数*********************//*void writl302(void){write(0x8e,0x00);write(0x8c,nian);write(0x8a,week);write(0x88,yue);write(0x86,ri);write(0x84,shi);write(0x82,fen);write(0x80,miao);*//*****************初始化函数*********************/void t0_init(void){IE=0X82;TMOD=0X01;TH0=0x3c;TL0=0XB0;TR0=1;r0=0;}/*****************定时器0函数*********************/void t imer() interrupt 1 {TH0=0x3c; //TL0=0XB0;r0++;if(r0==10){r0=0;shanshuo=~shanshuo;}}/*****************闹钟显示函数*********************/void n aozhong(void){P2=0xff;P2=tab[nsh];P0=0xfb;delay(2);P0=0xFF;P2=0xff;P2=tab[nsl];P0=0xF7;delay(2);P0=0xFF;P2=0xff;P2=tab[nfh];P0=0xfe;delay(2);P0=0xFF;P2=tab[nfl];P0=0xFd;delay(2);P0=0xFF;P2=0xff;P2=tab[wh];P0=0xbf;delay(2);P0=0xFF;P2=0xff;P2=tab[wl];P0=0x7f;delay(2);P0=0xFF;P2=0xff;P2=tab[mh];P0=0xef;delay(2);P0=0xFF;P2=0xff;P2=tab[ml];P0=0xdf;delay(2);P0=0xFF;}/*****************全部显示函数************************/ void d isplay(void){if(speek==1){naozhong();}else{P2=0xff;P2=tab[mh];P0=0xef;delay(2);P0=0xFF;P2=0xff;P2=tab[ml];P0=0xdf;delay(2);P2=0xff;P2=tab[fh]; P0=0xfb; delay(2);P0=0xFF;P2=0xff;P2=tab[fl]; P0=0xF7; delay(2);P0=0xFF;P2=0xff;P2=tab[sh]; P0=0xfe; delay(2);P0=0xFF;P2=0xff;P2=tab[sl]; P0=0xFd; delay(2);P0=0xFF;P2=0xff;P2=tab[rh]; P3=0xbf; delay(2);P3=0xFF;P2=0xff;P2=tab[rl]; P3=0x7f; delay(2);P3=0xFF;P2=0xff;P2=tab[yh]; P3=0xef; delay(2);P3=0xFF;P2=0xff;P2=tab[yl]; P3=0xdf; delay(2);P3=0xFF;P2=0xff;P2=tab[nh];delay(2);P3=0xFF;P2=0xff;P2=tab[nl];P3=0xF7;delay(2);P3=0xFF;P2=0xff;zz=0;P2=tab[week];delay(2);zz=1;P2=0xff;P2=tab[wh];P0=0xbf;delay(2);P0=0xFF;P2=0xff;P2=tab[wl];P0=0x7f;delay(2);P0=0xFF;}P2=0xff;P2=tab[wh];P0=0xbf;delay(2);P0=0xFF;P2=0xff;P2=tab[wl];P0=0x7f;delay(2);P0=0xFF;}/*****************闹钟切换函数*********************/ void n aokey(void){if(nao==0){if(naobz==0){naobz=1;speek=!speek;}}if(nao!=0){naobz=0;}}/*****************按键函数*********************/ void k ey(void){if(kaishi==0){if(kaishibz==0){kaishibz=1;bz=7;}}if(kaishi!=0){kaishibz=0;}if(moshi==0){if(moshibz==0){moshibz=1;if(bz==7){bz=0;}else{bz++;}}}if(moshi!=0){moshibz=0;}}/*****************按键加函数*********************/ void s hangtiao(void){if(jia==0){if(jiabz==0){jiabz=1;if(shuju==59){shuju=0;}else{shuju++;}}}if(jia!=0){jiabz=0;}}/*****************按键减函数*********************/void x iatiao(void){if(jian==0){if(jianbz==0){jianbz=1;if(shuju==0){shuju=20;}else{shuju--;}}}if(jian!=0){jianbz=0;}}/*****************分离函数*********************/void f enli(void){if(fen==59&miao==56){led=0;}else{led=1;}if(speek==1){if(bz==1){shuju=naoshi; //先用十进制家,加完后必须转化成十六进制写入shangtiao();xiatiao();naoshi=shuju;if(shanshuo==1){nsh=10;nsl=10;}else{nsh=naoshi/10;nsl=naoshi%10;}}else{nsh=naoshi/10;nsl=naoshi%10;if(bz==2){shuju=naofen;shangtiao();xiatiao();naofen=shuju;if(shanshuo==1){nfh=10;nfl=10;}else{nfh=naofen/10;nfl=naofen%10;}}else{bz=0;nfh=naofen/10;nfl=naofen%10;}}}else{if(bz==1){shuju=nian; //先用十进制家,加完后必须转化成十六进制写入shangtiao();xiatiao();nian=shuju;nian=(nian/10)*16+(nian%10);write(0x8c,nian);nian=(nian/16)*10+(nian%16);if(shanshuo==1){nh=10;nl=10;}else{nh=nian/10;nl=nian%10;}}else{nh=nian/10;nl=nian%10;if(bz==2){shuju=yue;shangtiao();xiatiao();yue=shuju;yue=(yue/10)*16+(yue%10);write(0x88,yue);yue=(yue/16)*10+(yue%16);if(shanshuo==1){yh=10;yl=10;}else{yh=yue/10;yl=yue%10;}}else{yh=yue/10;yl=yue%10;if(bz==3){shuju=ri;shangtiao();xiatiao();ri=shuju;ri=(ri/10)*16+(ri%10);write(0x86,ri);ri=(ri/16)*10+(ri%16);if(shanshuo==1){rh=10;rl=10;}else{rh=ri/10;rl=ri%10;}}else{rh=ri/10;rl=ri%10;if(bz==4){shuju=shi;shangtiao();xiatiao();shi=shuju;shi=(shi/10)*16+(shi%10);write(0x84,shi);shi=(shi/16)*10+(shi%16);if(shanshuo==1){sh=10;sl=10;}else{sh=shi/10;sl=shi%10;}}else{sh=shi/10;sl=shi%10;if(bz==5){shuju=fen;shangtiao();xiatiao();fen=shuju;fen=(fen/10)*16+(fen%10);write(0x82,fen);fen=(fen/16)*10+(fen%16);if(shanshuo==1){fh=10;fl=10;}else{fh=fen/10;fl=fen%10;}}else{fh=fen/10;fl=fen%10;if(bz==6){shuju=week;shangtiao();xiatiao();week=shuju;week=(week/10)*16+(week%10);write(0x82,week);week=(week/16)*10+(week%16);if(shanshuo==1){week=10;}else{;}}else{;}}}}}}}mh=miao/10;ml=miao%10;wh=temp/10;wl=temp%10;}/***********ds18b20延迟子函数(晶振12MHz)*******/void delay_18B20(unsigned int i){while(i--);}/**********ds18b20初始化函数**********************/void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位delay_18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(80); //精确延时大于480usDQ = 1; //拉高总线delay_18B20(14);x = DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}/***********ds18b20读一个字节**************/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat=0;for (i=8;i>0;i--){DQ=0; //给脉冲信号dat>>=1;DQ=1;//给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/*************ds18b20写一个字节****************/void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;}}/**************读取ds18b20当前温度************/void wendu(void){uchar a=0;uchar b=0;uchar flag; //初始化是否成功标志位0,成功1,失败Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0x44);//启动温度转换delay_18B20(100); // this message is very importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar();//读取温度值低8位b=ReadOneChar();//读取温度值高8位if(flag)//初始化失败{a=0x00;b=0x00;}temp1=b<<4;temp1+=(a&0xf0)>>4;//小数点前的数据// temp2=a&0x0f;//小数点后的数据temp=temp1;//temp=((b*256+a)>>4);//当前采集温度值除16得实际温度值//temp1 = t/100%10;//温度值十位// temp2 = t/10%10; //温度值个位// temp3 = t%10; //温度值十分位}/*****************比较函数*********************/void b ijiao(void){if(shi==naofen&fen==naoshi){led=0;if(naofen==naofen+1){led=1;}}else{led=1;}}/**********************主函数**********************/void m ain(void){bz=0;shanshuo=1;nian=0x13;yue=0x8;ri=0x11;shi=0x20;fen=0x44;miao=0x10;week=0x07;// writl302(); //因为ds1302只须写入一次,所以将此处屏蔽。
俄罗斯方块C语言代码
俄罗斯方块C语言代码#include#include#include#include#ifdef uuuucplusplus#define__cppargs...#else#定义_ucpargs#endif#defineminboxsize15/*最小方块的尺寸*/#definebgcolor7/*背景着色*/#定义200#定义10#definesjnum10000/*每当玩家打到一万分等级加一级*//*按键码*/#定义左0x4B00#定义右0x4D00#定义下0x5000#定义上0x4800#definevk_home0x4700#definevk_end0x4f00#definevk_space0x3920#definevk_esc0x011 b#definevk_enter0x1c0d/*定义俄罗斯方块的方向(我把它定义为4)*/#definef_uuu0#definef_uu1#definef_u2#definef_3#definenextcol20/*要出的下一个方块的纵坐标*/#definenextrow12/*要出的下一个方块的横从标*/#definemaxrow14/*游戏屏幕大小*/#definemaxcol20#definesccol100/*游戏屏幕大显示器上的相对位置*/#definescrow60intgril[22][16];/*游戏屏幕坐标*/intcol=1,row=7;/*当前方块的横纵坐标*/intboxfx=0,boxgs=0;/*当前庙宇块的形状和方向*/intnextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/intminboxcolor=6,nextminboxcolor=6;intnum=0;/*游戏分*/intdj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/*在游戏级别之下*//*我使用了一个三维组来记录盒子的初始形状和方向*/intboxstr[7][4][16]={{{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{1,1,0,0,0 ,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}},{{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0},{0,1,1,0,1 ,1,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,1 ,0,0,0,1,1,0,0,0,0,0,0},{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0},{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0 ,1,0,0,1,1,0,0,0,0,0,0},{1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}},{{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0 ,1,0,0,0,1,0,0,0,1,0,0},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}},{{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1 ,1,0,0,0,0,0,0.0,0,0,0},{1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}},{{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0},{0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0},{0,1,0,0,1 ,1,0,0,0,1,0,0,0,0,0,0}}};/*随机得到当前方块和下一个方块的形状和方向*/voidboxrad(){minboxcolor=nextminboxcolor;boxgs=nextboxgs;boxfx=nextboxfx;nextminboxcolor=random(14)+1;如果(nextminboxcolor==4 | | nextminboxcolor==7 | | nextminboxcolor==8)nextminboxcolor=9;nextboxfx=f_2;dong;nextboxgs=random(7);}/*初始化图形模试*/voidinit(intgdrive,intgmode){interrocode;initgraph(&gdrive,&gmode,\errorcode=graphresult();如果(错误代码!=grok){printf(\exit(1);}}/*图形模式下的屏幕清除*/void CLS(){setfillstyle(solid_fill,0);setcolor(0);巴(0,0640480);}/*在图形模式下的高级清屏*/voidclscr(inta,intb,intc,intd,intcolor){setfillstyle(solid_fill,color);setcolor(color);bar(a,b,c,d);}/*最小正方形的绘制*/voidminbox(intasc,intbsc,intcolor,intbdcolor){inta=0,b=0;a=sccol+asc;b=scrow+b sc;clscr(a+1、b+1、a-1+minboxsize、b-1+minboxsize、颜色);如果(color!=bgcolor){setcolor(bdcolor);line(a+1,b+1,a-1+minboxsize,b+1);线路(a+1、b+1、a+1、b-1+minboxsize);line(a-1+minboxsize,b+1,a-1+minboxsize,b-1+minboxsize);line(a+1,b-1+minboxsize,a-1+minboxsize,b-1+minboxsize);}}/*游戏中的文字*/voidtxt(inta,intb,char*txt,intfont,intcolor){setcolor(color);settextstyle(0,0,字体);outtextxy(a,b,txt);}/*windows绘制*/voidwin(inta,intb,intc,intd,intbgcolor,intbordercolor){clscr(a,b,c,d,bgcolor);setcolor(bordercolor);line(a,b,c,b);line(a,b,a,d);line(a,d,c,d);line(c,b,c,d);}/*当前方块的绘制*/voidfunbox(inta,intb,intcolor,intbdcolor){inti,j;intboxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[boxgs][boxfx][i];对于(i=0;i<4;i++)对于(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+row+a)*minboxsize,(i+col+b)*minboxsize,color,bdcolor);}/*下一个方块的绘制*/voidNextFunbX(inta,intb,intcolor,intbdcolor){inti,j;intboxz[4][4];for(i=0;i<16;i++)boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i];对于(i=0;i<4;i++)for(j=0;j<4;j++)if(boxz[i][j]==1)minbox((j+a)*minboxsize,(i+b)*minboxsize,color,bdcolor);}/*时间中断定义*/#definetimer0x1cinttimercounter=0;voidinterrupt(*oldhandler)(__cppargs);voidinterruptnewhandler(__cppargs){timer counter++;oldhandler();}voidsettimer(voidinterrupt(*intproc)(__cppargs)){oldhandler=getvect(timer);dis able();setvect(定时器,intproc);启用();}/*由于游戏的规则,消掉都有最小方块的一行*/voiddelcol(inta){因蒂,j;for(i=a;i>1;i--)for(j=1;j<15;j++){minbox(j*minboxsize,i*minboxsize,bgcolor,bgcolor);gril[i][j]=gril[i-1][j];if(gril[i][j]==1)minbox(j*minboxsize,i*minboxsize,minboxcolor,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;}。
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;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;}。
单片机C语言简单编程
1、点亮2、3、5、8四个发光二极管。
(课后作业)#include<reg52.h>sbit LED2=P1^0;sbit LED3=P1^3;sbit LED5=P1^5;sbit LED8=P1^6;main(){LED2=0; //第二盏灯亮LED3=0; //第三盏灯亮LED5=0; //第五盏灯亮LED8=0; //第八盏灯亮while(1);}2、设计走马灯和数码管逐一显示数字。
(课后作业)#include<reg52.h>void Delay(){unsigned int j;j=30000;while(j--);} //时间延时函数void main(){int a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示段码int b[10]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xaa,0x55}; //点亮灯的段码unsigned char i;while(1){for(i=0;i<10;i++){P1=b[i];P2=a[i];Delay();}}}3、开关K1控制加,开关K2控制减,开关K3控制复位。
当减到小于0的时候再从99开始减,当加到99的时候又从0开始加。
(课后作业)#include<reg52.h>sbit BIT1=P3^0;sbit BIT2=P3^1;sbit Button1=P3^7;sbit Button2=P3^6;sbit Button3=P3^5;{unsigned int i,j;for(i=0;i<t;i++)for(j=0;j<252;j++){;}} //时间延迟函数的定义void main(){char dat = 0; // 有符号数int b[10]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xaa,0x55}; //跑马灯显示的段码unsigned char z;while(1){for(z=0;z<10;z++){BIT1=0;BIT2=1;P2=a[dat/10];Delay(20);P2 = 0xff ; // 消隐,防止个位的数在十位显示,导致显示乱码BIT1=1;BIT2=0;P2=a[dat%10];Delay(20);P2 = 0xff ; // 消隐P1=b[z];Delay(20); //跑马灯显示if(Button1==0){dat++;if(dat >= 99)dat=0;while(Button1==0);} //按键1是控制加的,当加到大于等于99时又从0开始加if(Button2==0){dat--;if(dat <= 0)dat=99;while(Button2==0);} //按键2是控制减的,当减到小于等于0时再从99开始减if(Button3==0){dat=0;while(Button3==0);}} //按键3是控制复位的,任何时候按下就归04、开始1、2、3、4闪烁,按一下K1,5、6、7、8闪烁,再按一下K1全部闪烁。
keyboard test for ARM(键盘测试代码(C语言))
}
void Command()
{ // 读取按键,执行命令设置标志
int key;
key = keyScan();
if(!key) // 如果无按键
/*执行命令*/
switch(key)
{
case KEY1:
LedFlag = 1; // LED 运行方式标志 --> 1
break;
case KEY2:
LedFlag = 2;
break;
LedMode2Flag = 1;
break;
case 1:
LED1Off();
LED2Off();
LED3Off();
LED4Off();
Delay(10000);
LedMode2Flag = 0;
int LedFlag; // LED运行方式,取值 1 -- 4
int keyReleaseFlag; // 按键已经释放 1,没有释放 0
int LedMode1Flag; // LED运行方式1的LED状态标志,取值 0 --
int LedMode2Flag; // LED运行方式2的LED状态标志,
switch (LedFlag)
{
case LED1:
LedMode1();
break;
case LED2:
LedMode2();
break;
}
}
void LedMode1()
C语言游戏代码(里面揽括扫雷_俄罗斯方块_推箱子_五子棋_贪吃蛇)
五子棋#include <stdio.h>#include <bios.h>#include <ctype.h>#include <conio.h>#include <dos.h>#define CROSSRU 0xbf /*右上角点*/#define CROSSLU 0xda /*左上角点*/#define CROSSLD 0xc0 /*左下角点*/#define CROSSRD 0xd9 /*右下角点*/#define CROSSL 0xc3 /*左边*/#define CROSSR 0xb4 /*右边*/#define CROSSU 0xc2 /*上边*/#define CROSSD 0xc1 /*下边*/#define CROSS 0xc5 /*十字交叉点*//*定义棋盘左上角点在屏幕上的位置*/#define MAPXOFT 5#define MAPYOFT 2/*定义1号玩家的操作键键码*/#define PLAY1UP 0x1157/*上移--'W'*/#define PLAY1DOWN 0x1f53/*下移--'S'*/#define PLAY1LEFT 0x1e41/*左移--'A'*/#define PLAY1RIGHT 0x2044/*右移--'D'*/#define PLAY1DO 0x3920/*落子--空格键*//*定义2号玩家的操作键键码*/#define PLAY2UP 0x4800/*上移--方向键up*/#define PLAY2DOWN 0x5000/*下移--方向键down*/ #define PLAY2LEFT 0x4b00/*左移--方向键left*/#define PLAY2RIGHT 0x4d00/*右移--方向键right*/ #define PLAY2DO 0x1c0d/*落子--回车键Enter*//*若想在游戏中途退出, 可按Esc 键*/#define ESCAPE 0x011b/*定义棋盘上交叉点的状态, 即该点有无棋子*//*若有棋子, 还应能指出是哪个玩家的棋子*/#define CHESSNULL 0 /*没有棋子*/#define CHESS1 'O'/*一号玩家的棋子*/#define CHESS2 'X'/*二号玩家的棋子*//*定义按键类别*/#define KEYEXIT 0/*退出键*/#define KEYFALLCHESS 1/*落子键*/#define KEYMOVECURSOR 2/*光标移动键*/#define KEYINV ALID 3/*无效键*//*定义符号常量: 真, 假--- 真为1, 假为0 */#define TRUE 1#define FALSE 0/**********************************************************/ /* 定义数据结构*//*棋盘交叉点坐标的数据结构*/struct point{int x,y;};/**********************************************************/ /*自定义函数原型说明*/void Init(void);int GetKey(void);int CheckKey(int press);int ChangeOrder(void);int ChessGo(int Order,struct point Cursor);void DoError(void);void DoOK(void);void DoWin(int Order);void MoveCursor(int Order,int press);void DrawCross(int x,int y);void DrawMap(void);int JudgeWin(int Order,struct point Cursor);int JudgeWinLine(int Order,struct point Cursor,int direction);void ShowOrderMsg(int Order);void EndGame(void);/**********************************************************//**********************************************************/ /* 定义全局变量*/int gPlayOrder; /*指示当前行棋方*/struct point gCursor; /*光标在棋盘上的位置*/char gChessBoard[19][19];/*用于记录棋盘上各点的状态*//**********************************************************//**********************************************************/ /*主函数*/void main(){int press;int bOutWhile=FALSE;/*退出循环标志*/printf("Welcome ");Init();/*初始化图象,数据*/while(1){press=GetKey();/*获取用户的按键值*/switch(CheckKey(press))/*判断按键类别*/{/*是退出键*/case KEYEXIT:clrscr();/*清屏*/bOutWhile = TRUE;break;/*是落子键*/case KEYFALLCHESS:if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/DoError();/*落子错误*/else{DoOK();/*落子正确*//*如果当前行棋方赢棋*/if(JudgeWin(gPlayOrder,gCursor)==TRUE){DoWin(gPlayOrder);bOutWhile = TRUE;/*退出循环标志置为真*/}/*否则*/else/*交换行棋方*/ChangeOrder();ShowOrderMsg(gPlayOrder);}break;/*是光标移动键*/case KEYMOVECURSOR:MoveCursor(gPlayOrder,press);break;/*是无效键*/case KEYINV ALID:break;}if(bOutWhile==TRUE)break;}/*游戏结束*/EndGame();}/**********************************************************//*界面初始化,数据初始化*/void Init(void){int i,j;char *Msg[]={"Player1 key:"," UP----w"," DOWN--s"," LEFT--a"," RIGHT-d"," DO----space","","Player2 key:"," UP----up"," DOWN--down"," LEFT--left"," RIGHT-right"," DO----ENTER","","exit game:"," ESC",NULL,/* 先手方为1号玩家*/gPlayOrder = CHESS1;/* 棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/ for(i=0;i<19;i++)for(j=0;j<19;j++)gChessBoard[i][j]=CHESSNULL;/*光标初始位置*/gCursor.x=gCursor.y=0;/*画棋盘*/textmode(C40);DrawMap();/*显示操作键说明*/i=0;textcolor(BROWN);while(Msg[i]!=NULL){gotoxy(25,3+i);cputs(Msg[i]);i++;}/*显示当前行棋方*/ShowOrderMsg(gPlayOrder);/*光标移至棋盘的左上角点处*/gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);}/*画棋盘*/void DrawMap(void){int i,j;clrscr();for(i=0;i<19;i++)for(j=0;j<19;j++)DrawCross(i,j);}/*画棋盘上的交叉点*/void DrawCross(int x,int y){gotoxy(x+MAPXOFT,y+MAPYOFT); /*交叉点上是一号玩家的棋子*/if(gChessBoard[x][y]==CHESS1) {textcolor(LIGHTBLUE);putch(CHESS1);return;}/*交叉点上是二号玩家的棋子*/if(gChessBoard[x][y]==CHESS2) {textcolor(LIGHTBLUE);putch(CHESS2);return;}textcolor(GREEN);/*左上角交叉点*/if(x==0&&y==0){putch(CROSSLU);return;}/*左下角交叉点*/if(x==0&&y==18){putch(CROSSLD);return;}/*右上角交叉点*/if(x==18&&y==0){putch(CROSSRU);return;}/*右下角交叉点*/if(x==18&&y==18){putch(CROSSRD); return;}/*左边界交叉点*/if(x==0){putch(CROSSL); return;}/*右边界交叉点*/if(x==18){putch(CROSSR); return;}/*上边界交叉点*/if(y==0){putch(CROSSU); return;}/*下边界交叉点*/if(y==18){putch(CROSSD); return;}/*棋盘中间的交叉点*/ putch(CROSS);}/*交换行棋方*/int ChangeOrder(void) {if(gPlayOrder==CHESS1) gPlayOrder=CHESS2; elsegPlayOrder=CHESS1;return(gPlayOrder);}/*获取按键值*/int GetKey(void){char lowbyte;int press;while (bioskey(1) == 0);/*如果用户没有按键,空循环*/press=bioskey(0);lowbyte=press&0xff;press=press&0xff00 + toupper(lowbyte); return(press);}/*落子错误处理*/void DoError(void){sound(1200);delay(50);nosound();}/*赢棋处理*/void DoWin(int Order){sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);sound(1500);delay(100);sound(0); delay(50);sound(800); delay(100);sound(0); delay(50);nosound();textcolor(RED+BLINK);gotoxy(25,20);if(Order==CHESS1)cputs("PLAYER1 WIN!");elsecputs("PLAYER2 WIN!");gotoxy(25,21);cputs(" \\<^+^>/");getch();}/*走棋*/int ChessGo(int Order,struct point Cursor){/*判断交叉点上有无棋子*/if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL){/*若没有棋子, 则可以落子*/gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); textcolor(LIGHTBLUE);putch(Order);gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT); gChessBoard[Cursor.x][Cursor.y]=Order;return TRUE;}elsereturn FALSE;}/*判断当前行棋方落子后是否赢棋*/int JudgeWin(int Order,struct point Cursor){int i;for(i=0;i<4;i++)/*判断在指定方向上是否有连续5个行棋方的棋子*/if(JudgeWinLine(Order,Cursor,i))return TRUE;return FALSE;}/*判断在指定方向上是否有连续5个行棋方的棋子*/int JudgeWinLine(int Order,struct point Cursor,int direction) {int i;struct point pos,dpos;const int testnum = 5;int count;switch(direction){case 0:/*在水平方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y;dpos.x=1;dpos.y=0;break;case 1:/*在垂直方向*/pos.x=Cursor.x;pos.y=Cursor.y-(testnum-1);dpos.x=0;dpos.y=1;break;case 2:/*在左下至右上的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y+(testnum-1);dpos.x=1;dpos.y=-1;break;case 3:/*在左上至右下的斜方向*/pos.x=Cursor.x-(testnum-1);pos.y=Cursor.y-(testnum-1);dpos.x=1;dpos.y=1;break;}count=0;for(i=0;i<testnum*2+1;i++)/*????????i<testnum*2-1*/ {if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) {if(gChessBoard[pos.x][pos.y]==Order){count++;if(count>=testnum)return TRUE;}elsecount=0;}pos.x+=dpos.x;pos.y+=dpos.y;}return FALSE;}/*移动光标*/void MoveCursor(int Order,int press) {switch(press){case PLAY1UP:if(Order==CHESS1&&gCursor.y>0) gCursor.y--;break;case PLAY1DOWN:if(Order==CHESS1&&gCursor.y<18) gCursor.y++;break;case PLAY1LEFT:if(Order==CHESS1&&gCursor.x>0) gCursor.x--;break;case PLAY1RIGHT:if(Order==CHESS1&&gCursor.x<18) gCursor.x++;break;case PLAY2UP:if(Order==CHESS2&&gCursor.y>0) gCursor.y--;break;case PLAY2DOWN:if(Order==CHESS2&&gCursor.y<18) gCursor.y++;break;case PLAY2LEFT:if(Order==CHESS2&&gCursor.x>0) gCursor.x--;break;case PLAY2RIGHT:if(Order==CHESS2&&gCursor.x<18) gCursor.x++;break;}gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*游戏结束处理*/void EndGame(void){textmode(C80);}/*显示当前行棋方*/void ShowOrderMsg(int Order){gotoxy(6,MAPYOFT+20);textcolor(LIGHTRED);if(Order==CHESS1)cputs("Player1 go!");elsecputs("Player2 go!");gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); }/*落子正确处理*/void DoOK(void){sound(500);delay(70);sound(600);delay(50);sound(1000);delay(100);nosound();}/*检查用户的按键类别*/int CheckKey(int press){if(press==ESCAPE)return KEYEXIT;/*是退出键*/elseif( ( press==PLAY1DO && gPlayOrder==CHESS1) || ( press==PLAY2DO && gPlayOrder==CHESS2))return KEYFALLCHESS;/*是落子键*/elseif( press==PLAY1UP || press==PLAY1DOWN || press==PLAY1LEFT || press==PLAY1RIGHT || press==PLAY2UP || press==PLAY2DOWN ||press==PLAY2LEFT || press==PLAY2RIGHT)return KEYMOVECURSOR;/*是光标移动键*/elsereturn KEYINV ALID;/*按键无效*/}贪吃蛇#define N 200#include <graphics.h>#include <stdlib.h>#include <dos.h>#define LEFT 0x4b00#define RIGHT 0x4d00#define DOWN 0x5000#define UP 0x4800#define ESC 0x011bint i,key;int score=0;/*得分*/int gamespeed=50000;/*游戏速度自己调整*/ struct Food{int x;/*食物的横坐标*/int y;/*食物的纵坐标*/int yes;/*判断是否要出现食物的变量*/ }food;/*食物的结构体*/struct Snake{int x[N];int y[N];int node;/*蛇的节数*/int direction;/*蛇移动方向*/int life;/* 蛇的生命,0活着,1死亡*/}snake;void Init(void);/*图形驱动*/void Close(void);/*图形结束*/void DrawK(void);/*开始画面*/void GameOver(void);/*结束游戏*/void GamePlay(void);/*玩游戏具体过程*/void PrScore(void);/*输出成绩*//*主函数*/void main(void){Init();/*图形驱动*/DrawK();/*开始画面*/GamePlay();/*玩游戏具体过程*/Close();/*图形结束*/}/*图形驱动*/void Init(void){int gd=DETECT,gm;initgraph(&gd,&gm,"c:\\tc");cleardevice();}/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/ void DrawK(void){/*setbkcolor(LIGHTGREEN);*/setcolor(11);setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/for(i=50;i<=600;i+=10)/*画围墙*/{rectangle(i,40,i+10,49); /*上边*/rectangle(i,451,i+10,460);/*下边*/}for(i=40;i<=450;i+=10){rectangle(50,i,59,i+10); /*左边*/rectangle(601,i,610,i+10);/*右边*/}}/*玩游戏具体过程*/void GamePlay(void){randomize();/*随机数发生器*/food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/snake.life=0;/*活着*/snake.direction=1;/*方向往右*/snake.x[0]=100;snake.y[0]=100;/*蛇头*/snake.x[1]=110;snake.y[1]=100;snake.node=2;/*节数*/PrScore();/*输出得分*/while(1)/*可以重复玩游戏,压ESC键结束*/{while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/{if(food.yes==1)/*需要出现新食物*/{food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/ food.x++;while(food.y%10!=0)food.y++;food.yes=0;/*画面上有食物了*/}if(food.yes==0)/*画面上有食物了就要显示*/{setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);}for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/switch(snake.direction){case 1:snake.x[0]+=10;break;case 2: snake.x[0]-=10;break;case 3: snake.y[0]-=10;break;case 4: snake.y[0]+=10;break;}for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/{if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){GameOver();/*显示失败*/snake.life=1;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)/*蛇是否撞到墙壁*/{GameOver();/*本次游戏结束*/snake.life=1; /*蛇死*/}if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/ break;if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/{setcolor(0);/*把画面上的食物东西去掉*/rectangle(food.x,food.y,food.x+10,food.y-10);snake.x[snake.node]=-20;snake.y[snake.node]=-20;/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/snake.node++;/*蛇的身体长一节*/food.yes=1;/*画面上需要出现新的食物*/score+=10;PrScore();/*输出新得分*/}setcolor(4);/*画出蛇*/for(i=0;i<snake.node;i++)rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);delay(gamespeed);setcolor(0);/*用黑色去除蛇的的最后一节*/rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);} /*endwhile(!kbhit)*/if(snake.life==1)/*如果蛇死就跳出循环*/break;key=bioskey(0);/*接收按键*/if(key==ESC)/*按ESC键退出*/break;elseif(key==UP&&snake.direction!=4)/*判断是否往相反的方向移动*/snake.direction=3;elseif(key==RIGHT&&snake.direction!=2)snake.direction=1;elseif(key==LEFT&&snake.direction!=1)snake.direction=2;elseif(key==DOWN&&snake.direction!=3)snake.direction=4;}/*endwhile(1)*/}/*游戏结束*/void GameOver(void){cleardevice();PrScore();setcolor(RED);settextstyle(0,0,4);outtextxy(200,200,"GAME OVER");getch();}/*输出成绩*/void PrScore(void){char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);settextstyle(0,0,2);sprintf(str,"score:%d",score);outtextxy(55,20,str);}/*图形结束*/void Close(void){getch();closegraph();}扫雷游戏/*模拟扫雷游戏*/#include <graphics.h>#include <math.h>#include <stdio.h>#include <dos.h>#include <stdlib.h>#include <conio.h>#include <alloc.h>union REGS regs;int size=15;/*用于表示每个方块的大小(正方形的边长)*/int pix,piy=50;/*pix,piy是矩阵的偏移量*/char b[2]="1";/*用于显示方格周围的雷的个数*/int pan[30][16];/*用于记录盘面的情况:0:没有、9:有雷、1~8:周围雷的个数*/int pan1[30][16];/*pan1[][]纪录当前的挖雷情况,0:没有操作、1:打开了、2:标记了*/int tt;/*纪录时间参数*/int Eflags;/*用于标记鼠标按钮的有效性,0:有效,1:无效,2:这是鼠标的任意键等于重新开始*/int Msinit();void Draw(int x,int y,int sizex,int sizey);void Facedraw(int x,int y,int sizel,int k);void Dead(int sizel,int x,int y);void Setmouse(int xmax,int ymax,int x,int y);int Msread(int *xp,int *yp,int *bup,struct time t1,int k);void Draw1(int x,int y);int Open(int x,int y);float Random();void Have(int sum,int x,int y,int xx,int yy);void Help();void Coread();void Ddraw2(int x,int y);/*下面是主函数*/main(){int mode=VGAHI,devices=VGA;/*图形模式初始化的变量*/char ams; /*鼠标操作中的标志变量*/int xms,yms,bms; /*鼠标的状态变量*/int i,j,k,k1=0; /*i,j,k是循环变量*/int x=9,y=9,flags=0; /*x,y矩阵的大小*/int sum=10; /*sum 盘面的雷的总数目,是个x,y的函数*/int x1=0,y1=0; /*用于记录光标当前的位置*/int x11=0,y11=0; /*暂时保存鼠标位置的值*/int sizel=10; /*脸的大小*/int cflags=1; /*这是菜单操作标志变量,没有弹出1,弹出0*/struct time t1={0,0,0,0}; /*时间结构体,头文件已定义*/int co[3]; /*暂时纪录历史纪录*/void far *Map; /*用于保存鼠标图片*/char name[3][20]; /*名字字符串,用于记录名字*/FILE * p; /*文件指针用于文件操作*/Msinit(); /*鼠标初始化*//*registerbgidriver(EGA VGA_driver);*/initgraph(&devices,&mode,"C:\\tc"); /*图形模式初始化*//*为图片指针分配内存*/if((Map=farmalloc(imagesize(0,0,20,20)))==NULL)/*图片的大小是20*20*/{printf("Memory ererr!\n");printf("Press any key to out!\n");exit(1);}/*用于检验文件是否完整*/while((p = fopen("score.dat", "r")) == NULL) /*如果不能打开就新建一个*/{if((p = fopen("score.dat", "w")) == NULL)/*如果不能新建就提示错误并推出*/{printf("The file cannot open!\n");printf("Presss any key to exit!\n");getch();exit(1);}/*写入初始内容*/fprintf(p,"%d %d %d,%s\n%s\n%s\n",999,999,999,"xiajia","xiajia","xiajia");fclose(p);}/*暂时读出历史纪录。
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数码管中,个位显示最亮(稳定显示),而十、百、千位显示较暗(有闪烁感),说明可对个位进行输入。
按下“加法键”或“减法键”,即可输入个位数的值;点按一下“左移键”,变为十位显示最亮,而个、百、千位显示较暗,说明可对十位进行输入。
C语言实现按键
if(ch==0x0b)key_data=0x0a;
if(ch==0x07)key_data=0x0e;
sss2:
ch = RD244;
ch &= 0x0f;
if(ch==0x0f){return;}
goto sss2;
}
//扫描第2列
WR273=0x0b;
ssss://判断是否有键被按下
WR273 = 0xf0;
for(ki=0;ki<10;ki++);
ch = RD244;
ch &= 0x0f;
if(ch==0x0f)goto ssss;
//扫描第0列
WR273 = 0x0e;
for(ki=0;ki<10;ki++);
ch = RD244;
ch &= 0x0f;
if(ch!=0x0f){//如果有按键的话,逐行确认是哪一个按键
if(ch==0x0e)key_data=0x03;//根据读到的行线状态确定按下的键值
if(ch==0x0d)key_data=0x07;
if(ch==0x0b)key_data=0x0b;
if(ch==0x07)key_data=0x0f;
buf[0]=key_data;
Print();
}
}
sss3:
ch = RD244;
ch &= 0x0f;
if(ch==0x0f){return;}
goto sss3;
}
//扫描第3列
WR273=0x07;
for(ki=0;ki<10;ki++);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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)
{
// 在没有超过双击等待时间内检测到再次按键,把标志改为并设置时间等待释放
key2doubleflag=1; key2downtime=G_timebase; return NOKEY;
}
else
{
// 超了时间,属于新的一次按键startkey2flag=1;
key2doubleflag=0; key2downtime=G_timebase;
shortkey2flag=0;
return NOKEY;直接判断
1,
}
}
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;
}。