找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2603|回复: 8
打印 上一主题 下一主题
收起左侧

新人,关于51单片机的程序有些地方不懂,请高手给指点。

[复制链接]
跳转到指定楼层
楼主
ID:231688 发表于 2017-9-7 16:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
宋老师的《手把手教你学51单片机》中第7章中,有一段关于扫描确认按键矩阵的程序,如下:
#include<reg52.h>
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY_IN_1 = P2^4;
sbit KEY_IN_2 = P2^5;
sbit KEY_IN_3 = P2^6;
sbit KEY_IN_4 = P2^7;
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2;
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;
unsigned char code LedChar[]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char KeySta[4][4] = {
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
void main()
{
unsigned char i, j;
unsigned char backup [4][4] = {
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};

EA = 1;
ENLED = 0;
ADDR3 = 1;
ADDR2 = 0;
ADDR1 = 0;
ADDR0 = 0;
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x67;
ET0 = 1;
TR0 = 1;
P0 = LedChar[0];
while(1)
{
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(backup[ i][j] != KeySta[ i][j])    这一段中,KeySta[ i][j])并没有被声明对应哪个按键的输入,那么当某个按键动作时,程序如何能检测到?
{
if(backup[ i][j] == 0)
{
P0 = LedChar[i*4+j];
}
backup[ i][j] = KeySta[ i][j];
}
}
}
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char keyout = 0;
unsigned char i = 0;
static unsigned char keybuf[4][4] = {
{0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF}
};

TH0 = 0xFC;
TL0 = 0x67;
keybuf[keyout][0] = (keybuf[keyout][0] <<1) | KEY_IN_1;  这一段的作用是“将一行的4个按键值移入缓冲区”,可我看不懂这句程序,高手能否给解答下?
keybuf[keyout][1] = (keybuf[keyout][1] <<1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] <<1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] <<1) | KEY_IN_4;

for(i=0; i<4; i++)
{
if((keybuf[keyout][ i] & 0x0F) == 0x00)
{
KeySta[keyout][ i] = 0;
}
else if((keybuf[keyout][ i] & 0x0F) == 0x0F)
{
KeySta[keyout][ i] = 1;
}
}
keyout++;
keyout = keyout & 0x03;
switch(keyout)
{
case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
default: break;
}
}
        以上这段程序我根本没吃透,暂时有两个问题在程序里用红字标注出来了,还望高手给指点下,谢谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:231633 发表于 2017-9-7 17:36 | 只看该作者
我就解释一下这个问题把:
keybuf[keyout][0] = (keybuf[keyout][0] <<1) | KEY_IN_1;  这一段的作用是“将一行的4个按键值移入缓冲区”,可我看不懂这句程序,高手能否给解答下?

回答如下:
keybuf[keyout][0]  首先左移一位,那么变量的最低位就会空出来(指的是没有实际意义),此时又进行了一个“逻辑加”操作,相当于把KEY_IN_1(也就是对应的IO口)状态放到了变量的最低位,这样,一个状态就保存到了变量中了。如此看来,一个变量可以保存8个Bit,也就是8个状态信息。


建议:
学单片机,刻苦钻研值得鼓励!不过我不建议在没有实际需求的前提下搞这些,你也看到了,你现在仅仅是阅读了,而且不懂。试想一下,当你想解决一个问题的时候,你再来看这段代码,可能理解就不一样了。这段代码作用就是把几个IO口的状态保存到一个变量里面,便于处理。

评分

参与人数 2黑币 +58 收起 理由
张小帅1126 + 8 很给力!
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:231688 发表于 2017-9-7 18:41 | 只看该作者
零妖 发表于 2017-9-7 17:36
我就解释一下这个问题把:
keybuf[keyout][0] = (keybuf[keyout][0]

您好,您解答的非常好,我一下就明白了,非常感谢啊!还有就是,我看这个单片机的目的还是有的,不过我不是为了搞单片机,而是为了学PLC和数据通信。但是我这个人比较笨,那些PLC和数据通信的书又大都写的比较晦涩,看起来比较费劲。宋老师的这本《手把手》感觉借鉴了老外的教学模式,力求浅显化。我看这本书,一是打打相关基础,二是开拓下思路,感觉还是有收获的,毕竟很多东西都是相通的。怎奈他的这书在有些地方却未讲解到位,甚至根本就没有讲,所以就卡住了。不过还好有论坛,有很多像您这样的热心高手,那我就更应该努力学习,积极请教了。
回复

使用道具 举报

地板
ID:231688 发表于 2017-9-7 18:47 | 只看该作者
那么我的第一个问题,就是关于 KeySta[ i][j],这个自定义变量在整个程序中根本就没有被定义跟任何按键的输入有关,那么程序如何识别它是在进行按键状态的扫描呢?
回复

使用道具 举报

5#
ID:231688 发表于 2017-9-8 00:37 | 只看该作者
不好意思,我搞明白了,在中断程序里,KeySta[keyout][ i] = 0;或KeySta[keyout][ i] = 1;
回复

使用道具 举报

6#
ID:111634 发表于 2017-9-9 17:14 | 只看该作者
本帖最后由 zl2168 于 2017-9-10 09:34 编辑

这样没有注解的书,没有老师讲解辅导,学生能理解吗?给你介绍2本便于自学的书。张志良编著的:《80C51单片机实用教程——基于Keil C和Proteus》高等教育出版社ISBN 978-7-04-044532-9, 用于学习51单片机原理,程序(双解c和汇编)语句条条有注解,便于阅读理解,便于自学。《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,可演示,可观测,电路与程序真实可靠可信可行,程序语句条条有注解
新华书店翻阅,看看是否合意,还可与其他书比较一下,有比较才能有鉴别!绝不忽悠你!
回复

使用道具 举报

7#
ID:231688 发表于 2017-9-11 00:25 | 只看该作者
zl2168 发表于 2017-9-9 17:14
这样没有注解的书,没有老师讲解辅导,学生能理解吗?给你介绍2本便于自学的书。张志良编著的:《80C51单片 ...

十分感谢啊,我一定去看看您给推荐的书。不过啊,这里也是有些冤枉宋老师了,他的书里的程序还是有注解的,只是有些地方没有点到,我发的程序是在网上复制的,内容一样的,但是缺少了注解。可能宋老师觉得天下不会有太笨的学生吧,但恰恰我就是了。进步还是有的,但也确实在某些方面感到吃力,感觉功夫还是没下够。
我现在感觉《手把手教你学51单片机》这本书的优点:借鉴了欧美的教学模式,一切以便于理解吸收为前提,而不是像国内很多书,生怕你没把他当教授,写的书晦涩难懂!缺点:在一些比较难的点上反而讲解的不够或者根本就没有讲解,导致我经常性卡壳。以上共大家借鉴,感觉也确实应该参考下其他书籍,互补一下比较好。
回复

使用道具 举报

8#
ID:232442 发表于 2017-9-11 17:25 | 只看该作者
een  学习了
回复

使用道具 举报

9#
ID:232442 发表于 2017-9-11 17:26 | 只看该作者
在中断程序
KeySta[keyout][ i] = 0;
KeySta[keyout][ i] = 1;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表