单片机实训报告心得

广东轻工职业技术学院

实 训 报 告

实训项目 单片机实训

系别: 电子通信工程系

专业: 应用电子技术

班级: 嵌入式091班

姓名: **

学号: ***

指导老师:***

实训地点: 第三实训楼 C309

实训时间: 20**年1月10日至1月14日

前言

单片机应用技术是现代电子设计的核心技术,学习单片机只是就是要将单片机应用到电子产品中,以单片机为控制核心实现电子系统所需实现的功能。单片机的应用能力很多程度上决定了电子类专业学生电子设计与电子应用的水平与能力,尤其是高职学生更是如此。

本项目要求设计一个简单的电子时钟,用六位LED数码管实现电子时钟的功能,显示方式为时、分、秒,采用24h(小时)计时方式,使用按键开关可实现时分调整。

通过电子闹钟项目的课题设计,让同学们体验项目设计的要点,了解项目设计的流程,加深对单片机应用知识的学习,体会团队协作的力量所在。为日后的嵌入式专业学习巩固基础。

目录

1.概述…………………………………………………………

1.1 系统的作用………………………………………………………………

1.2 系统的功能要求 ……………………………………………………………

2.系统硬件设计………………………………………………..

2.1系统的电路原理……………………………………………………………

2.2 电路原理图………………………………………………………………

2.3 各控制按钮控制功能说明……………………………………………….

3.系统软件设计 ……………………………………………….

4.系统调试…………………………………………………….

5. 总结…………………………………………………………

1.概述

1.1 系统的作用

本系统是利用AT89C51单片机结合6个七段显示器以24时制“时时分分秒秒”格式显示时间的电子定时闹铃,系统可以设置8组定时闹铃和1组倒计时功能;当定时闹铃和倒计结束时,该电子时钟通过蜂鸣器发出嘀嘀嘀响声;本系统还具有半点和整点报时功能,当现在时间为半点时会发出嘀的一声响,当现在时间为整点时报整点数响声。由于该电子定时闹铃有强大功能可以在多种场合下使用,利用七段显示器发光也可以在夜晚和黑暗场合下使用。

1.2 系统的功能要求

(1)使用6位七段显示器显示24时制时间。

(2)时间显示格式为“时时分分秒秒”。

(3)定时闹铃功能。

(4)倒计时功能。

(5)半点报时功能:当现在时间为半点时,蜂鸣器发出“嘀”一声响。

(6)整点报时功能:当现在时间为整点时,蜂鸣器发出现在时间整点数响声。

(7)当任一闹铃时间到时发出连续“嘀嘀嘀”响声,七段显示器显示“X HHMM”。

(8)当倒计时时间到时发出嘀嘀嘀响声,七段显示器显示“000000”。

(9)定时闹铃、倒计时和现在时间模式可以互相切换而不影响各自功能。

(10)具有4个按键来进行功能设置,可以设置当前时间、8组闹铃的时间设置和开关及倒计时的时间设置。

(11)通过复位按键可以重启系统。

2.系统的硬件设计

2.1系统的电路原理

(1)系统以AT89C51单片机为本电路的核心元件,通过单片机的P0.0~P0.7引脚和A102J排阻加上拉电压来驱动七段显示器段显示数字。

(2)通过单片机的P2.2~P2.7引脚连接A103J排阻拉升电压信号,控制6个8050NPN三极管使共阴极七段显示器连通接地来循环点亮6位七段显示器。

(3)在七段显示器供电的同时由P0脚驱动显示不同数字。根据人眼的视觉暂留特点,调整延迟时间使所观察到时间数字是稳定的数字。

(4)系统使用了HYDZ蜂鸣器,通过单片机P3.7引脚连接8550PNP三极管推动发声。

(5)电路通过4个按键连接单片机P1.0~P1.3引脚低电平控制系统功能设置。

(6)单片机的复位电路,采用传统上电复位,通过Reset按键控制。

(7)电路可以通过+5V和+12V直流电供电,当使用+12V直流供电时,电路通过1个7805三端稳电器、2个35v100μF电解电容和1个50v10μF电解电容转换成+5V直流电供电。

(8)系统通过一个发光二极管指示电路供电是或正常。

2.2 电路原理图

https://upload.fanwen118.com/wk-img/img100/2533578_1.jpg

图示为数码管显示电路

https://upload.fanwen118.com/wk-img/img100/2533578_2.jpg

图示为主程序电路图

2.3 各控制按钮控制功能说明

KEY0(按键INT0):调时向左移一位数——接P3.0

KEY1(按键INT1):当前位加1——接P3.1

KEY2(按键T0):当前位减1——接P3.2

KEY3(按键T1):确定调时时间——接P3.3

S1:切换闹钟调时模式(高电平)——接P3.4

S2:中断程序(高电平),中断当前的闹钟或整点报时的响应——接P3.5

S3:暂停和开始计时(高电平)——接P3.6

BELL:蜂鸣器——接P3.7

——当整点报时和闹钟响应的时候会响。

LED灯——当整点报时和闹钟响应的时候会亮。

P1.0 ~ P1.3分别接LED灯的高四位,P1.4 ~ P1.7分别接灯的低四位。

P0.0 ~ P0.7分别口接数码管的段选的a~h位

P2.0 ~ P2.5口分别接数码管的位选的6~1位

3.软件设计

流程图显示如下:

单片机实训报告心得

单片机实训报告心得

单片机实训报告心得

主程序流程图

单片机实训报告心得

功能选择中断

单片机实训报告心得

调时程序流程图

单片机实训报告心得

调时0.3s闪烁显示中断

源程序清单:

#include<reg51.h>

#define uchar unsigned char

#define led_data P0 //P0显示数码管当前位的数字

#define led_bit P2 //P2控制当前数码管显示的位数

int b;

uchar conls=0x00; //记录秒分时的个位数

uchar cons=0x00; //记录秒分时的十位数

uchar con=0x00; //记录调时程序当前位数

uchar x=0x00; //记录闹钟

sbit key0=P3^0; //key0控制调时位左移以一位

sbit key1=P3^1; //key1控制挑时当前位数字+1

sbit key2=P3^2; //key1控制挑时当前位数字-1

sbit key3=P3^3; //确定当前挑时中断程序

sbit stop=P3^4; //用来暂时计时和启动计时

sbit baojing=P3^5; //用以响应整点报时和闹钟

sbit naozhong=P3^6; //用来开启闹钟调时程序

sbit beep=P3^7; //用来终止当前整点报时或闹钟响应

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //数码管当前位0~9的显示码

uchar data scan_con[6]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF}; //数码管左到右6个位的显示

uchar data dis[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00}; //数码管的显示码

uchar data timedata[6]={0x00,0x00,0x00,0x00,0x00,0x00}; //电子钟的初始时间:00:00:00

uchar data secclock[6]={0x00,0x00,0x00,0x00,0x00,0x00}; //闹钟调时的初始时间:00:00:00

uchar i;

display(); //显示数码管函数申明

keyscan(); //调时按钮函数声明

//alarmcolk();

/************************************************************************/

/* 1ms延时显示程序 */

/************************************************************************/

void delay(int z)

{

int x,y;

for(x=0;x<z;x++)

for(y=0;y<120;y++);

}

initializa();

/************************************************************************/

/* 主函数 */

/************************************************************************/

void main()

{

initializa();

while(1)

{

display();

keyscan();

//alarmcolk();

}

}

/************************************************************************/

/* 显示子程序 */

/************************************************************************/

display()

{

uchar k;

for(k=0;k<6;k++)

{

led_data=table[dis[k]];led_bit=scan_con[k];delay(1);P2=0x00;

}

}

/************************************************************************/

/* 初始化子程序 */

/************************************************************************/

initializa()

{

for(i=0;i<6;i++)

{

dis[i]=timedata[i];

}

TH0=0X3C;TL0=0XB0;

TH1=0x3c;TL1=0XB0;

TMOD=0X11;

ET0=1;

ET1=1;

TR0=1;

TR1=0;

EA=1;

}

/************************************************************************/

/* 调时按钮处理子程序 */

/************************************************************************/

keyscan()

{

int a=0,j;

for(i=0,j=0;i<6;i++) //分别比较电子钟与闹钟时分秒

{

if(timedata[i]==secclock[5-i]&&timedata[0]!=0)

j++;

}

if(j==6)

{

if(beep==0) //若都相等,且没关闭响应

{

for(i=1;i<10;i++)

{

baojing=0;

P1=0x00;

delay(500);

baojing=1;

P1=0xff;

delay(500);

}

}

}

if(key3==0){con=0;x=0;TR1=0;ET1=0;TR0=1;ET0=1;} //关闭调时按钮中断,继续显示电子钟的时间

else if(naozhong==0) //开启调时按钮中断

{

EA=0;

if(key0==0)

{

delay(10);

while(key0==0);

if(dis[con]==10)

{

dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];

}

con++;TR0=0;ET0=0;TR1=1;ET1=1;

if(con>=6) //若左移位数超过6,则关闭调时按钮中断,继续显示电子钟的时间

{

con=0;TR1=0;ET1=0;TR0=1;ET0=1;

}

}

if(con!=0)

{

if(key1==0)

{

delay(10);

while(key1==0);

timedata[con]++; //当前位数据+1

switch(con)

{

case 1:

case 3:

if(timedata[con]>=6) //1、3位满6进一

{

timedata[con]=0;

}break;

case 2:

case 4:

if(timedata[con]>=10) //2、4位满10进一

{

timedata[con]=0;

}

break;

case 5: //5位满2清零

if(timedata[con]>=3)

{

timedata[con]=0;

}

break;

default: ;

}

dis[con]=timedata[con];

dis[6]=0x0a;

}

}

if(con!=0)

{

if(key2==0)

{

delay(10);

while(key2==0);

switch(con)

{

case 1:

case 3:

if(timedata[con]==0)

{

timedata[con]=0x05; //1、3位为0时的减1处理

}

else

{

timedata[con]--; //当前位数据-1

}break;

case 2:

case 4:

if(timedata[con]==0)

{

timedata[con]=0x09; //2、4位为0时的减1处理

}

else

{

timedata[con]--; //当前位数据-1

}break;

case 5:

if(timedata[con]==0)

{

timedata[con]=0x02; //5位为0时的减1处理

}

else

{

timedata[con]--; //减1处理

}

break;

default: ;

}

dis[con]=timedata[con];dis[6]=0x0a; //送显示数据

}

}

EA=1;

}

else if(naozhong!=0) //开启调时按钮中断,功能类似上面

{

EA=0;

if(key0==0)

{

delay(10);

while(key0==0);

if(dis[x]>=10)

{

dis[7]=dis[x];dis[x]=dis[6];dis[6]=dis[7];

}

x++;TR0=0;ET0=0;TR1=1;ET1=1;

if(x>=6)

{

x=0;TR1=0;ET1=0;TR0=1;ET0=1;

}

}

if(x<=9)

{

if(key1==0)

{

delay(10);

while(key1==0);

secclock[x]++;

switch(x)

{

case 1:

case 3:

if(secclock[x]>=6)

{

secclock[x]=0;

}break;

case 2:

case 4:

if(secclock[x]>=10)

{

secclock[x]=0;

}

break;

case 5:

if(secclock[x]>=3)

{

secclock[x]=0;

}

break;

default: ;

}

dis[x]=secclock[x];

dis[6]=0x0a;

}

}

if(x>=0)

{

if(key2==0)

{

delay(10);

while(key2==0);

switch(x)

{

case 1:

case 3:

if(secclock[x]==0)

{

secclock[x]=0x05;

}

else

{

secclock[x]--;

}break;

case 2:

case 4:

if(secclock[x]==0)

{

secclock[x]=0x09;

}

else

{

secclock[x]--;

}break;

case 5:

if(secclock[x]==0)

{

secclock[x]=0x02;

}

else

{

secclock[x]--;

}

break;

default: ;

}

dis[x]=secclock[x];dis[6]=0x0a;

}

}

EA=1;

}

}

/************************************************************************/

/* 0.3s闪烁中断小程序 */

/************************************************************************/

void time_intt1(void)interrupt 3

{

EA=0;TR1=0;TH1=0X3C;TL0=0XB0;TR1=1;

cons++;

if(cons==6) //50ms x 6 =300ms =0.3s

{

cons=0x00;

dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];

}

EA=1;

}

/************************************************************************/

/* 电子钟显示进位处理程序 */

/************************************************************************/

void time_intt0(void)interrupt 1

{ {

int i,j,x=0;

j=0;

if(naozhong==0&&stop==1)

{

ET0=0;TR0=0;TH0=0X3C;TL0=0XB0;TR0=1;

conls++;

if(conls==20) //20次延时,秒+1

{

conls=0x00;

timedata[0]++;

if(timedata[0]>=10) //10s时,秒十位数+1

{

timedata[0]=0;

timedata[1]++;

if(timedata[1]>=6) //60s时,分+1

{ //5

timedata[1]=0;

timedata[2]++;

if(timedata[2]>=10) //10min时,分十位数+1

{

timedata[2]=0;

timedata[3]++;

if(timedata[3]>=6) //60min时,时+1

{

timedata[3]=0;

timedata[4]++;

if(beep==0)

{

for(i=1;i<=(timedata[5]*10+timedata[4])&&beep==0;i++) //整点报时功能,几点钟就响几下

{

baojing=0;

P1=0x00;

delay(500);

baojing=1;

P1=0xff;

delay(500);

timedata[0]++;

}

}

if(timedata[4]>=10) //10h时,时十位数+1

{

timedata[4]=0;

timedata[5]++;

if(timedata[5]==2) //当h等于24时,清零

{

if(timedata[4]==4)

{

timedata[4]=0;

timedata[5]=0;

}

}

}

}

}

}

}

for(b=0;b<6;b++) //分别向各个位送显示码

{

dis[b]=timedata[b];

}

}

ET0=1;

}

/*显示清零并转换成秒计时(原时间仍然保存)*/

/*else if(jishi==1)

{

for(j=0;j<6;j++)

secclock[j]=0;

ET0=0;TR0=0;TH0=0X3C;TL0=0XB0;TR0=1;

conls++;

if(jishi==0) ;

else

{ //3

if(conls==20)

{ //4

conls=0x00;

timedata[0]++;

secclock[0]++;

if(timedata[0]>=10)

{

timedata[0]=0;

timedata[1]++;

if(secclock[0]>=10)

{

secclock[0]=0;

secclock[1]++;

}

}

if(timedata[1]>=6)

{

timedata[1]=0;

timedata[2]++;

if(secclock[1]>=6)

{

secclock[1]=0;

secclock[2]++;

}

}

if(timedata[2]>=10)

{

timedata[2]=0;

if(secclock[2]>=10)

{

secclock[2]=0;

secclock[3]++;

}

}

}

}

for(b=0;b<6;b++)

{

dis[b]=timedata[b];

}

ET0=1;

}*/

}

}

4.系统调试

4.1 调试设备

4.1.1 硬件设备:

GQDJL-1型单片机开发板

4.1.2 软件程序:

Keil μVision2集成开发环境、STC系列单片机ISP下载软件。C语言编写源程序代码。

5.总结

AT89C51单片机作为嵌入式专业的入门基础,受到行业内的高度重视。作为一名高职高专的学生,最重要的是实际操作能力,而对于修读嵌入式专业的高职学生更是如此。单片机实训,敲开了同学们对知识求知若渴的大门。

本周的单片机实训项目课题是定时闹铃。刚接到课题时感觉毫无压力,觉得自己的能力应该很快就可以完成,因为本项目要实现的功能只不过是同等于价值2元的电子闹钟!

但是现实却击垮了浮夸的我们。程序设计无从入手,调试错误,单片机无响应……老师在讲解课题任务的时候确实是很简单,清晰明了。但是真正到我们设计的时候,错误接一连二。由于对汇编语言掌握不足,最终放弃汇编语言改换C语言编写程序。函数调用,设计循环语句,调用数组函数……

一步步慢慢深入,一点点渐渐掌握。最终,经过小组成员不停地编码,测试,运行,一个小项目终于完成。

项目虽然完成,但通过本次实训确实感触不少。于嵌入式行业而言,单片机谈得上是基础,但是就连这样一门基础我们也没有熟悉掌握,对于日后ARM的学习就更是困难。不过在实训中我们也学会了很多。项目设计、功能选定、搭建硬件工作环境、编写软件程序,程序下载测试、程序最终实现,以及在项目设计中的团队分工与合作。

嵌入式行业在我国日趋发展成熟,而嵌入式行业的人才却是十分紧缺,这就取决于嵌入式行业对技术型人才要求高的特点。要想在嵌入式行业站稳脚,就必须要痛下苦工,敢于钻研。相信通过日后的专业知识学习,我们会在嵌入式学习的道路上越走越远。

相关推荐