单片机实习报告

时间:2024.4.13

单片机实习报告

学    院:                           

专    业:                           

姓    名:                            

学    号:                             

起讫时间:                           

指导教师:                           

二〇##年九月九日

一、实习目的

1、熟悉单片机的原理、功能与应用

2、熟悉单片机开发的相关软硬件

3、培养单片机应用开发的兴趣

4、提高单片机应用系统的开发能力

二、实习要求

1、熟悉MCS-51单片机的原理;

2、熟悉单片机KEIL C51编程语言;

3、熟悉uVision2单片机C语言开发环境;

三、实习内容

1、熟悉单片机实习板的电路原理,焊接数字钟电路板,连接实习板上的电路,构成数字钟电路。

2、熟悉C51编程语言和开发环境,设计数字钟的软件程序,调试软硬件实习数字时钟功能。

数字钟的具体设计要求

一、设计要求

1、以MCS-51系列单片机为核心器件,组成一个电子时钟系统。

2、系统显示器由8位LED数码管组成,分别显示时间值的小时、分和秒,以24h(小时)计时方式。

3、 能够使用按键开关随时对当前时间进行调整。(推荐:键1为功能切换键,键2为移位键,键3为增加键,键4为减少键。也可自行定义。)

4、 有精力的学生可以实现秒表功能、闹钟定时功能、温度显示功能和通讯功能。

二、实习工具

计算机、万用表、稳压电源、编程器、电烙铁、单片机实习套件

三、方案论证

1、总体设计

为了实现LED显示器的数字显示,采用静态显示法和动态显示法。由于静态显示法需要数据锁存器等硬件,接口复杂一些。考虑时钟显示有8位,且系统没有其他复杂的处理任务,所以决定采用动态扫描法实现LED的显示。单片机采用Atmel的AT89S52芯片,这样单片机可具有足够的空余硬件资源实现其它的扩充功能。

2、系统硬件电路的设计

秒表/时钟计时器的硬件电路采用AT89S52单片机,最小化应用设计;采用共阴七段LED显示器,P0口输出段码数据,P2.0~P2.5口作列扫描输出,P1.0,P1.1,P1.2,p1.3口接四个按钮开关,用以调时功能设置。P3.2口接温度传感器,P3.3口接闹铃,P3.4口接闹铃旁的LED。采用12MHz晶振,有利于精确定时。

3、系统程序的设计

(1)程序实现功能说明

刚开始复位,数码管显示学号,随后从1秒开始计时。短按按键1,可以实现调时功能,长按1可实现闹钟设置功能,当可以设置闹钟时LED灯亮,当设置时间与计时时间吻合时,闹铃响1分钟。短按按键2,实现移位功能,长按按键2,实现确定锁定功能。按键3实现“+”功能,按键4实现“-”功能。18B20为温度传感器,所以数码管后两位可以实现温度显示功能。

(2)主程序

本设计中,计时采用定时器T0中断完成,其余状态循环调用显示子程序,当端口开关按下时,转入相应功能程序。

(3)LED显示子程序

数码管显示的数据存放在内存单元dis [0]-dis[5]中。其中dis[0]-dis[1]存放秒数据,dis[2]-dis[3]存放分数据,dis[4]-dis[5]存放时数据,每一地址单元内均为十进制BCD码。由于采用软件动态扫描实现数据显示功能,显示用十进制BCD码数据的对应码段存放在ROM表(LEDMAP[]中)。显示时,先取出dis[0]-dis[5]中的某一数据,然后查得对应的显示用码段,并从P0口输出,P2口将对应的数码管选中供电,就能显示该地址单元的数据值。

(4)定时器T0中断服务程序

定时器T0用于时间计时。中断进入后,时钟计时累计中断达1秒时,对秒计数单元进行加1操作。在计数单元中采用十进制BCD码计数,满60进位,T0中断服务程序执行流程见图2.4。

      

(5)具体程序如下

#include <reg52.h>

#include <math.h>

#define LEDLen 8

#define jump_ROM 0xcc

#define start 0x44

#define read_EEROM 0xbe

unsigned char k=0;

unsigned char status;                            //按键处理的状态

bit seconds_flag=0;                              //秒标志位,表明时间已到一秒

bit flag_key_delay;                              //键盘连续处理间隔时间周期信号

bit key_first=1;                                 //第一次扫描到按键按下

#define KEY_PORT P1                             //按键连接的端口

bit key_operated=1;                              //按键已处理过标记

unsigned char elaps;                             //按键长按的时间

unsigned char timer_s;                           //按键随时时间

unsigned char temperature;                       //温度显示

unsigned char hours, minutes, seconds;          //时间显示的时、分、秒

unsigned char timer_hours,timer_minutes;        //闹钟定时的小时、分钟

unsigned char hours_flag,minutes_flag,naozhong_flag;//小时,分钟,闹钟可设置标志位

sbit P10 = P1^0;

sbit P11 = P1^1;

sbit P12 = P1^2;

sbit P13 = P1^3;

sbit DQ = P3^2;

sbit P33 = P3^3;

sbit P34 = P3^4;

unsigned char dis[LEDLen];                         //发光二极管位选数组 

code unsigned char LEDMAP[] = {                    //发光二极管0~F的段码

  0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,

  0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71

}; 

————————————————延时程序———————————————————

void delay_ms(unsigned char N)                      //N*100us 软件延时

{

    unsigned char i,j;

    i=N;

    j=50;

    do

    {

        do

        {

        }while(--j);

    }while(--i);

}

————————————————-键盘相关程序————————————————

unsigned char scankey()                          //按键的监测

{

    unsigned char temp1,temp2; 

    unsigned char start_time;

    temp1=~KEY_PORT;                             //按键未按下为1,按下为0

    temp1&=0x0f;                                 //取低四位

    if(temp1==0)                                 //若没有键按下,temp1为0

    {

        key_first=1;

        elaps=0;

    }

    else                                         //否则有键按下

    {

        delay_ms(10);                           //延时去抖动,通过比较temp1 和

        temp2=~KEY_PORT;                        temp2是否相等,确切判断是否有键

        temp2&=0x0f;                            按下

        if(temp1==temp2)

        {

            if(key_first)

            {

                start_time=timer_s;

                key_first=0;

                key_operated=0;

            }              

            elaps= (timer_s+60-start_time)%60;  //计算按键时间长短

            return temp1;                       //返回键值

        }

    }

    return 0;                                  //没键按下时返回0

}

void keydeal()                                 //按键的处理

{

    unsigned char keyval;                      //键值

    keyval=scankey();

    if(keyval==1)                             //长按及短按key1(调时、定时闹钟)

    {

    if(elaps<=6) 

    {

     hours_flag=1;                           //小时标志位,等于1时表示可设置小时

     }

    if(elaps>6)

    {

    hours_flag=1;

    naozhong_flag=1;                       //闹钟标志位,等于1时表示可以设置闹钟

    P34=0;                                 //可设置闹钟时间时LED灯亮

    }

    }

    if(keyval==2)                          //短按及长按key2(移位、锁定)

    {

     if(elaps<=6)   minutes_flag=1;        //分钟标志位,等于1时表示可设置分

     if(elaps>6)                           //长按为锁定功能

     {

     if((hours_flag==1)&&(minutes_flag==0)&&(naozhong_flag==0))   hours_flag=0;

     if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==0))

     {

     hours_flag=0;

     minutes_flag=0;

     }

     if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==1))

     {

     P34=1;

     hours_flag=0;

     minutes_flag=0;

     naozhong_flag=0;

     }

     if((hours_flag==1)&&(minutes_flag==0)&&(naozhong_flag==1))

     {

     P34=1;

     hours_flag=0;

     minutes_flag=0;

     naozhong_flag=0;

     }

     }

    }

    if((keyval==4)&&(!key_operated))      //短按key3(慢+)

    {

        key_operated=1;

        if(hours_flag==1&&(minutes_flag==0)&&(naozhong_flag==0))

        {

            hours++;

            hours=hours%24;

        }

        if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==0))

        {

            minutes++;

            minutes=minutes%60;

        }

        if((hours_flag==1)&&(minutes_flag==0)&&(naozhong_flag==1))

        {

            timer_hours++;

            timer_hours=timer_hours%24;

        }

        if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==1))

        {

            timer_minutes++;

            timer_minutes=timer_minutes%60;

        }

    }

    if((keyval==8)&&(!key_operated))    //短按key4键(慢-)

    {

        key_operated=1;

        if(hours_flag==1&&(minutes_flag==0)&&(naozhong_flag==0))

        {

            hours+=24;

            hours--;

            hours=hours%24;

        }

        if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==0))

        {

            minutes+=60;              

            minutes--;

            minutes=minutes%60;

        }

        if((hours_flag==1)&&(minutes_flag==0)&&(naozhong_flag==1))

        {

            timer_hours+=24;

            timer_hours--;

            timer_hours=timer_hours%24;

        }

        if((hours_flag==1)&&(minutes_flag==1)&&(naozhong_flag==1))

        {

            timer_minutes+=60;            

            timer_minutes--;

            timer_minutes=timer_minutes%60;

        }

    }

}    

————————————————温度相关函数—————————————————

void delay(unsigned char N)        //N*4us 软件延时

{

    unsigned char i;

    i=N;

    do

    {

   

    }while(--i); 

unsigned char reset(void)          //18B20复位

{

    unsigned char ready;

    DQ=1;

    delay(1);

    DQ=0;

    delay(120);                   //>480us  ,120

    DQ=1;

    delay(8);                     //大于60us小于75 ,注意值不能太大或太小(7)

    ready=DQ;

    delay(80);                     //响应周期>300us ,75,不能太小

    return(ready);

}

void write_byte(unsigned char dat)//18B20写字节

{

    unsigned char i;

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

    {

        DQ=0;

        DQ=dat&0x01;              //至少隔1us再输出

        delay(15);                //数据至少保持60us ,注意值不能太大或太小(10)

        DQ=1;

        dat>>=1;                   //至少隔1us再输出下一位

    }

}

unsigned char read_byte(void)      //18B20读字节

{

    unsigned char i=0;

    unsigned char dat=0;

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

    {

        DQ=0;

        dat>>=1;                  //1us

        DQ=1;

        if(DQ==1)

            dat|=0x80;

        delay(15);                //大于60us    ,15

    }

    return(dat);

}

void convert_temp(void)

{

    while(reset());

    write_byte(jump_ROM);

    write_byte(start); 

}

void read_temp(void)             //温度测量子程序

{

    unsigned char TMPH,TMPL,temp=0;

    while(reset());

    write_byte(jump_ROM);

    write_byte(read_EEROM);

    TMPL=read_byte();

    TMPH=read_byte();

    TMPH=TMPH<<4;

    TMPL=TMPL>>4;

    temp=(TMPH+TMPL);

    if(temp<85)

    {

        dis [6]=LEDMAP[temp/10];

        dis [7]=LEDMAP[temp%10];

        temperature=temp;

    }

    else 

    {

        temperature=256-temperature;

        dis [6]=17;

        dis [7]=temperature%10;

    }  

}

————————————————-定时中断——————————————————

#define Tick   500           // 500 x 2 ms = 1s

unsigned int C100us;    

void T0Int() interrupt 1

{

  static unsigned char Pos=0x01;

  unsigned char LED;

  TH0  = 0xfc;

  TL0  = 0x18;

  P2 = 0;  

  LED = dis[k];

  k++;

  if(k>7)  k=0;

  P0 = LED;

  P2= Pos; 

  Pos <<= 1;

  if(Pos==0x00)  Pos=0x01;   

  C100us--;

  if (C100us == 0) {

    C100us = Tick;

    seconds_flag=1;                   //秒标志位,表明时间已到一秒

    seconds++;

    timer_s=seconds;

    if (seconds >= 60) {

      seconds = 0;

      minutes++;

      if (minutes >= 60) {

        minutes = 0;

        hours++;

        if (hours >= 24) hours = 0;

      }

    }

  }

}

——————————————————主程序————————————————-

void main()

{

  static bit wendu_flag=1;

  unsigned int x=60000;

  TMOD = 0x01;             //定时工作方式,采用工作方式1

  TH0  = 0xfc;

  TL0  = 0x18;

  IE   = 0x82;             // EA=1(中断总允许), ET0 = 1(允许定时器中断)

  hours   = 0;

  minutes = 0;

  timer_hours=0;

  timer_minutes=0;

  seconds = 0;

  hours_flag   = 0;

  minutes_flag = 0;

  naozhong_flag=0;

  C100us = Tick;

  TR0    = 1;              //启动定时器

  do{

  disp_buf[0]=0x3F;

  disp_buf[1]=0x07;   

  disp_buf[2]=0x3F;

  disp_buf[3]=0x06;

  disp_buf[4]=0x3F;

  disp_buf[5]=0xCF;

  if(seconds_flag)

   {

     seconds_flag=0;

     if(wendu_flag) 

     {

     read_temp();

     wendu_flag=0;

     }

     else

     {

     convert_temp();

     wendu_flag=1;

     }

   }

 }while(x--);

  while (1)

 {

  if(naozhong_flag==1)

  {

  dis[0]=LEDMAP[timer_hours/10];

  dis[1]=LEDMAP[timer_hours%10]|0x80;

   }

  else

  {

    dis[0] = LEDMAP[hours/10];

    dis[1] = LEDMAP[hours%10] | 0x80; 

   }

  if(naozhong_flag==1)

  {

   dis[2]=LEDMAP[timer_minutes/10];

    dis[3]=LEDMAP[timer_minutes%10]|0x80;

   }

   else

   {

    dis[2] = LEDMAP[minutes/10];

    dis[3] = LEDMAP[minutes%10] | 0x80;

    }

   dis[4] = LEDMAP[seconds/10];

   dis[5] = LEDMAP[seconds%10]| 0x80;

    scankey();

    keydeal();

if((timer_hours==hours)&&(timer_minutes==minutes)&&(timer_hours!=0)&&(timer_minutes!=0)&&(naozhong_flag==0))    P33=0;                   //定时时间到闹铃响

   if((P33==0)&&(abs(timer_minutes-minutes)>=1))      P33=1;

   if(seconds_flag)

   {

     seconds_flag=0;

     if(wendu_flag) 

     {

     read_temp();

     wendu_flag=0;

     }

     else

     {

     convert_temp();

     wendu_flag=1;

     }

   }

  }

}

四、实习小结

这是我第一次用单片机做成功的小制作硬件。在制作过程中,我对52单片机的了解进一步的加深,对KEIL软件的使用更加灵活。程序是整个系统的核心,没有程序,硬件就无法运行,所以程序的编写就是我们学习的重点。学好了每一个软件的使用方法,自己就可以在软件里做自己想实现的工能。回顾起此次单片机实习,从理论到实践,在接近两个星期的日子里,可以说是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说对单片机汇编语言掌握得不好……通过这次实习之后,我对单片机的了解更深了。总之这次单片机的实习让我把理论设计和工程实践相结合、巩固基础知识与培养创新意识相结合、个人作用和集体协作相结合等方面全面的培养学生的全面素质。这些在我今后的学习和工作当中都会有很大的帮助。

更多相关推荐:
单片机实训报告

单片机实训报告姓名学号班级指导老师实训时间前言一周的单片机实训很快就结束咯在这一周的时间里我学到了很多关于单片机各方面的知识老师在实训课中也教会咯我们很多关于单片机软件编程与硬件设施的知识一周的实训中我们一共实...

单片机实习报告

单片机实习报告1引言11实习目的随着人们生活水平的不断提高单片机控制无疑是人们追求的目标之一它给人们带来的方便也是不可否定的本次实习的目的在于加深AT89C51单片机的理解初步掌握单片机应用系统的设计方法通过本...

单片机实习总结报告

专业综合实习总结专业班级:电子信息工程0801学生学号:***指导教师:实习时间:20XX.6.2020XX.7.15机电工程学院一、实习目的和意义1、实习目的:(1)利用单片机小系统实习板,掌握电路原理图;(…

单片机实习报告

电子与信息工程学院程设计报(20##20##学年第2学期)课程名称:创新课题课程设计班级:电子0801学号:15姓名:指导教师:20xx年03月课告实习报告

单片机实训报告心得

广东轻工职业技术学院实训报告实训项目单片机实训系别:电子通信工程系专业:应用电子技术班级:嵌入式091班姓名:**学号:***指导老师:***实训地点:第三实训楼C309实训时间:20**年1月10日至1月14…

单片机实习报告

单片机实习报告题目姓名学院专业班级学号指导教师交通灯控制系统职称讲师20xx年5月27日内容提要本系统采用AT89S52作为交通灯控制系统的核心控制器件利用单片机的定时器产生秒级信号控制十字路口的红绿黄灯交替点...

单片机实训报告

目录一概述11设计制作产品的背景目的意义12设计制作产品的设计要求13分工情况工作计划及本人所总结工作14本课题的基本内容重点及难点二正文21实验原理22实验流程图23硬件设计24软件设计25C语言程序26简易...

《单片机实习报告温控系统

学院单片机课程设计报告书题目温度控制系统设计院系名称学生姓名专业名称班级时间学院自动化自动20xx年6月7日至6月17日温度控制系统设计一设计目的在现代化的工业生产中电流电压温度压力流量流速和开关量都是常用的主...

c51单片机实习报告

基于单片机实现短距离无线通信设计1引言短距离无线传输具有抗干扰性能强可靠性高安全性好受地理条件限制少安装灵活等优点在许多领域有着广泛的应用前景低功耗微型化是用户对当前无线通信产品尤其是便携产品的实际需求短距离无...

单片机论文、实习报告

单片机课程设计说明书题目数字式温度计的设计系部专业班级姓名学号指导教师起止日期单片机原理及应用课程设计任务书系部电子与通信工程系专业指导教师张刚林刘光灿陈威兵罗朝明冯璐谢志宇20xx650摘要在科学技术不断发展...

基于AT89S52单片机的多模式带音乐跑马灯设计实训报告

实训课题基于AT89S52单片机的多模式带音乐跑马灯设计一实训目的及要求1通过实训理解与掌握单片机系统的开发流程及常见系统的开发设计仿真调试等培养一定的单片机设计与开发能力2掌握按键电路的设计3掌握单片机复位电...

单片机最小系统实训报告

单片机最小系统实训报告一实训目的1掌握并理解单片机最小系统的原理和制作熟悉电子元件的参数以及应用2熟悉PCB板的工业制作流程并且要求会使用protel软件绘制相应的PCB图3复习使用keil51软件编写相应程序...

单片机实习报告(37篇)