myvioletchen
发表于 2010-6-11 09:31:07
楼主好人啊!支持!
jjinhuang
发表于 2010-6-11 10:06:00
嗯嗯。希望集合成个合集的!支持!!
ITOP
发表于 2010-6-11 10:44:43
学习了!!
ball648500361
发表于 2010-6-11 19:01:39
mark
linhai
发表于 2010-6-11 19:16:17
谢谢
lerysun
发表于 2010-6-11 20:34:29
mark 好贴…… 建议加精
gxy508
发表于 2010-6-12 14:46:13
mark
liangtao
发表于 2010-6-12 16:12:16
mark
electricit
发表于 2010-6-12 16:34:27
mark
hhui02
发表于 2010-6-12 17:23:09
学习了,谢谢。
Linfanfeng
发表于 2010-6-12 17:55:10
我也觉得现在在网上的资料要么是供初学者用的,要么是功能很强,但是只是演示性质(晒),或者是卖广告的。
幸亏我们这个论坛的高手们都不吝赐教啊!代表所有初学者向你们致敬!
再说说楼主所提到的释放CPU、按键处理,我简单地说说我的看法(仅供参考)。
释放CPU:在你所建立的工程不是很复杂并且实时性要求不高的时候,你不懂这个概念的话貌似问题不大,但是倘若你所设计的系统实时性要求较强时,你没有考虑过释放CPU,那你做出来的系统将是问题多多的。
举个例子:做一个简单的门禁系统(真的是很简单的,高手们看到不能偷笑哦),有上位机、下位机,下位机需要串口与上位机进行通讯,两者的通讯协议是多字节的帧结构;下位机需要扫描按键,检查是否有按键按下,按键是由数字键和几个功能键组成;还要LCD显示。
对于这个系统,按键扫描可采用“零耗时扫描”以及查表法来选择返回键码值的方式,这样设计的话,按键消抖处理的延时就可以用定时器来完成,不用CPU去软件延时;键盘扫描利用查表法的话,可以使得程序结构简单,不用太多的重复,也不用一大堆switch{case:……}结构,整个键盘扫描程序就一个循环查表搞定。
与上位机通信这个模块,可以声明两个缓冲区,一个缓冲区(buffer1)是放置当前在接收中的帧,另外一个(buffer2)是放置已经接收完的帧。帧接收工作最好放在串口中断中完成,当接收完成即将buffer1的内容转到buffer2当中去,并将接收完成标志置1,让主程序去处理帧。
如此一来,主程序就没有延时语句,就是循环判断各个标志位,若标志有效才去工作。
按键处理:对于4X4键盘,可能很多像我一样的初学者都用或者用过类似下面程序的方法去扫描。下面说说基于查表法的键盘扫描方法
unsigned char key_check(void)
{
unsigned char code table[]={0x01,0x02,0x03,0x0a,
0x04,0x05,0x06,0x0b,
0x07,0x08,0x09,0x0c,
0x0f,0x00,0x0e,0x0d};
unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char key_number=0xff;
unsigned int kk=0;
while(kk<=2)
{
kk=kk+1;
P2=0xff;
P2_4=0;
temp=P2;
temp=temp&0x0f;
if (temp!=0x0f)
{
for(i=100;i>0;i--)
for(j=200;j>0;j--);
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P2;
temp=temp&0x0f;
switch(temp)
{
case 0x07:
key=0;
break;
case 0x0b:
key=4;
break;
case 0x0d:
key=8;
break;
case 0x0e:
key=12;
break;
default:
break;
}
temp=P2;
key_number=table;
temp=temp&0x0f;
while(temp!=0x0f) //等待按键放开
{
temp=P2;
temp=temp&0x0f;
}
return key_number;
}
}
P2=0xff;
P2_5=0;
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=100;i>0;i--)
for(j=200;j>0;j--);
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P2;
temp=temp & 0x0f;
switch(temp)
{
case 0x07:
key=1;
break;
case 0x0b:
key=5;
break;
case 0x0d:
key=9;
break;
case 0x0e:
key=13;
break;
}
temp=P2;
key_number=table;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P2;
temp=temp&0x0f;
}
return key_number;
}
}
P2=0xff;
P2_6=0;
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P2;
temp=temp & 0x0f;
switch(temp)
{
case 0x07:
key=2;
break;
case 0x0b:
key=6;
break;
case 0x0d:
key=10;
break;
case 0x0e:
key=14;
break;
}
temp=P2;
key_number=table;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P2;
temp=temp & 0x0f;
}
return key_number;
}
}
P2=0xff;
P2_7=0;
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=100;i>0;i--)
for(j=200;j>0;j--);
temp=P2;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P2;
temp=temp & 0x0f;
switch(temp)
{
case 0x07:
key=3;
break;
case 0x0b:
key=7;
break;
case 0x0d:
key=11;
break;
case 0x0e:
key=15;
break;
}
temp=P2;
key_number=table;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P2;
temp=temp & 0x0f;
}
return key_number;
}
}
}
return 0xff;
}
查表键盘扫描法:
首先,先建立一个表,
//键盘扫描所用的表格
//格式:输出值、输入值、对应的键码
unchar code KeyScanTable={
0xef,0x0e,0x00,
0xef,0x0d,0x04,
0xef,0x0b,0x08,
0xef,0x07,0x0c,
0xdf,0x0e,0x01,
0xdf,0x0d,0x05,
0xdf,0x0b,0x09,
0xdf,0x07,0x0d,
0xbf,0x0e,0x02,
0xbf,0x0d,0x06,
0xbf,0x0b,0x0a,
0xbf,0x07,0x0e,
0x7f,0x0e,0x03,
0x7f,0x0d,0x07,
0x7f,0x0b,0x0b,
0x7f,0x07,0x0f};
然后在键盘扫描程序里面就只需要一个循环去查表即可(注意下面的程序是没有消抖处理的,是在定时器中断服务程序中调用)
unchar KeyScan_No_Delay()
{
unchar i,base_addr;
unchar data_in;
P2=0x0f;
if(P2==0x0f) //说明没有按键按下
return 0xff;
for(i=0;i<=0x0e;i++)
{
base_addr=i*0x03;
P2=KeyScanTable; //输出
_nop_();
_nop_();
data_in=P2; //读入
if(data_in==KeyScanTable) //比较,若相同则返回对应的键码
return KeyScanTable;
}
}
写地不好,请见谅。
That's all.(别拍砖呐!./emotion/em007.gif)
markloveyou
发表于 2010-6-12 19:01:09
写得很实际
07636678
发表于 2010-6-12 19:44:59
ding
07636678
发表于 2010-6-12 21:16:36
我的是用Keil uVision2好像建不起你那个模板,是不是一定要你那个版的KEIL才行啊?
chenzy
发表于 2010-6-13 12:57:59
不错,定一个
hwx123
发表于 2010-6-13 22:15:38
LZ,能否发个带组合键功能的按键扫描程序让大家学习学习
xiaohutu
发表于 2010-6-13 23:00:51
感谢分享。。。
liuyun_1969
发表于 2010-6-14 12:03:58
写的真好。我正在做一个项目。发现例程只是教你理解。而实际中根本不能那样用。是呀,CPU有很多事情要做,你得大致估算执行任务的时间,要尽量减少程序对CPU的占用。更不允许让CPU死等的情况。支持支持。
t632159
发表于 2010-6-14 18:59:22
恩,正在学习,期待后续!!!!
Linfanfeng
发表于 2010-6-17 00:53:38
写得非常好!希望LZ能够打包上传提供下载啊
iamwangwei
发表于 2010-6-18 09:48:17
回复【199楼】xuesongrenjun
-----------------------------------------------------------------------
非常好,学习。
shenzhenlang
发表于 2010-6-18 17:37:46
学习中
wjs1981
发表于 2010-6-19 15:50:08
mark
hopkins
发表于 2010-6-19 17:14:50
mark
hpdell
发表于 2010-6-19 17:52:35
不错哟!!!!!!!!!
zhangfuhg
发表于 2010-6-19 19:12:05
太好了!!!!!!!!!
KevinLee
发表于 2010-6-19 19:27:34
感谢分享。
ababvic
发表于 2010-6-19 22:58:49
mark
xslff
发表于 2010-6-19 23:39:21
一语点中要害!
wxx116zh
发表于 2010-6-20 20:37:26
学习了。。
ilovezeno
发表于 2010-6-20 21:55:37
其实农民_运动讲习所的那个经典文章更加透彻。。。。。
mdj-fish
发表于 2010-6-20 22:38:27
其实农民_运动讲习所的那个经典文章更加透彻。。。。。
myworkmail
发表于 2010-6-21 00:29:50
支持
xinyou
发表于 2010-6-21 08:58:18
学习了…
jring2002
发表于 2010-6-21 16:05:27
回复【139楼】tangwei039
-----------------------------------------------------------------------
TH0 = 255-CLOCK/TIME_PER_SEC/12/256;
//CRY_OSC,TIME_PER_SEC在 os_cfg.h中定义
TL0 = 255-CLOCK/TIME_PER_SEC/12%256;
什么意思?
jring2002
发表于 2010-6-21 17:27:51
回复【楼主位】tangwei039
-----------------------------------------------------------------------
为何初值如此计算?
jring2002
发表于 2010-6-24 17:23:13
初值应该是这样 TH0=(65535-clock/time_per_sec/12)/256;
TL0=(65535-clock/time_per_sec/12)%256;
cocoasuny
发表于 2010-6-25 23:43:46
PDF呢??
KR770906
发表于 2010-6-26 13:33:37
和lz同感
liok
发表于 2010-6-26 15:14:23
楼主,各位牛人,有一段代码没看懂,帮忙解答一下:
while(1)
{
Timer0MainLoop() ;
KeyMainLoop(&KeyValue) ;
if(KeyValue == (KEY_VALUE_1 | KEY_DOWN)) P0 = ~1 ;
if(KeyValue == (KEY_VALUE_1 | KEY_LONG)) P0 = ~2 ;
if(KeyValue == (KEY_VALUE_1 | KEY_CONTINUE)) { P0 ^= 0xf0;}
if(KeyValue == (KEY_VALUE_1 | KEY_UP)) P0 = 0xa5 ;
}
这是楼主写的KEY第二章里面的一段代码,但是在这个主程序中有一个子函数的调用我没看懂
Timer0MainLoop() ;
这个子函数的源代码是什么?放在这里的功能是什么?
请各位帮忙解答一下!谢谢!
qtds11
发表于 2010-6-28 17:27:52
顶一个标记,刚工作慢慢学习
hanzhifei_2004
发表于 2010-6-29 00:45:54
楼主很强悍,我深有同感,向楼主学习
Linfanfeng
发表于 2010-6-30 15:09:39
希望LZ打包上传提供下载的顶起!
./emotion/em018.gif
./emotion/em018.gif
./emotion/em018.gif
zgcumt
发表于 2010-6-30 15:37:42
mark
zjj2010
发表于 2010-6-30 22:44:46
记号
Imcu
发表于 2010-7-1 10:31:56
太好了
xytzc
发表于 2010-7-1 12:04:45
从上班看到下班还没看完,很是受益,做个记号,感谢楼主!
sharp0
发表于 2010-7-1 15:35:16
楼主热心肠,支持!
hanzhifei_2004
发表于 2010-7-1 21:36:04
回复【342楼】liok
-----------------------------------------------------------------------
Timer0MainLoop() ;
函数是一个20ms的系统周期,
还有我的板子要改成
if(KeyValue == (KEY_VALUE_1 & KEY_DOWN)) P0 = ~1 ;
if(KeyValue == (KEY_VALUE_1 &KEY_LONG)) P0 = ~2 ;
if(KeyValue == (KEY_VALUE_1 & KEY_CONTINUE)) { P0 ^= 0xf0;}
if(KeyValue == (KEY_VALUE_1 & KEY_UP)) P0 = 0xa5 ;
功能才能实现;
zsgood6688
发表于 2010-7-2 17:30:43
不错
gmolzc
发表于 2010-7-2 17:49:21
頂,有時間好好看看!!!
pan90
发表于 2010-7-3 13:04:35
mark
qianlihu
发表于 2010-7-9 11:58:20
回复【楼主位】tangwei039
-----------------------------------------------------------------------
mark it
danielzhuang
发表于 2010-7-9 14:37:53
支持下了1
wxx116zh
发表于 2010-7-9 20:06:35
mark
liok
发表于 2010-7-10 13:04:26
回复【350楼】sharp0
-----------------------------------------------------------------------
那请问:
Timer0MainLoop() ;
这个函数放这里就只是起一个延时作用还是里面有其他什么功能,麻烦了!希望您能说明一下!谢谢!
zhaopapaya
发表于 2010-7-12 11:32:39
好啊,关注
l.htlht
发表于 2010-7-12 12:21:47
从单片机初学者迈向单片机工程师
liumaojun_cn
发表于 2010-7-12 13:18:26
mark
lusen
发表于 2010-7-12 15:05:34
茅塞顿开
shenqibuhui
发表于 2010-7-15 23:27:06
顶一下楼主~~~~~
gmolzc
发表于 2010-7-16 08:30:46
頂!強烈支持!
worldwindhuu
发表于 2010-7-16 16:18:53
顶!
hefei1314
发表于 2010-7-16 18:06:36
不错
zqd311107
发表于 2010-7-17 09:22:22
不错
zqq823557482
发表于 2010-7-17 16:11:38
mark
gyzzg2030
发表于 2010-7-17 16:30:27
学习,再学习
yasewang2
发表于 2010-7-20 18:38:47
这个必须顶
qq335702318
发表于 2010-7-21 00:16:35
mark
书本学不到的!!极为有用~~~~~~~~~~
aqjinhu
发表于 2010-7-21 11:30:06
怎么没复位电路的硬件设计啊?
zidong_MCU
发表于 2010-7-21 12:50:33
mark!!!!!!!!!!!
xujc0806
发表于 2010-7-22 15:40:14
怎么不传了啊,写的很好
Rocker
发表于 2010-7-22 16:03:56
咋不出本书呢?
watts_007
发表于 2010-7-22 17:14:31
留印,有更新一定看
rgb0
发表于 2010-7-22 18:59:56
谢楼主,MARK,收了
yasewang2
发表于 2010-7-22 19:38:06
请问这些知识,有哪些书本上提到过吗,或者说想学更高级的编程知识上哪去学,国外有好的网站吗
mcu_mouse
发表于 2010-7-30 20:48:31
mark
billiejean
发表于 2010-7-30 23:38:29
好贴,收藏了,本人初学
czg_82
发表于 2010-7-31 16:10:54
不错,受益匪浅!
gasolhu
发表于 2010-7-31 21:37:25
留标记
xyyjjb
发表于 2010-7-31 23:22:55
Mark
qilujie
发表于 2010-7-31 23:23:38
这些我觉得是初学者都应该会的。⊙﹏⊙b汗
some9009
发表于 2010-8-1 02:52:01
Mark
yesjustme1
发表于 2010-8-1 14:37:49
我决定了,摒弃从前,着眼此处,从头再学!哈哈
hexi8511
发表于 2010-8-1 17:35:04
期待楼主继续更新啊
ddaitt999
发表于 2010-8-1 17:56:10
这个牛
2006lc
发表于 2010-8-1 21:38:37
有启发
tangshanqiang
发表于 2010-8-2 11:07:57
强烈感谢楼主,强烈要求给一个cool,希望楼主能打包上传更多资料,顶。。。。。。。。。。。。。。。。
poet_lee
发表于 2010-8-3 10:14:01
好贴子 讲的不错
jinbangzhou
发表于 2010-8-3 10:35:02
mark
zwdxsky
发表于 2010-8-6 22:50:35
好好学习!
Mr_Cool
发表于 2010-8-7 01:54:14
激_情贴!顶!为人民服务!
zxycba
发表于 2010-8-9 11:22:45
一路走过,深有感触。希望大家继续把楼主顶出来!哈哈
youdianchedan
发表于 2010-8-9 16:17:08
谢谢楼主。
光那一段按键的程序都看了一个多小时才看明白,惭愧。
不过受益良多,继续看。
maxuedong
发表于 2010-8-10 13:02:04
学习中,顶!!
tianyi996
发表于 2010-8-10 21:10:46
回复【楼主位】tangwei039
-----------------------------------------------------------------------
LZ啊
后面的怎么没发
期待你重出江湖啊
wgm_123
发表于 2010-8-11 10:22:55
楼主的红外解码教程呢?楼主,快来看看那,这么多人在等候你的大作,快点儿啊,谢谢你对我们的帮助。
hope0903
发表于 2010-8-11 10:59:27
期待LZ的全套PDF!
tianyuanqike
发表于 2010-8-11 11:51:03
等我有成就了,在来回看此帖,谢谢您!
nanan1211
发表于 2010-8-11 15:45:21
学习了
页:
1
2
3
[4]
5
6
7
8
9
10
11
12
13