这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 34岁“高龄”学习单片机,以此贴记录重难点,坚持!坚持!、

共49条 4/5 |‹ 1 2 3 4 5 跳转至
菜鸟
2014-05-13 20:35:32     打赏
31楼
矩阵键盘检测。
视频里现场写的代码给弄复杂了,难理解,简化一下以后好多了
主要就是那个与操作是不必要的。把按键取出的数与了以后,最后还要再重新从P3口取完整的数。因为如果不重新取P3口完整的值,会导致扫描2 、3、4行时取得同样的值。比如第一行第一个键被按下取的值是0xee,和0xf0与操作后得到0xe0。扫描第2行时,按下第一个键,取得的值是0xed,和0xf0与操作后仍然是0xe0,剩下的也同样。就没法区分了。
所以完全没必要做“与”操作,增加了复杂性,还容易出错。第一行直接判断是否为0xfe,第二行直接判断是否为0xfd,以此类推,就可以了。

#include
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;
sbit wei=P2^7;
sbit d1=P1^0;
uchar temp,num;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint);
void main()
{
wei=1;
P0=0xc0;
wei=0;
duan=1;
P0=0x00;
duan=0;
while(1)
{
/* P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0) *///这里视频写的“与”操作根本多余的吧,改掉~~。
P3=0xfe; //第一行赋值为0,P3值即为0xfe
temp=P3;
if(temp!=0xfe) //如果为真,则执行if{}内代码,如果为假,
//则跳出if{}执行(去检测第2行按键有没有被按下)
{ //视频里用while循环,感觉用if好点
delay(5);
temp=P3;
//temp=temp&0xf0;
//if(temp!=0xf0)
if(temp!=0xfe)
{
temp=P3;//取回P3口的值(有可能是按下某件得到的值,必须要取),在swith case语句中进行比较。
switch(temp)
{
case 0xee:num=0;
break;
case 0xde:num=1;
break;
case 0xbe:num=2;
break;
case 0x7e:num=3; //分别比较几个算好的码,相同则赋给相关的值,并将其值赋给num,以方便显示时调用。
break;
}

duan=1;
P0=table[num];//打开段选口,让P0口显示数值
duan=0; //注意,这里,必须放在最里面的if下,否则逻辑出问题。
while(temp!=0xfe)//松手检测。
{
temp=0xfe;
}
}
}

P3=0xfd; //将第2行赋值为0,P3口的值即为0xfd
temp=P3;
if(temp!=0xfd) //开始扫描第2行有无键按下
{
delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xfd)
{
temp=P3;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=7;
break;
}

duan=1;
P0=table[num];
duan=0;
while(temp!=0xfd)
{
temp=0xfd;
}
}
}

P3=0xfb; //开始扫描第三行有无键按下
temp=P3;
if(temp!=0xfb)
{
delay(5);
temp=P3;

if(temp!=0xfb)
{
temp=P3;
switch(temp)
{
case 0xeb:num=8;
break;
case 0xdb:num=9;
break;
case 0xbb:num=10;
break;
case 0x7b:num=11;
break;
}

duan=1;
P0=table[num];
duan=0;
while(temp!=0xfb)
{
temp=0xfb;

}
}
}

P3=0xf7; //开始扫描第4行有无键按下
temp=P3;
if(temp!=0xf7)
{
delay(5);
temp=P3;
if(temp!=0xf7)
{
temp=P3;
switch(temp)
{
case 0xe7:num=12;
break;
case 0xd7:num=13;
break;
case 0xb7:num=14;
break;
case 0x77:num=15;
break;
}

duan=1;
P0=table[num];
duan=0;
while(temp!=0xf7)
{
temp=0xf7;
}
}
}


}

}
void delay(uint z) //延迟子程序
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}


菜鸟
2014-05-13 21:02:53     打赏
32楼

前面没弄明白的都理清了,真的很轻松,晚上睡个好觉了。

帖子也不是我的笔记本,没事大家都可以进来聊聊自己啊,有空多交流交流,说不定就碰出点火花 呵呵

    

 


菜鸟
2014-05-16 18:44:41     打赏
33楼
不是太明白您后面说的PA8个pin&PB^0的意思~ 不过一组I/O口只有8个,5*4的话,第5个口只能接另外的I/O口当做独立键盘单独处理了吧? 也许有其他更好办法,我知识还浅不清楚了就

菜鸟
2014-05-16 18:47:14     打赏
34楼
谢谢

菜鸟
2014-05-16 18:52:29     打赏
35楼
呵呵 最近累的够呛,昨天休息一天爬山去了 今天A/D D/A看完了 继续更 话说就隔了这么一天 写代码就生了很多 真是拳不离手曲不离口啊 

菜鸟
2014-05-16 18:54:12     打赏
36楼
感谢支持!受教什么的岂敢啊~呵

菜鸟
2014-05-16 18:59:54     打赏
37楼
感谢!已经在看了,不过还是有点难理解,基础欠缺~ 不过也不着急,我准备等这阶段完了就看模电和数电。有时间的话再看看汇编。  

菜鸟
2014-05-16 19:09:53     打赏
38楼
第6课课间作业。利用D/A模块实现发光二极管在2秒内逐渐变亮,达到最亮时再在2秒内逐渐变暗。保持循环。
因为这是自己没有跟着视频写的第一个完整的程序,也算零的突破.经过仿真验证没有问题。值得纪念一下。
另外,看来直接对P0口赋10进制的值是没问题的(以前还一直以为对I/O口的操作只能用16进制,囧)。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit csda=P3^2;
sbit wr=P3^6;
sbit duan=P2^6;
sbit wei=P2^7;
int num;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
duan=0;  
wei=0;      //关闭位选和段选,否则信号会串到数码管上。
num=0;
while(1)
{
csda=0;   //打开D/A片选
wr=0;    //写信号置低电平

if(num==0)    //判断,当num为0时      
{
while(num<255) 
{
num=num+5;    //num自加5
P0=num;     //每次执行到此,将加5后的num赋值给P0口。除非num值等于255推出循环进入下面程序。
delay(40); //延迟40ms ,控制变化速度
}
}

if(num==255)
{
while(num>0)
{
num=num-5;
P0=num;
delay(40);
}
}

}
}

菜鸟
2014-05-16 19:25:42     打赏
39楼

晚上就不看书了,论坛订的开发板散件到货,争取晚上给搞定,呵呵

上张全家福!老板不错,元件有不少都还给了备份!给个赞!

不过包装要改进,单片机底座的针脚全都60度了~

万事俱备,只是镊子找不着了。拿老婆的眉毛夹磨一磨试试看

 


菜鸟
2014-05-18 05:43:28     打赏
40楼
网盘无论如何都共享不成功,也不知道为什么。你需要什么资料?我单独发邮箱吧

共49条 4/5 |‹ 1 2 3 4 5 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]