单片机课程设计
课题: 计数器
系 别: 电气与电子工程系 专 业: 电子信息工程 姓 名: 严鹏飞 学 号: 093409160
河南城建学院
2011年12月28日
成绩评定·
一、指导教师评语(根据学生设计报告质量、答辩情况及其平时表现综合评
定)。
二、评分
课程设计成绩评定
自动计数器在日常生活中屡见不鲜,它是根据不同的情况设定的,能够 通过技术功能实现一些相应的程序, 如通过自动计数器来实现自动打开和关闭各 种电器设备的电源。广泛用于路灯,广告灯,电饭煲等领域。 自动计数器给人们生产生活带来了极大的方便, 而且大大地扩展了自动计数器的 功能。诸如自动定时报警器、按时自动打铃、时间程序自动控制、定时广播、自 动启闭电路,定时开关烤箱、甚至各种定时电器的自动启用等,所有这些,都是 以自动计数器为基础的。由于它的功能强劲,用途广泛,方便利用,所以在这个 电子科技发展的时代,它是一个很好的电子产品。如在洗衣机的定时控制以及路 灯等一些人们不能再现场控制的操控。都可以利用自动计数器来完成这样的功 用。可见此系统所能带来的方便和经济效益是相当远大的。因此,研究自动计数 器及扩大其应用,有着非常现实的意义。 本次课设设计是检验理论学习水平、实践动手能力及理论结合实际的能力,要求 具有一定的分析处理问题能力和自学能力的一个比较重要得实践课程。 通过这样 的过程,使我们的论文及实践水平有一次较为全面的检查,同时也使我们硬件方 面的能力有所提高,对以后的学习有这非常重要的意义。
二、设计目的
1、使学生增进对单片机的感性认识,加深对单片机理论方面的理解; 2、使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片 内外存贮器、I/O口、A/D、D/A、串行口通讯等;
3、使学生了解和掌握单片机应用系统的软硬件设计过程、方法及实现,为以 后设计和实现单片机应用系统打下良好基础。
三、设计要求
1、可以实现六位的计数:0~999999 2、键盘能实现全锁、半锁、清零功能
3、能实现计数的自加一 减一
四、总体设计
1、电路的总体原理框图
2、 LED 显示器的结构与原理
(1)结构种类 七段LED 显示器(数码管)系发光器件的一种。常用的LED 发光器件有两类:数码管和点阵。数码管内部有七个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组成字符。常见数码管有10根管脚。管脚排列如下图(a )所示。其中COM 为公共端,根据内部发光二极管的接线形式可分为共阴极和共阳极两种。如下图(b )(c )所示,使用时,共阴极数码管公共端接地,共阳极数码管公共端接电源。发光二极管需5~10mA的驱动电流才能正常发光,一般需加限流电阻控制电流的大小。
(2)显示原理 LED数码管的a~g七个发光二极管。加正电压的发光加零电压的不能发光,不同亮暗的组合能形成不同的字符,这种组合称为字型码。共阳极和共阴极的字型码是不同的,如下所示。
LED 字符显示代码表 显示 段符号 十六进制代码 dp g f e d c b a 共阴极 共阳极 0 0 0 1 1 1 1 1 1 3FH C0H 1 0 0 0 0 0 1 1 0 06H F9H 2 0 1 0 1 1 0 1 1 5BH A4H 3 0 1 0 0 1 1 1 1 4FH B0H 4 0 1 1 0 0 1 1 0 66H 99H 5 0 1 1 0 1 1 0 1 6DH 92H 6 0 1 1 1 1 1 0 1 7DH 82H 7 0 0 0 0 0 1 1 1 07H F8H 8 0 1 1 1 1 1 1 1 7FH 80H 9 0 1 1 0 1 1 1 1 6FH 90H
3、 译码器原理(74LS47)
译码为编码的逆过程。它将编码时赋予代码的含义“翻译”过来。实现译码的逻辑电路成为译码器。译码器输出与输入代码有唯一的对应关系。74LS47是输出低电平有效的七段字形译码器,它在这里与数码管配合使用,表2列出了74LS47的真值表,表示出了它与数码管之间的关系。 表2
输 入 输 出 显示数字符号
LT(——) RBI(——-) A3 A2 A1 A0 BI(—)/RBO(———)
a(—) b(—) c(—) d(—) e(—) f(—) g(—)
1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 X 0 0 0 1 1 1 0 0 1 1 1 1 1 1 X 0 0 1 0 1 0 0 1 0 0 1 0 2 1 X 0 0 1 1 1 0 0 0 0 1 1 0 3 1 X 0 1 0 0 1 1 0 0 1 1 0 0 4 1 X 0 1 0 1 1 0 1 0 0 1 0 0 5 1 X 0 1 1 0 1 1 1 0 0 0 0 0 6 1 X 0 1 1 1 1 0 0 0 1 1 1 1 7 1 X 1 0 0 0 1 0 0 0 0 0 0 0 8 1 X 1 0 0 1 1 0 0 0 1 1 0 0 9 X X X X X X 0 1 1 1 1 1 1 1 熄灭 1 0 0 0 0 0 0 1 1 1 1 1 1 1 熄灭 0 X X X X X 1 0 0 0 0 0 0 0 8
(1)LT(——) :试灯输入,是为了检查数码管各段是否能正常发光而设置的。当LT(——)=0时,无论输入A3 ,A2 ,A1 ,A0为何种状态,译码器输出均为低电平,若驱动的数码管正常,是显示8。
(2)BI(—) :灭灯输入,是为控制多位数码显示的灭灯所设置的。BI(—)=0时。不论LT(——) 和输入A3 ,A2 ,A1,A0为何种状态,译码器输出均为高电平,使共阳极数码管熄灭。
(3)RBI(——-) :灭零输入,它是为使不希望显示的0熄灭而设定的。当对每一位A3= A2 =A1 =A0=0时,本应显示0,但是在RBI(——-)=0作用下,使译码器输出全为高电平。其结果和加入灭灯信号的结果一样,将0熄灭。
(4)RBO(———) :灭零输出,它和灭灯输入BI(—) 共用一端,两者配合使用,可以实现多位数码显示的灭零控制。
3、 74LS138
3 线-8 线译码器,共有 54/74S138和 54/74LS138 两种线 路结构型式。 其工作原理如下:
①当一个选通端(E1)为高电平,另两个选通端(E2) 和/(E3))为低电平时,可将地址端(A0、A1、A2)的二进制编码在Y0至Y7对应的输出端以低电平译出。比如:A2A1A0=110时,则Y6输出端输出低电平信号。 ②利用 E1、E2和E3可级联扩展成 24 线译码器;若外接一个反相器还可级联扩展成 32 线译码器。
③若将选通端中的一个作为数据输入端时,74LS138还可作数据分配器。
④可用在8086的译码电路中,扩展内存。
4、硬件总体设计
1、主要元器件选择
主要元器件选用型号和数量如下:
1个AT89C51(单片机) 1个CRYSTAL(晶振) 2个CAP(电容) 1个RES (电阻)
2个7SEG-COM-CATHOD(共阴极数码管) 1个CAP-ELEC(电解电容) 1个发光二极管
1个74LS47(七段字形译码器) 1个74LS138(3 线-8 线译码器) 2、系统板上硬件连线
(1.单片机P3.0~P3.7接按键端口P0~P7
(2.单片机P0.0~P0.7接74LS47和74LS138的输入端
(3.数码管的七段和六位分别与74LS47 和74LS138的输出端相接
5、软件总体设计
# include # include # include
bit FLAG0=0; /*设定位标记, 键盘扫描回应标记*/ sbit LED = P2^0; /*LED*/
char m=0,ptr=0,ptr1=0; /*PTR键盘扫描指标,PTR1显示器扫描
指标*/
bit stand=0,stand1=0; /*键盘锁控制位*/ char code tab[16]= {
0x01,0x02,0x03,0x0c, /*键盘码*/ 0x04,0x05,0x06,0x0d, 0x07,0x08,0x09,0x0e, 0x0a,0x00,0x0b,0x0f };
unsigned long DATA[16]; /*按键值存放数组*/
void delay (unsigned int value) /*延时子程序*/ {
while (value!=0) value--; /*10US延时*/
}
void scan(void); /*声明键盘扫描子程序*/
void clear(void); /*声明清除按键存放/显示器数组DATA[]
子程序*/
void xch(void); /*声明按键存放/显示器数组DATA[]
右键滚入子程序*/
void CF(void); void CH5(void);
void main() /*主程序*/ {
TMOD=0x11; /* TIMER0,TIMER1工作在MODE1方式*/
TH1=(65536-3000)/256; /*设定每隔3000US 扫描一次*/ TL1=(65536-3000)%256;
IE=0x88; /*8是允许中断,a 是TIMER0,
TIMER1中断使能位*/
TR1=1; /*启动TEMER1*/
clear(); /*调用清除显示器为000000子程序*/
while (1) {do
scan (); /*调用键盘扫描子程序有按FLAG0
会为1*/
while (FLAG0!=1); /*判断有按键输入否?*/
delay(1000); /*按钮去抖动*/ while(m==P1); /*按钮放开否?*/ delay(1000); switch(tab[ptr]) /*是则测试PTR 键盘扫描计数器指标至
TAB[]取到的键盘码*/
{
case 0x0e:
if(stand==0&stand1==0) clear(); /*是否按"c" 是则调用清除显示器CLEAR*/
break; case 0x0c: /*是否按"A" ,计数器加*/ if(stand==0) CF(); break;
case 0x0d: /*是否按"B" ,计数器减*/ if(stand==0) CH5(); break; case 0x0a: /*是否按"*",锁键*/ stand=1; break;
case 0x0f: /*是否按"d" ,解锁键*/ stand=0; stand1=0; break; case 0x0b: if(stand==0) stand1=1; break; default:
if(stand==0&stand1==0) xch(); else ; break; } } }
void CF(void) {
unsigned long temp;
temp=DATA[0];
temp=temp+DATA[1]*10; temp=temp+DATA[2]*100; temp=temp+DATA[3]*1000; temp=temp+DATA[4]*10000; temp=temp+DATA[5]*100000;
if(temp==999999) temp=0; else temp++;
/*是否按"#",半锁键*/ /*跳出此循环*/
DATA[0]=(temp%10); /*取秒的个位数存入data2[0]*/
DATA[1]=(temp/10%10); /*取秒的十位数存入data2[1]*/
DATA[2]=(temp/100%10);
DATA[3]=(temp/1000%10);
DATA[4]=(temp/10000%10);
DATA[5]=(temp/100000%10);
}
void CH5(void)
{
unsigned long temp;
temp=DATA[0];
temp=temp+DATA[1]*10;
temp=temp+DATA[2]*100;
temp=temp+DATA[3]*1000;
temp=temp+DATA[4]*10000;
temp=temp+DATA[5]*100000;
if(temp==0)
temp=999999;
else
temp--;
DATA[0]=(temp%10); /*取秒的个位数存入data2[0]*/
DATA[1]=(temp/10%10); /*取秒的十位数存入data2[1]*/
DATA[2]=(temp/100%10);
DATA[3]=(temp/1000%10);
DATA[4]=(temp/10000%10);
DATA[5]=(temp/100000%10);
}
void xch(void)
{char c;
for(c=5;c>0;c--)
{DATA[c]=DATA[c-1];}
DATA[0]=tab[ptr];
}
void clear(void) /*清除显示DATA[]为00子程序*/
{
char c; /*声明变量*/
for(c=0;c
{
DATA[c]=0x00;
} /*返回主程序*/
}
void scan(void) /*扫描键盘子程序*/
{
char a1=0xf7,i; /*A1=0XF7列扫描初值,I 行*/
FLAG0=0; /*设按键回应标记为0,键盘扫描计数指标为0*/
ptr=0;
for(i=0;i
{
P1=a1; /*列扫描输出,读入P1存入M ,以便检测行与检测按键是否放开*/ m=P1;
switch(m&0xf0) /*取行的高4位,检测那一行被按*/
{
case 0x70: ptr=i*4; /*第一行被按否?是则扫描指标=列X4*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xb0: ptr=i*4+1; /*第二行被按否?是则扫描指标=列X4+1*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xd0: ptr=i*4+2; /*第三行被按否?是则扫描指标=列X4+2*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xe0: ptr=i*4+3; /*第四行被按否?是则扫描指标=列X4+3*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
default: break; /*跳出此循环*/
}
if(FLAG0==1)break; /*不为1,则扫描列右移,扫描下一列*/
a1=a1>>1|0x80; /*高位补1,由于P1.7~P1.4未接+5V,而是由指令加载高电平*/ }
} /*返回主程序*/
void service_int1 () interrupt 3 using 2 /*TIMER1中断子程序*/
{//char ptr1;
/*声明扫描指标变量*/
TH1=(65536-3000)/256; /*每隔4000US 扫描一次*/
TL1=(65536-3000)%256;
if(stand==1) LED=0;else LED=1;
if (ptr1>5) ptr1=0; /*PTR1>5表示6个数码管都已经扫描过*/
P0=(ptr1
ptr1++; /*扫描指标加1*/
} /*返回主程序*/
五、各部分电路设计
1.MCS-51
单片机电路的设计
本电路使用单片机内部振荡器,12MHz 的晶体谐振器直接接在单片机的时钟端口X1和X2,电路中C2、C3为振荡器的匹配电容。该电路简单,工作可靠 。
2. 按键电路
按键的左右管脚分别相连,与单片机的P1口连接
3.74LS47 74LS138数码管电路
本电路使用74LS47控制数码管的七段显示,74LS138控制数码管的位显示
六、整体电路图(见附图)
七、设计总结
1、设计过程中遇到的问题及解决方法
1)在编程后发现程序无法运行,有几个错误,经过检查后发现原来开始的uchar 与 uint 这两个变量在main 函数中没有定义导致出错
(2)在焊接玩工程板后发现通电后无反应,经过仔细的排查才发现原来由于焊工不精导致很多地方出现虚焊,导线接触不良导致无法通电,在经过仔细复查后将虚焊的地方重新焊接了一遍解决了问题。
2、设计体会
这次课程设计是一次非常好的锻炼机会, 历时一个星期,通过这一个星期的学习,发现了自己的很多不足,自己知识的不怎么牢固,看到了自己的实践经验更是比较缺乏,理论联系实际的能力还急需提高。
这次的课程设计也让我看到了团队的力量,我认为我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。团结协作是我们成功的一项非常重要的保证。而这次设计也正好锻炼我们这一点,这也是非常宝贵的。
这次设计就我个人而言,和同学老师这一周的一起工作的日子,让我们有说有笑,相互帮助,配合默契,多少人间欢乐在这里洒下,我感觉我和同学们之间的距离更加近了。学到的东西,将对我后面两年的学习有重要的指导作用,不敢说以后,但在毕业前的这段时间内,这次学习对我的确很重要。感激系里让我们有这次学习设计的机会,还有指导老师那不厌其烦的指导,让我受益匪浅,这次学习对于我们没有真正实践经验的同学来说,绝对是一次成长的机会。
3、对设计的建议
虽然设计完成了,但是我知道自己仍然有许多设计与制作上的不足,有些地方仍然有很大可以改进的地方,例如,在工程板的焊接设计上可以更有条理些,布线应该更工整与精细,在设计上,还可以加上更多的功能,例如可以增加传感器实现自动计数的功能。
参考文献
《测控电路及装置》 孙传友等编。
《单片机原理及接口技术》 李朝青 主编 北京航空航天大学出版社,2002。 《单片机中级教程》 张迎新等主编 北京航空航天大学出版社出版社。 《51单片机》
于永 戴佳 刘波 编著. 电子工业出版社
单片机课程设计
课题: 计数器
系 别: 电气与电子工程系 专 业: 电子信息工程 姓 名: 严鹏飞 学 号: 093409160
河南城建学院
2011年12月28日
成绩评定·
一、指导教师评语(根据学生设计报告质量、答辩情况及其平时表现综合评
定)。
二、评分
课程设计成绩评定
自动计数器在日常生活中屡见不鲜,它是根据不同的情况设定的,能够 通过技术功能实现一些相应的程序, 如通过自动计数器来实现自动打开和关闭各 种电器设备的电源。广泛用于路灯,广告灯,电饭煲等领域。 自动计数器给人们生产生活带来了极大的方便, 而且大大地扩展了自动计数器的 功能。诸如自动定时报警器、按时自动打铃、时间程序自动控制、定时广播、自 动启闭电路,定时开关烤箱、甚至各种定时电器的自动启用等,所有这些,都是 以自动计数器为基础的。由于它的功能强劲,用途广泛,方便利用,所以在这个 电子科技发展的时代,它是一个很好的电子产品。如在洗衣机的定时控制以及路 灯等一些人们不能再现场控制的操控。都可以利用自动计数器来完成这样的功 用。可见此系统所能带来的方便和经济效益是相当远大的。因此,研究自动计数 器及扩大其应用,有着非常现实的意义。 本次课设设计是检验理论学习水平、实践动手能力及理论结合实际的能力,要求 具有一定的分析处理问题能力和自学能力的一个比较重要得实践课程。 通过这样 的过程,使我们的论文及实践水平有一次较为全面的检查,同时也使我们硬件方 面的能力有所提高,对以后的学习有这非常重要的意义。
二、设计目的
1、使学生增进对单片机的感性认识,加深对单片机理论方面的理解; 2、使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片 内外存贮器、I/O口、A/D、D/A、串行口通讯等;
3、使学生了解和掌握单片机应用系统的软硬件设计过程、方法及实现,为以 后设计和实现单片机应用系统打下良好基础。
三、设计要求
1、可以实现六位的计数:0~999999 2、键盘能实现全锁、半锁、清零功能
3、能实现计数的自加一 减一
四、总体设计
1、电路的总体原理框图
2、 LED 显示器的结构与原理
(1)结构种类 七段LED 显示器(数码管)系发光器件的一种。常用的LED 发光器件有两类:数码管和点阵。数码管内部有七个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组成字符。常见数码管有10根管脚。管脚排列如下图(a )所示。其中COM 为公共端,根据内部发光二极管的接线形式可分为共阴极和共阳极两种。如下图(b )(c )所示,使用时,共阴极数码管公共端接地,共阳极数码管公共端接电源。发光二极管需5~10mA的驱动电流才能正常发光,一般需加限流电阻控制电流的大小。
(2)显示原理 LED数码管的a~g七个发光二极管。加正电压的发光加零电压的不能发光,不同亮暗的组合能形成不同的字符,这种组合称为字型码。共阳极和共阴极的字型码是不同的,如下所示。
LED 字符显示代码表 显示 段符号 十六进制代码 dp g f e d c b a 共阴极 共阳极 0 0 0 1 1 1 1 1 1 3FH C0H 1 0 0 0 0 0 1 1 0 06H F9H 2 0 1 0 1 1 0 1 1 5BH A4H 3 0 1 0 0 1 1 1 1 4FH B0H 4 0 1 1 0 0 1 1 0 66H 99H 5 0 1 1 0 1 1 0 1 6DH 92H 6 0 1 1 1 1 1 0 1 7DH 82H 7 0 0 0 0 0 1 1 1 07H F8H 8 0 1 1 1 1 1 1 1 7FH 80H 9 0 1 1 0 1 1 1 1 6FH 90H
3、 译码器原理(74LS47)
译码为编码的逆过程。它将编码时赋予代码的含义“翻译”过来。实现译码的逻辑电路成为译码器。译码器输出与输入代码有唯一的对应关系。74LS47是输出低电平有效的七段字形译码器,它在这里与数码管配合使用,表2列出了74LS47的真值表,表示出了它与数码管之间的关系。 表2
输 入 输 出 显示数字符号
LT(——) RBI(——-) A3 A2 A1 A0 BI(—)/RBO(———)
a(—) b(—) c(—) d(—) e(—) f(—) g(—)
1 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 X 0 0 0 1 1 1 0 0 1 1 1 1 1 1 X 0 0 1 0 1 0 0 1 0 0 1 0 2 1 X 0 0 1 1 1 0 0 0 0 1 1 0 3 1 X 0 1 0 0 1 1 0 0 1 1 0 0 4 1 X 0 1 0 1 1 0 1 0 0 1 0 0 5 1 X 0 1 1 0 1 1 1 0 0 0 0 0 6 1 X 0 1 1 1 1 0 0 0 1 1 1 1 7 1 X 1 0 0 0 1 0 0 0 0 0 0 0 8 1 X 1 0 0 1 1 0 0 0 1 1 0 0 9 X X X X X X 0 1 1 1 1 1 1 1 熄灭 1 0 0 0 0 0 0 1 1 1 1 1 1 1 熄灭 0 X X X X X 1 0 0 0 0 0 0 0 8
(1)LT(——) :试灯输入,是为了检查数码管各段是否能正常发光而设置的。当LT(——)=0时,无论输入A3 ,A2 ,A1 ,A0为何种状态,译码器输出均为低电平,若驱动的数码管正常,是显示8。
(2)BI(—) :灭灯输入,是为控制多位数码显示的灭灯所设置的。BI(—)=0时。不论LT(——) 和输入A3 ,A2 ,A1,A0为何种状态,译码器输出均为高电平,使共阳极数码管熄灭。
(3)RBI(——-) :灭零输入,它是为使不希望显示的0熄灭而设定的。当对每一位A3= A2 =A1 =A0=0时,本应显示0,但是在RBI(——-)=0作用下,使译码器输出全为高电平。其结果和加入灭灯信号的结果一样,将0熄灭。
(4)RBO(———) :灭零输出,它和灭灯输入BI(—) 共用一端,两者配合使用,可以实现多位数码显示的灭零控制。
3、 74LS138
3 线-8 线译码器,共有 54/74S138和 54/74LS138 两种线 路结构型式。 其工作原理如下:
①当一个选通端(E1)为高电平,另两个选通端(E2) 和/(E3))为低电平时,可将地址端(A0、A1、A2)的二进制编码在Y0至Y7对应的输出端以低电平译出。比如:A2A1A0=110时,则Y6输出端输出低电平信号。 ②利用 E1、E2和E3可级联扩展成 24 线译码器;若外接一个反相器还可级联扩展成 32 线译码器。
③若将选通端中的一个作为数据输入端时,74LS138还可作数据分配器。
④可用在8086的译码电路中,扩展内存。
4、硬件总体设计
1、主要元器件选择
主要元器件选用型号和数量如下:
1个AT89C51(单片机) 1个CRYSTAL(晶振) 2个CAP(电容) 1个RES (电阻)
2个7SEG-COM-CATHOD(共阴极数码管) 1个CAP-ELEC(电解电容) 1个发光二极管
1个74LS47(七段字形译码器) 1个74LS138(3 线-8 线译码器) 2、系统板上硬件连线
(1.单片机P3.0~P3.7接按键端口P0~P7
(2.单片机P0.0~P0.7接74LS47和74LS138的输入端
(3.数码管的七段和六位分别与74LS47 和74LS138的输出端相接
5、软件总体设计
# include # include # include
bit FLAG0=0; /*设定位标记, 键盘扫描回应标记*/ sbit LED = P2^0; /*LED*/
char m=0,ptr=0,ptr1=0; /*PTR键盘扫描指标,PTR1显示器扫描
指标*/
bit stand=0,stand1=0; /*键盘锁控制位*/ char code tab[16]= {
0x01,0x02,0x03,0x0c, /*键盘码*/ 0x04,0x05,0x06,0x0d, 0x07,0x08,0x09,0x0e, 0x0a,0x00,0x0b,0x0f };
unsigned long DATA[16]; /*按键值存放数组*/
void delay (unsigned int value) /*延时子程序*/ {
while (value!=0) value--; /*10US延时*/
}
void scan(void); /*声明键盘扫描子程序*/
void clear(void); /*声明清除按键存放/显示器数组DATA[]
子程序*/
void xch(void); /*声明按键存放/显示器数组DATA[]
右键滚入子程序*/
void CF(void); void CH5(void);
void main() /*主程序*/ {
TMOD=0x11; /* TIMER0,TIMER1工作在MODE1方式*/
TH1=(65536-3000)/256; /*设定每隔3000US 扫描一次*/ TL1=(65536-3000)%256;
IE=0x88; /*8是允许中断,a 是TIMER0,
TIMER1中断使能位*/
TR1=1; /*启动TEMER1*/
clear(); /*调用清除显示器为000000子程序*/
while (1) {do
scan (); /*调用键盘扫描子程序有按FLAG0
会为1*/
while (FLAG0!=1); /*判断有按键输入否?*/
delay(1000); /*按钮去抖动*/ while(m==P1); /*按钮放开否?*/ delay(1000); switch(tab[ptr]) /*是则测试PTR 键盘扫描计数器指标至
TAB[]取到的键盘码*/
{
case 0x0e:
if(stand==0&stand1==0) clear(); /*是否按"c" 是则调用清除显示器CLEAR*/
break; case 0x0c: /*是否按"A" ,计数器加*/ if(stand==0) CF(); break;
case 0x0d: /*是否按"B" ,计数器减*/ if(stand==0) CH5(); break; case 0x0a: /*是否按"*",锁键*/ stand=1; break;
case 0x0f: /*是否按"d" ,解锁键*/ stand=0; stand1=0; break; case 0x0b: if(stand==0) stand1=1; break; default:
if(stand==0&stand1==0) xch(); else ; break; } } }
void CF(void) {
unsigned long temp;
temp=DATA[0];
temp=temp+DATA[1]*10; temp=temp+DATA[2]*100; temp=temp+DATA[3]*1000; temp=temp+DATA[4]*10000; temp=temp+DATA[5]*100000;
if(temp==999999) temp=0; else temp++;
/*是否按"#",半锁键*/ /*跳出此循环*/
DATA[0]=(temp%10); /*取秒的个位数存入data2[0]*/
DATA[1]=(temp/10%10); /*取秒的十位数存入data2[1]*/
DATA[2]=(temp/100%10);
DATA[3]=(temp/1000%10);
DATA[4]=(temp/10000%10);
DATA[5]=(temp/100000%10);
}
void CH5(void)
{
unsigned long temp;
temp=DATA[0];
temp=temp+DATA[1]*10;
temp=temp+DATA[2]*100;
temp=temp+DATA[3]*1000;
temp=temp+DATA[4]*10000;
temp=temp+DATA[5]*100000;
if(temp==0)
temp=999999;
else
temp--;
DATA[0]=(temp%10); /*取秒的个位数存入data2[0]*/
DATA[1]=(temp/10%10); /*取秒的十位数存入data2[1]*/
DATA[2]=(temp/100%10);
DATA[3]=(temp/1000%10);
DATA[4]=(temp/10000%10);
DATA[5]=(temp/100000%10);
}
void xch(void)
{char c;
for(c=5;c>0;c--)
{DATA[c]=DATA[c-1];}
DATA[0]=tab[ptr];
}
void clear(void) /*清除显示DATA[]为00子程序*/
{
char c; /*声明变量*/
for(c=0;c
{
DATA[c]=0x00;
} /*返回主程序*/
}
void scan(void) /*扫描键盘子程序*/
{
char a1=0xf7,i; /*A1=0XF7列扫描初值,I 行*/
FLAG0=0; /*设按键回应标记为0,键盘扫描计数指标为0*/
ptr=0;
for(i=0;i
{
P1=a1; /*列扫描输出,读入P1存入M ,以便检测行与检测按键是否放开*/ m=P1;
switch(m&0xf0) /*取行的高4位,检测那一行被按*/
{
case 0x70: ptr=i*4; /*第一行被按否?是则扫描指标=列X4*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xb0: ptr=i*4+1; /*第二行被按否?是则扫描指标=列X4+1*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xd0: ptr=i*4+2; /*第三行被按否?是则扫描指标=列X4+2*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
break; /*跳出此循环*/
case 0xe0: ptr=i*4+3; /*第四行被按否?是则扫描指标=列X4+3*/
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
default: break; /*跳出此循环*/
}
if(FLAG0==1)break; /*不为1,则扫描列右移,扫描下一列*/
a1=a1>>1|0x80; /*高位补1,由于P1.7~P1.4未接+5V,而是由指令加载高电平*/ }
} /*返回主程序*/
void service_int1 () interrupt 3 using 2 /*TIMER1中断子程序*/
{//char ptr1;
/*声明扫描指标变量*/
TH1=(65536-3000)/256; /*每隔4000US 扫描一次*/
TL1=(65536-3000)%256;
if(stand==1) LED=0;else LED=1;
if (ptr1>5) ptr1=0; /*PTR1>5表示6个数码管都已经扫描过*/
P0=(ptr1
ptr1++; /*扫描指标加1*/
} /*返回主程序*/
五、各部分电路设计
1.MCS-51
单片机电路的设计
本电路使用单片机内部振荡器,12MHz 的晶体谐振器直接接在单片机的时钟端口X1和X2,电路中C2、C3为振荡器的匹配电容。该电路简单,工作可靠 。
2. 按键电路
按键的左右管脚分别相连,与单片机的P1口连接
3.74LS47 74LS138数码管电路
本电路使用74LS47控制数码管的七段显示,74LS138控制数码管的位显示
六、整体电路图(见附图)
七、设计总结
1、设计过程中遇到的问题及解决方法
1)在编程后发现程序无法运行,有几个错误,经过检查后发现原来开始的uchar 与 uint 这两个变量在main 函数中没有定义导致出错
(2)在焊接玩工程板后发现通电后无反应,经过仔细的排查才发现原来由于焊工不精导致很多地方出现虚焊,导线接触不良导致无法通电,在经过仔细复查后将虚焊的地方重新焊接了一遍解决了问题。
2、设计体会
这次课程设计是一次非常好的锻炼机会, 历时一个星期,通过这一个星期的学习,发现了自己的很多不足,自己知识的不怎么牢固,看到了自己的实践经验更是比较缺乏,理论联系实际的能力还急需提高。
这次的课程设计也让我看到了团队的力量,我认为我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。团结协作是我们成功的一项非常重要的保证。而这次设计也正好锻炼我们这一点,这也是非常宝贵的。
这次设计就我个人而言,和同学老师这一周的一起工作的日子,让我们有说有笑,相互帮助,配合默契,多少人间欢乐在这里洒下,我感觉我和同学们之间的距离更加近了。学到的东西,将对我后面两年的学习有重要的指导作用,不敢说以后,但在毕业前的这段时间内,这次学习对我的确很重要。感激系里让我们有这次学习设计的机会,还有指导老师那不厌其烦的指导,让我受益匪浅,这次学习对于我们没有真正实践经验的同学来说,绝对是一次成长的机会。
3、对设计的建议
虽然设计完成了,但是我知道自己仍然有许多设计与制作上的不足,有些地方仍然有很大可以改进的地方,例如,在工程板的焊接设计上可以更有条理些,布线应该更工整与精细,在设计上,还可以加上更多的功能,例如可以增加传感器实现自动计数的功能。
参考文献
《测控电路及装置》 孙传友等编。
《单片机原理及接口技术》 李朝青 主编 北京航空航天大学出版社,2002。 《单片机中级教程》 张迎新等主编 北京航空航天大学出版社出版社。 《51单片机》
于永 戴佳 刘波 编著. 电子工业出版社