首页 >> 实验教学 >> 实验项目 >> 详细内容
实验教学
 
实验项目 >> 正文
单片机原理及应用
日期:2021-12-09 17:43:17  发布人:nclgjsj  浏览量:335

 

 

 

   

 

实验一 开发环境

一、实验目的:掌握单片机的开发环境,学会Keil CProteus的使用方法。

二、实验要求:用单片机的P0.0口控制一个LED电路,并完成编程,使LED循环亮灭。

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验步骤:

  • Keil C的使用方法;

步骤1:建立工程文件

(1) 单击“Project"→“New μVision Project 菜单命令,打开“Create New Project" 对话框;

(2)在“保存在"下拉列表框中,选择工程保存目录(E: \ project\ ex11) 并在 “文件名” 文本框中输人工程名字(ex1_1),不需要加扩展名,单击“保存”按钮,出现如图1.3所示的选择目标器件“ Select Device for Target”对话框;
(3)在图1.3中,单击左侧列表框中; Atmel 项前面的“+”号,展开该层,单击其中的“ AT89C51”,然后再单击“OK"按钮;

(4)打开如图1.5所示的复制标准8051启动代码选择窗口界面,单击“(N)”按钮回到主界面。

步骤2:建立并添加源文件

(1)单击“File-New”菜单命令,在该窗口中输人源程序
(2)对该源程序检查校正后,单击“File -Save as...”菜单命令,将源程序另存为C语言源程序文件

(3)在工程管理窗口中“Source Group 1”项上单击鼠标右键打开快捷菜单,再选择“Add Files to Group ' Source Group 1'”菜单命令。然后“文件类型”下拉列表框中选择“C Source file( *.c)”,找到前面新建的“exl_ _1.c"文件并选择后,单击“Add"按钮加入工程中;

(4)在工程管理窗口“Source Group 1”项中会出现名为“ex1_ 1.c 的文件,说明新文件的添加已完成。

步骤3:配置工程属性

(1) 如图1.12所示,将鼠标移到工程管理窗口的"Target1 上,单击鼠标右键,再选“Options for Target 1 'Target1 " 菜单;

(2)单击“Output 选项卡,打开“Output”选项设置页面,选中“Create HEX File”复选框,再单击“OK"按钮。

步骤4:编译工程

(1)在主界面中,单击“Project”一“Build target 菜单命令(或按快捷键F7),或单击工具栏中的快捷图标“”来进行编译。

  • Proteus的使用方法;

单机P”选中所需的电子元件,按照下图给出仿真电路图。

 

1-1硬件仿真图

  • 实验程序:

keil C51编写如下程序:

ORG 0000H

JMP START

ORG 0030H

START: CLR P0.0

CALL DELAY

SETB P0.0

CALL DELAY

JMP START

DELAY: MOV 55H,#10

D1: MOV 56H,#200

D2: MOV 57H,#248

DJNZ 57H,$  

DJNZ 56H,D2

DJNZ 55H,D1

RET

END

五、实验结果Proteus仿真中加载编译的程序,观察到程序循环执行,LED一闪一灭。熟悉单片机应用的开发环境,完成了一个简单的单片机应用的设计过程。

六、实验心得:(不如少于200字)

 

 

 

 

实验二 流水灯的设计

一、实验目的:1、掌握C51的移位运算;

   2、熟悉C51程序设计,掌握程序结构和子程序的调用。

二、实验要求:用单片机的P1口接8LED,使LED依次间隔1秒,循环点亮。

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下2-1所示。

 

2-1 流水灯仿真图

五、实验程序如下

#include <reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint  unsigned int

void delay1ms(uint x)  //基准延时时间为1ms的延时子程序

{

 uint i,j;

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

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

}

main()

{

 uchar i;

 while(1)

  {

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

    {

     P1=_crol_(0x01,i);   //0000 1000

     delay1ms(80);

    }

  }

}

六、实验结果通过仿真实验,实验完成了循环点亮LED的要求。掌握了延时子程序的编写和移位函数的应用。

七、实验心得:(不如少于200字)

 

实验三 外部中断

一、实验目的:1、熟悉单片机中断系统;

       2、掌握外部中断的使用方法。

二、实验要求:用单片机的P1口接8LED,INT0中断控制8LED,当有INT0中断触发一次LED依次循环移动一位。

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下3-1所示。

 

3-1 外部中断仿真图

 

五、实验程序如下

#include <reg51.h>

#include <intrins.h>

unsigned char sum;

void delay1ms(unsigned int x)

{

 unsigned int i,j;

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

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

}

main()

{

 TCON=0X01; //TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0  IT0=1;

 IE=0X81;  //EA - - ES ET1 EX1 ET0 EX0 EA=1; EX0=1;

 while(1)

  {

  P1=_crol_(0x01,sum);

  }

}

void wbzd() interrupt 0

{

  EA=0;

  delay1ms(10);

  sum=(sum+1)%8;

  delay1ms(10);

  EA=1;

}

六、实验结论:通过实验仿真,实现了外部中断事件的相应。每按一次外部中断按键LED移位点亮一下。

七、实验总结:

 

实验四 定时器中断

一、实验目的: 1、熟悉单片机中断系统;

      2、掌握定时器/计数器中断的使用方法;

3、掌握定时器/计数器的初值的设置方法。

二、实验要求:T1获取1秒的定时,用单片机的P1口接8LED,使得每隔1秒循环移位点亮一个LED

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下4-1所示。

 

4-1 流水灯仿真图

 

五、实验程序:

#include<reg51.h>

#include<intrins.h>

#define uchar unsigned char

#define uint  unsigned int

uchar num;

main()

{

 TMOD=0X10;    //GATE CT M1 MO GATE CT M1 MO     0001 0000

 TH1=0X3C;    //TH1=(65536-50000)/256

 TL1=0XB7;    //TL1=(65536-50000)%256

 IE=0X88;    //EA - - ES ET1 EX1 ET0 EX0       1000 1000

 TCON=0X40;    //TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 0100 0000

 while(1)

   {

   P1=_crol_(0x01,num);

   }

}

void timer1() interrupt 3

{

 uchar js;

 TH1=(65536-50000)/256;

 TL1=(65536-49990)%256;

 js++;

 if(js==20)

   {

    num=(num+1)%8;

js=0;

   }

}

六、实验结果通过仿真实验,实现了定时器中断定时一秒的要求。掌握了定时器中断的应用方法。

七、实验心得:(不如少于200字)

 

实验五   多机通信

 

 

一、实验目的:1、掌握串行通信的异步通信方式的设置;

  1. 掌握多机通信的方法和步骤;
  2. 熟悉单片机的中断系统

二、实验要求:通过上位机选中通信的下位机,并向下位机发送数据,数据在下位机用LED指示输出的状态。

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下4-1所示。

 

5-1 多机通信实验图

 

五、实验程序:

1、上位机程序:

#include <reg51.h>

void initurat()

{

 SCON=0Xd0;   //M0 M1 M2 REN TB8 RB8 TI RI  1000 0000

 TMOD=0X20;

 TH1=TL1=0XFa;

 PCON=PCON|0X80;

 IE=0X90;   //EA - - ES ET1 EX1 ET0 EX0 1001 0000

 TR1=1;

}

void fssj(unsigned char x)

{

 SBUF=x;

 while(!TI);

 TI=0;

}

main()

{

 unsigned char addr,sum;

 initurat();

 while(1)

   {

     addr=P0;

 TB8=1;

 fssj(addr);

 TB8=0;  

 sum=P1;

 fssj(sum);  

   }

}

2、下位机程序:

#include <reg51.h>

unsigned char js,addr;

void delay1ms(unsigned int x)

{

 unsigned int i,j;

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

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

}

void initurat()

{

 SCON=0Xd0;   //M0 M1 M2 REN TB8 RB8 TI RI  1011 0000

 TMOD=0X20;

 TH1=TL1=0XFA;

 PCON=PCON|0X80;

 IE=0X90;   //EA - - ES ET1 EX1 ET0 EX0 1001 0000

 TR1=1;

}

unsigned char jssj()

{

 while(!RI);

 if(RB8==1)

   return 0xee;  //若接收到地址位,则接受状态返回非0

 js=SBUF;  //接收到的数据放在js

 RI=0;

 return 0; //若接收到地址位,则接受状态返回0

}

main()

{

 initurat();    //串行中断初始化

 P2=0;    //LED初始状态

 while(1)

   {   

  SM2=1;    //多机工作方式

  while(addr!=P0)  //判断接收的地址不为本机地址,执行循环直到满足条件

    {

    RI=0;

 while(!RI);

 addr=SBUF;

 RI=0;

 P2=0;    

    }

  SM2=0;  //接收的地址为本机地址,则把接收的数据送P2口输出

  addr=jssj();  //执行接受数据,结果送num

  if(addr==0)  //地址位返回非0,只有返回0时表示是数据

    {

 P2=js;  //输出num的值

 delay1ms(100);

}       

   }

}

六、实验结论

  1. 上位机发送第九位数据,读取上位机P0口状态作为下位机的地址设置,并发送下位机的通信地址;
  2. 读取上位机P1口状态作为要发送的数据,并且上位机通过串行通信发送数据;
  3. 下位机允许多机通信,接收上位机的地址;
  4. 选中地址的下位机关闭多机通信,选择直通的异步通信方式,接收上位机的发送的数据;
  5. P2口输出接收的数据。

七、实验心得:(不如少于200字)

 

 

实验六 数码管的动态显示

一、实验目的: 1、掌握数码管的显示原理;

      2、掌握动态显示方式。

二、实验要求:用P0驱动2个数码管,使数码管从00-99循环显示数值,每次的显示为0.4秒。

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下6-1所示。

 

6-1 数码管动态显示仿真图

五、实验程序:

#include<reg51.h>

#include<intrins.h>

#define uint unsigned int

#define uchar unsigned char

#define ulong unsigned long

uchar code smg[]={0x3f,0x06,0x5b,0x4f,0x66,

          0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管0-9字型码

void delay1ms(uint x)

{

 uint i,j;

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

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

}

void displed(uchar i,j)  //动态显示子程序,i为显示的数值,j为位选

{

 P0=smg[i];   //输出i的字型码

 P2=_crol_(0xfe,j);   //输出位选信号,j0表示选通十位,j1表示选通个位

 delay1ms(1);   //延时

 P2=0xff;   //关位选

}

void disp(ulong x)

{

 uchar a[8];

 uchar i,j;   //12345678

 ulong num=1;

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

   {

     a[i]=(x/num)%10;

 num=num*10;    

 if(num>x) break;

   }

 for(j=0;j<=i;j++) displed(a[j],7-j);

}

main()

{

 uchar num;  //i为显示的数值,num控制每一个数值的显示时间

 ulong i;

 while(1)

   {

    for(i=0;i<10000000;i++)    //i是在0-99之间取值

  {

    for(num=0;num<20;num++)//num200,表示每一个数值显示0.4

  {

            disp(i) ;

//displed(i/10,0); //在十位数码管上显示i的十位

        //displed(i%10,1); //在个位数码管上显示i的个位

  }

  }

   }

}

六、实验结果通过仿真实验,实现了数码管的动态显示,实现了实验要求。掌握了数码管显示的原理,掌握了动态显示的设计方法。

七、实验心得:(不如少于200字)

 

 

实验七 独立按键

一、实验目的:1、掌握中断按键判断;

   2、熟悉软件去抖的方法。

二、实验要求:用一个按键加数码管显示的数值,用另一个按键减数码管显示的数值,数码管显示的范围是0-9

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下7-1所示。

 

7-1 独立按键实验仿真图

五、实验程序:

#include<reg51.h>

#include<intrins.h>

#define uchar unsigned char

#define uint  unsigned int

uchar code smg[]={0x3f,0x06,0x5b,0x4f,0x66,

                  0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管字型码

uchar sum;    //sum为数码管显示的数值

sbit jia = P3^2;

sbit jian = P3^3;

void delay1ms(uint x)  //基准延时1ms的子程序

{

 uint i,j;

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

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

}

void displed(uchar i,j)   //显示子程序,i是显示内容,j是位选

{

 P2=smg[i];

 j=0;

 delay1ms(1);

}

main()

{

  while(1)

    {

  if(jia==0)

    {

 delay1ms(10);  //去抖延时

 sum=(sum+1)%10;  //sum数值在0-9范围内改变,+1

 delay1ms(10);  //去抖延时

}

  if(jian==0)

    {

 delay1ms(10);  //去抖延时

 if(sum==0) sum=10;

 sum--;  //sum数值在0-9范围内改变,-1

 delay1ms(10);  //去抖延时

}

  displed(sum,0);

}

}

 

六、实验结果:通过仿真实验,实现了独立按键的扫描,达到了实验要求。掌握了独立按键的判断方法及应用设计。

七、实验心得:(不如少于200字)

 

 

实验 矩阵按键实验

一、实验目的:1、掌握单片机的矩阵按键设计方法

   2、熟悉软件去抖的方法。

二、实验要求:设计14*4的矩阵按键,并给按键编号0-15;当有按键按下就用数码管显示该按键的编号

三、实验设备:计算机、Keil C51编程软件、Proteus仿真软件等。

四、实验仿真图:仿真图如下8-1所示。

 

8-1 矩阵按键实验仿真图

五、实验程序:

#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

uchar code smg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

uchar jz;

void delay1ms(uint x)

{

 uint i,j;

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

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

}

void dispw(uchar w,uchar s)

{

 P2=_cror_(0x7f,w);

 P0=smg[s];

 delay1ms(1);

 P2=0xff;

 P0=0xff;

}

void scanjz()

{

uchar hyw,lyw,hsm,lsm; //gw存放个位数,sw存放十位数,hyw负责p1.0-p1.3送低电平

//lsm扫描p1.4-p1.7是否有低电平,hsm,lsm负责判断按键是否按下松开

for(hyw=0;hyw<4;hyw++)

  {

  P1=_crol_(0xfe,hyw); //p1.0-p1.3送低电平,进行行的扫描

    for(lyw=0;lyw<4;lyw++)     //扫描p1.4-p1.7是否有低电平

  {

   lsm=_crol_(0xfe,lyw+4)&0xf0; //lsm赋值,取高四位值

   hsm=P1&0xf0; //hsm赋值,读取P1口高四位值

   if(hsm==lsm) //判断按键是否按下

     {

   delay1ms(10);  //去抖延时

   while(hsm==lsm)  //判断按键是否松开

     {

   hsm=P1&0xf0;  //重新读取hsm

       jz=hyw*4+lyw;  //给按键编号jz赋值

     }

 }

  }

  }

}

main()

{

 uchar gw,sw; //jz存放矩阵按键编号,gc用于存放P1高四位

  while(1)

    {

  scanjz();

  gw=jz%10;

  sw=jz/10;

  dispw(0,gw);

  dispw(1,sw);

}

}

六、实验结论通过仿真实验,实现了矩阵按键的扫描,达到了实验要求。掌握了矩阵按键的判断方法及应用设计。

七、实验心得:(不如少于200字)

核发:nclgjsj 点击数:335收藏本页