1

关于投票
单片机驱动标准PC机键盘的C51程序
功能:实现pc机键盘(p/s2接口)与8位单片机连接使用
原理:键盘时钟接在p3.2口,既8051的外部中断int0上,键盘数据接到p1.0上
每次按键,键盘会向单片机发脉冲使单片机发生外部中断,数据有p1.0口一位一位传进来
传回的数据格式为:1位开始位(0),8位数据位(所按按键的通码,用来识别按键),1位
校验位(奇校验)
1位结束位(1)
实现:将键盘发回的数据放到一个缓冲区里(数组),当按键结束后发生内部中断来处理所
按的按键
缺点:由于51单片机的容量有限所以缓冲区不可以开的太大,这就导致可以记录键盘的按键
次数过少,
也就是容错性一般。不过如果正常使用键盘是不会出错的
================================================================================
====================*/</P><P>//#include"reg51.h"
#include "intrins.h"
#include "ku.h" //按键通码与ascii对照表
sbit sda= p1^0; //键盘数据线</P><P>unsigned char dat=0,dat1=0,dat2=0; //接收键盘
数据变量? 存储通码变量 接受连续通码变量
unsigned char count=0,num=9,temp[5],shu=0; //中数次数 中断控制变量 缓冲区数组 缓
冲区指针
unsigned char key=0; //按键最终值</P><P>void zhongduan() interrupt 0 //外部中断
0 用来接受键盘发来的数据
{
dat>>=1; //接受数据 低->高
if(sda) dat|=0x80;
count++;
if(count==num)
{
if(count==9)
{
dat1=dat; //中断9次后为键盘所按按键的通码(开始位始终为0在第一次中断时右移中忽
略)
num=20; //使中断可以继续中断11次
}
if(count==20)
{
dat2=dat; //取回第二个通码
if(dat1==0xe0 || dat2==0xf0) //第一个通码是0xe0则证明所按按键为功能键,第二个通
码是0xf0证明按键结束
{
temp[shu]=dat1;temp[shu+1]=dat2; shu+=2; //将所按按键存到缓冲区中
ie=0x82; //关闭外部中断并打开内部中断来处理所按按键
tr0=1;
}
else
{
temp[shu]=dat1;temp[shu+1]=dat2; shu+=2; //如果shift键被按下则记录与它同时按下的
那个键
count=0;
}
if((temp[0]==18 || temp[0]==89) && (temp[2]==18 || temp[2]==89) ) tr0=1; //如果
缓冲区中有两个间隔的shift键则证明需要的铵键结束
}
}
}</P><P>
void getkey() interrupt 1 //内部中断0 用来处理缓冲区里的数据
{
unsigned char i=0;
tr0=0;
th0=0;
tl0=0;
count=0; //中断记数则0
if((temp[0]==18 || temp[0]==89) && temp[1]!=0xf0 ) //shift被按下

for(i=0;i<21;i++)
{
if(addshift[i][0]==temp[1]) //搜索shift被按下的表
{
key=addshift[i][1];
ie=0x83; //打开外部中断
return;
}
}
}
else if(temp[0]==0xe0) //所按下的按键是功能键
{
for(i=0;i<80;i++)
{
if(noshift[i][0]==temp[1]) //功能键的通码在缓冲区的第二位
{
key=noshift[i][1];
ie=0x83;
return;
}
}
}
else //普通按键
{
for(i=0;i<80;i++)
{
if(noshift[i][0]==temp[0]) //普按键的通码在缓冲区的第一位
{
key=noshift[i][1];
ie=0x83;
return;
}
}

for(i=0;i<5;i++) 
{
temp[i]=0;

}
系统分类: 单片机
用户分类: 无分类
标签: 无标签
来源: 转贴
发表评论 阅读全文(146) | 回复(1)

0

关于投票
串行驱动led显示
//一个74hc595位移寄存器驱动三极管驱动led位,
//两个74hc595驱动led段,方式位5位x8段x2=10个数码管
//5分频,每次扫描时间位1.25ms


//定义特殊符号

#define nul 0xf
#define qc 0xc
#define qb 0xb
#define q_ 0xa
#define q__ 0xd
#define q___ 0xe
#define qp 0x10
#define qe 0x11
#define qj 0x12
#define qn 0x13
#define qf 0x14
#define qa 0x15
#define qr 0x16
#define qd 0x17
#define qu 0x18
#define ql 0x19
#define qh 0x1a
#define qwen 0x1b
#define qt 0x1c
#define qla 0x1d
#define qlb 0x1e
#define qlc 0x1f
#define qld 0x20
#define qle 0x21
#define qlf 0x22
#define qlg 0x23
#define qldp 0x24


//显示段信息,不同led排列组合的段信息只需更改8个数值即可。
//因此,该定义具有通用性。

// 显示 
//  -d 20
// |c 40 |e 10
//  - g  80  
// |b 2 |f 4
//  _a1 .dp 8
#define pa 1
#define pb 2
#define pc 0x40
#define pd 0x20
#define pe 0x10
#define pf 4 
#define pg 0x80
#define pdp 8

//--------------
#define l0 pdp+pg
#define l1 255-pf-pe
#define l2 pdp+pc+pf
#define l3 pdp+pc+pb
#define l4 pdp+pa+pb+pd
#define l5 pdp+pb+pe
#define l6 pdp+pe
#define l7 pdp+pc+pg+pb+pa
#define l8 pdp
#define l9 pdp+pb
#define la pdp+pa
#define lb pdp+pd+pe
#define lc pdp+pg+pe+pf
#define ld pdp+pc+pd
#define le pdp+pe+pf
#define lf pdp+pe+pf+pa
#define l_ 255-pg
#define lnul 255
#define ll pdp+pg+pd+pf+pe
#define lp pdp+pa+pf
#define lt pdp+pd+pe+pf
#define lr pdp+pe+pf+pg+pa
#define ln pdp+pg+pa
#define lh pdp+pd+pe+pa
#define ly pdp+pb+pd
#define lu pdp+pg+pd
#define l__ pdp+pg+pb+pc+pe+pf
#define l___ l__-pg
#define l_1 255-pa
#define l_2 255-pa-pg
#define lj 255-(pe+pf+pa)
#define lwen 255-(pd+pe+pg+pb)
#define lall 0


#define lla 255-pa
#define llb 255-pb
#define llc 255-pc
#define lld 255-pd
#define lle 255-pe
#define llf 255-pf
#define llg 255-pg
#define lldp 255-pdp


//串行送出的位信息,目前是10位led显示。
unsigned char code un_dig[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb};
//串行送出的短信息。
unsigned char code un_disp[]={l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l_,lb,lc,l__,l___,lnul,lp,le,lj,ln,lf,la,lr,ld,lu,
ll,lh,lwen,lt,lla,llb,llc,lld,lle,llf,llg,lldp,lnul};




sbit d_clk=P0^0;  //移位时钟
sbit d_dat=P0^1;  //移位数据
sbit d_st=P0^2;   //移位锁定


unsigned char dig;   //位扫描计数器
unsigned char d[10];       //显示缓冲

//送出8位串行数据
void out_disp(unsigned char dd) {
 unsigned char i;
 for (i=0;i<8;i++) {
  if (dd&1) d_dat=1; else d_dat=0;
  d_clk=0;
  dd>>=1;
  d_clk=1;
 }
}
//控制小数点和闪烁,显示数据|0x040表示有小数点;显示数据|0x80表示闪烁。
void out_displ(unsigned char dd) {
 if (dd>=0x80) {
  if (s001>flash_time) {out_disp(0xff);return;}
 }
 dd&=0x7f;
 if (dd>=0x40) {
  dd=un_disp[dd&0x3f]^pdp;
 } else dd=un_disp[dd];
 out_disp(dd);
}





unsigned int s001; //闪烁时间参考
void int_t0(void) interrupt 1 {
 unsigned char dd;
 TL0=TL0+30;TH0=0xfb; //800
 time++;
 if ((++s001)>=800) s001=0;
 // 显示 
 if ((++dig)>4) dig=0;
 d_st=0;
 dd=d[dig+5];
 out_displ(dd);
 dd=d[dig];
 out_displ(dd);
 out_disp(un_dig[dig]);
 d_st=1;
}
void main(void) {
 unsigned char i;
 TMOD=0x1;
 TR0=ET0=1;
 EA=1;
 for (i=0;i<10;i++) d[i]=i; //display test
 while (1) {}
}
系统分类: 单片机
用户分类: 单片机
标签: 无标签
来源: 整理
发表评论 阅读全文(134) | 回复(0)

0

关于投票
老师是这么教我们进修单片机的

看到不少网友都在问怎样提高自己的能力,我在这里想谈一下我自己当年的学习过程。

我学的是计算机系的通讯工程专业,主要的发展方向是做计算机网络偏软件这一块,这点从我的毕业设计课题《宾馆客房管理系统》就能看出来。

因为带到通讯,所以学校里也教数电模电单片机什么的。其中《单片机和通讯接口》这门课我学到了很多东西,可以说,整个大学觉得最有收获的就是这门课。

我的老师上课很有特性,首先没有教材,理由是现在技术一日千里,等到教材出来就已经淘汰了。我们直接拿磁盘从老师的电脑上拷课件,然后打印。通常讲到单片机这门课,许多人学的时候都会觉得枯燥,因为很多都是一成不变的在讲8051,大段大段的源代码讲的大家昏昏欲睡,而我们的老师在整个单片机的教学过程中,从来没有提过8051这个东东,她可以说不是在上课,而是在介绍新技术,让大家都听得津津有味,大大提高了学生的积极性。

绝的是我们老师给我们布置的作业,总共有四次,作业从布置到上交有2周时间。第一次作业,拷给我们一篇IC资料,全英文的,打印了三十几页,然后“微笑地”对我们说,作业很“少”,请大家把其中介绍XX控制字的那一段翻译一下,很少,就两段。当时我们很开心,上课听故事,下课作业就只要翻译两段英文。回去以后发现被卖了,三十几页,哪两段是介绍那个控制字的???最后基本把三十几页啃完后才在最后找到。哭倒一片。

第二次作业和第三次作业是都做一个单片机产品设计,作业题目就是《具有XX功能的产品》,具体怎么做让我们上网去查,要我们写出实现的硬件架构和软件运算流程,所用到的IC必须注明网址,要随机抽查,看看我们是不是有“天才”会自己开发IC,并说有很多IC可以实现这个功能,如果你们每一个IC都一样,我就知道你们抄袭作业,后果自负,然后就夹了包跑了。我们什么都不懂,只能去校园bbs广发英雄贴,然后在高手指点下去电子进修网(www.studydz.com)、21IC找资料(www.21ic.com),或者用google大海捞针地翻,因为工作量大,最主要是看英文资料比较慢,作业又不能一样,然后就几个人合作,一个人专门找传感器方面的资料,一个人专门找数据处理IC方面的资料,一个专门找数据通信接口方面的IC,因为同样的产品,资料中的单词相同的比较多,可以提高速度,最后三个人合作了三款东东交差。

第四次是最BT的,让我至今记忆犹新,要做一个远程粮库温控系统,20个粮库,4*5的排列方式,每个粮库为20米边长的正方形,粮库间距10米,每个粮库要12个测温点,第一排粮库左边20米有一个房间监控所有粮库温度。数据要用10 Base T双绞线传输。要求我们设计粮库端数据采集器的温度采集、数模转换、数据前期处理的硬件架构和软件运算流程,并简短介绍相关IC;网络传输的硬件架构,因为粮库距离超过了10 Base T双绞线直接传输的有效距离;后台服务器要求我们写出所用服务器配置,操作系统,用什么数据库,数据库的关系图,用什么语言写后台处理程序,后台处理程序的运算流程,如果温度超标还要能自动发出警报,最后还要你说明,你为什么选用这个操作系统、数据库和后台程序语言,要和其他的比较一下,写出你的选用理由。这个作业算作50分成绩,同时和前面第二第三次作业一样,抄袭没门。同学抱怨BT,老师很轻松的口气说,你们大一学了C和C++,大二学了数电模电,大三学了DSP、数据库、系统集成、计算机原理和汇编,现在我只是让你们学会综合运用而已,前面没学好的,现在补补,不要出去说老师没有教。

工作到现在,觉得这个老师的四次作业,让我们非常受益,

1.我们不怕看英文资料,特别是IC方面的;

2.我们学会了怎样获取最新技术和资讯;

3.我们锻炼了团队合作,完成作业的时间限制就相当于现在抢占市场一样拖不得,怎样分工合作大家双赢才是最主要的;

4.就是我们已经养成了由面找点的习惯,每接触到一个电子产品,就会很快在大脑中出现这个产品的整个系统框架,然后逐一了解每个功能。而不是对每一个功能了解后,再去把他们联系起来。

5.毕业后感到在学校还学了不少东西.

系统分类: 自由话题
用户分类: 单片机
标签: 无标签
来源: 原创
发表评论 阅读全文(124) | 回复(0)
总共 , 当前 /