单片机课后实验报告

时间:2024.4.5


实验(1)名称 :I/O控制

一、   实验要求

将8个LED灯分别接入任何一个端口(P0、P1、P2、P3),让LED灯不停止地进行循环亮/灭(亮/灭现象也可以自由发挥,如并列2个LED或交叉几个LED灯进行循环亮/灭)。

二、实验原理

用红外对管输入一个脉冲,利用了左移函数_crol_()使得LED巡回亮灭,中间加入了延迟函数,使得LED的亮灭,让我们可以明显看到在通过红外对管输入一个脉冲时,数码管依次亮灭。

 


 

三、程序设计


#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define aint unsigned int

void delay(uchar);

void main()

{

uchar led;

    led=0Xfe;       

         P1=led;

           while(1)

           {

           led=_crol_(led,1);          //左移函数

           delay(50);

           P1=led;

           delay(50);

           }

}

void delay(uint c)

{

  uchar a,b;

  for(a=c;a>0;a--)

     {

    for(b=200;b>0;b--);

                   }

 }


四、现象及结果

从红外对管处给一个脉冲,流水灯亮一个,依次循环。

实验(2)名称中断与定时

一、实验要求

(1)外部中断的使用

采用2种触发方式(边沿与电平)进行。每次中断点亮/灭掉一个LED即可。

(2)Timer定时器的使用

使用16位和8位自动装载方式定时1/2/3秒,循环亮/灭LED灯。

三、程序设计

(1)外部中断的使用


#include<reg52.h>

sbit p10=P1^0;

sbit p17=P1^7;

sbit key=P3^2;

sbit key1=P3^3;

void init();

void delay(unsigned z);

int b;

void main()

{

         init();

         while(1);

}

void init()

{

         TCON=0x05;

         EA=1;

         EX0=1;

         EX1=1;

         P1=0xfe;

}

void out_interrupt0()   interrupt 0

{

         if(!key)

         {

                   delay(20);

                   if(!key)

               {b=p17;

                   P1=P1<<1;

                   p10=b;      

        


         while(!key);

                   delay(20);

                   while(!key);

                   }

         }

}

void out_interrupt1() interrupt 2

{

         if(!key1)

         {

                   delay(20);

                   if(!key1)    

               b=p17;

                   P1=P1>>1;

                   p10=b;      

        

                   delay(2000);

         }

}

void delay(unsigned z) //延迟

{

         unsigned int x,y;

         for(x=z;x>0;x--)

         for(y=110;y>0;y--);

}

(2)Timer定时器的使用

1.16位定时器

#include<reg52.h>

sbit p10=P1^0;

sbit p17=P1^7;

sbit speak=P2^7;

void init();

int time=0,b;

//unsigned char code table[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void main()

{

         init();

         while(1)

         {

                   if(time==20)

                   {

                            time=0;

                            b=p17;

                            P1=P1<<1;

                            p10=b;

                   }

         }                         

}

void init()

{

         TMOD=0x01;

         P1=0xfe;

         EA=1;

         ET0=1;

         TR0=1;

         TH0=0x3c;

         TL0=0xb0;

         time=0;

}

void timer0() interrupt 1

{

         TH0=0x3c;

         TL0=0xb0;

         time++;

}

2.8位自动重装

#include<reg52.h>

sbit p10=P1^0;

sbit p17=P1^7;

sbit speak=P2^7;

void init();

int time=0,b;

void main()

{

         init();

         while(1)

         {

                   if(time==5000)

                   {

                            time=0;

                            b=p17;

                            P1=P1<<1;

                            p10=b;

                   }

         }

                           

}

void init()

{

         TMOD=0x02;

         P1=0xfe;

         EA=1;

         ET0=1;

         TR0=1;

         TH0=0x37;

         TL0=0x37;

         time=0;


}

void timer0() interrupt 1

{

         time++;

}


四、现象及结果

(1)外部中断:

当按下K1键,LED灯左移。按下K2键,LED右移一位。

(2)Timer定时器

LED灯以1秒的间隔循环亮灭。

实验(3)名称键盘键值的读取

一、实验要求

完成4X4的矩阵键盘键值的读取。采用联机调试的方式,将读取的键值赋给一变量,在keil变量观察窗口中查看键值。

二、实验原理

三、程序设计


#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

uint key;

uint code table[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,

0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

uint key_scan()

{

       uint cord,cord_hang,cord_lie;

       P3=0xf0;

       cord_lie=P3;

       P3=0x0f;

       cord_hang=P3;

       cord=cord_hang+cord_lie;

       if(cord!=0xff)

       {

       return(cord);  

}

       return(cord);  

 }

void main()

{    

       uint temp;

       P2=0xfe;

       P1=0xfe;

       while(1)

       {

              temp=key_scan();

              if(temp!=0xff)

              {

                    switch(temp)

                     {

                            case 0xee:key=0;break;

                            case 0xed:key=1;break;

                            case 0xeb:key=2;break;

                            case 0xe7:key=3;break;

                            case 0xde:key=4;break;

                            case 0xdd:key=5;break;

                            case 0xdb:key=6;break;

                            case 0xd7:key=7;break;

                            case 0xbe:key=8;break;

                            case 0xbd:key=9;break;

                            case 0xbb:key=10;break;

                            case 0xb7:key=11;break;

                            case 0x7e:key=12;break;

                            case 0x7d:key=13;break;

                            case 0x7b:key=14;break;

                            case 0x77:key=15;break;

                     }

                     P2=~key;

                     P0=~table[key];

              }

             

}


四、现象及结果

当按下0—16的按键时,数码管显示相应的键值。

实验(4)名称LED数码管的显示

一、   实验内容及目的

用4支8段数码管分别用动态和静态显示4位数,如1234和1111。硬件电路自行搭接。

二、实验原理

通过控制数码管的段选和位选,让数码管显示不同的值。

 

(1)静态扫描

给位选低电平,数码管亮,给段选段码信号,

(2) 动态扫描

控制位选,选择一个数码管亮,然后给段选分别送相应的值,通过调节延时的长短和数码管的余晖,让数码管动态显示出1234,而人为的感觉像是静态显示。

三、程序设计

(1)静态扫描


#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

uint code table[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,

0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void delay(uint z)  

{

       uint x,y;

       for(x=z;x>0;x--)

              for(y=110;y>0;y--);

}

void main()

{

       while(1)

       {

             

              P1=0x00;

              delay(10);

              P0=0xc0;

       }

}

(2) 动态扫描

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

uint code table[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,

0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void delay(uint z)  

{

       uint x,y;

       for(x=z;x>0;x--)

              for(y=110;y>0;y--);

}

void main()

{

       while(1)

       {   P1=0xfe;

              P0=~table[0];

              delay(10);

              P1=0xfd;

              P0=~table[1];

              delay(10);

              P1=0xfb;

              P0=~table[2];

              delay(10);

              P1=0xf7;

              P0=~table[3];

              delay(10);

       }

}


四、现象及结果

(1)静态扫描

数码管显示0000。

(2) 动态扫描

数码管显示1234。

实验(5)名称串口通讯

一、实验要求

通过单片机的UART,完成单片机对PC(计算机)的通讯。学会使用上位机串口助手,通过该助手完成单片机与PC之间的“接收”与“发送”数据(任意字符串)。具体要求:

(1) 通过矩阵键盘输入数值,并设计功能键(如”A”发送);

(2) 键盘输入数值放入显示缓冲单元(显缓)中,通过4位LED数码管显示;

(3) 按下“功能键”,实现发送(显缓中的数据)与接收(上位机发送的数据,并在LED上显示)。

二、实验原理

通过单片机的TXD、 RXD引脚实现串行口的收发数据,让后用RS232线实现单片机和电脑之间的链接,其中要经过MAX232进行电平转换。

 

三、程序设计


#include<reg52.h>

#include<stdio.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

uint cord_hang,cord_lie,shu,send,accept=1;

 uint code table[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,

0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void serial_accept();

uint a=16,b=16,c=16,d=16;

uint wei=0,key,temp,s1,s2,s3,s4;

uint e=1,flag=0;

void delay(uint z)     

{

         uint x,y;

         for(x=z;x>0;x--)

                   for(y=110;y>0;y--);

}

void display(uchar a,uchar b,uchar c,uchar d)

{

   dula=0;

   P0=table[a];

   dula=1;

   dula=0;

   wela=0;

   P0=0xfe;

   wela=1;

   wela=0;

   delay(1);

   P0=table[b];

   dula=1;

   dula=0;


   P0=0xfd;

   wela=1;

   wela=0;

   delay(1);

   P0=table[c];

   dula=1;

   dula=0;

   P0=0xfb;

   wela=1;

   wela=0;

   delay(1);

   P0=table[d];

   dula=1;

   dula=0;

 


 P0=0xf7;

   wela=1;

   wela=0;

   delay(1);     

}

uint key_scan()

{

         P3=0xf0;

         cord_hang=P3;

         P3=0x0f;

         cord_lie=P3;

         cord_hang=cord_hang|cord_lie;

         if(cord_hang!=0xff)             //消抖

         {

                   delay(20);

                   P3=0xf0;

                   cord_hang=P3;

                   P3=0x0f;

                   cord_lie=P3;

                   cord_hang=cord_hang|cord_lie;       

                   if(cord_hang!=0xff)

                   {

                            delay(20);

                   P3=0xf0;

                   cord_hang=P3;

                   P3=0x0f;

                   cord_lie=P3;

                   cord_hang=cord_hang|cord_lie;       

                   if(cord_hang!=0xff)

                   return(cord_hang); //有键按下时候的返回值

                   }

         }

         return(cord_hang);     //无键按下时候的返回值,为0xff

}


 

void key_num(int j)

{

         wei++;

         if(wei==5)

         {wei=1;a=16;b=16;c=16;d=16;}

      if(wei!=0)                                       //实时显示

         {

                   switch(wei)

                   {

                            case 1: a=j;s1=a; break;

                            case 2: b=j;s2=b; break;

                            case 3: c=j;s3=c; break;

                            case 4: d=j;s4=d; break;

                   }

         }

}

void key_combin()

{

         switch(wei)

         {

                   case 1: shu=s1; break;

                   case 2: shu=s2+s1*10; break;

                   case 3: shu=s3+s2*10+s1*100; break;

                   case 4: shu=s4+s3*10+s2*100+s1*1000; break;

         }

}

void key_accept()

{      

         printf("请输入数据:");

         TI=0;  //使不会应为发送标示位而进入中断函数

         EA=1;

         ES=1;  //打开串行中断

         while (flag==0); //原地等待发送完数据

         flag=0;

         b=e&0x0f;                 //显示低4位

         a=e&0xf0;               //显示高4位;

         a=a>>4;

         c=16;

         d=16;

         wei=4;

         EA=0;

         ES=0;

         TI=1;


}

void serial_init()

{

         SM0=0;

         SM1=1;

         REN=1;

         TMOD=0x20;

         TR1=1;

         TH1=0xfd;

         TL1=0xfd;

         TI=1;

         //RI=1;

         EA=0;

         ES=0;

}

void serial() interrupt 4

{

         if(RI==1)

         { e=SBUF;

         flag = 1;

         RI=0;}

}

 void main()

 {

        serial_init();

         while(1)

         {      

                   temp=key_scan();

                   if(temp!=0xff)

                   {

                            switch(temp)

                            {


                                     case 0xee:key_num(1);break;

                                     case 0xde:key_num(2);break;

                                     case 0xbe:key_num(3);break;

                                     case 0x7e:key_num(4);break;

                                     case 0xed:key_num(5);break;

                                     case 0xdd:key_num(6);break;

                                     case 0xbd:key_num(7);break;

                                     case 0x7d:key_num(8);break;

                                     case 0xeb:key_num(9);break;

                                     case 0xdb:key_num(10);break;

                                     case 0xbb:key_num(11);break;

                                     case 0x7b:key_num(12);break;

                                     case 0xe7:key_num(13);break;

                                     case 0xd7:key_combin();break;       //组合成10进制数

                                     case 0xb7:printf("%d",shu);break;   //把10进制数输出

                                     case 0x77:key_accept();break;                    //接收PC机的值。

                            }

                            while(key_scan()!=0xff);//松手检测

                             

                   }

                   display(a,b,c,d);

         }

 }


四、现象及结果

矩阵键盘的第一个到第13个键盘,按下后,数码管会显示0—C十六进制数。

按下第14个按键后,最新按下的4个数会整合成一个4位数,并在数码管在显示。

按下第15个案件后,会吧数据发送到PC机的串口调试助手里面。

按下第16个按键后,会等待PC机串口发送数据并显示在数码管上。

实验(6)名称综合实验

一、实验内容及目的

通过功能按键(A,B,C,D等)实现“秒表”、“通讯”和“步进电机的控制”等组合功能。

二、实验原理

本次实验是综合前面七次的实验,从而达到综合应用的目的。

三、程序设计


#include<reg52.h>

#include<stdio.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^6;

sbit wela=P2^7;

//sbit key_en=P1^0;

 uint cord_hang,cord_lie,shu,send,accept=1;

 uint code table[]={0x3f  , 0x06 , 0x5b , 0x4f , 0x66 ,

0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void serial_accept();

uint a=16,b=16,c=16,d=16;

uint wei=0,key,temp,s1,s2,s3,s4,flag_dian_ji;

uint e=1,flag=0,timer,miao_biao;

bit dian_ji_fangxiang;

uchar dot;

void delay(uint z)  

{

       uint x,y;

       for(x=z;x>0;x--)

              for(y=110;y>0;y--);

}

void display(uchar a,uchar b,uchar c,uchar d,uchar dt)

{

   dula=0;

 


 P0=table[a];

   dula=1;

   dula=0;

  

   wela=0;

   P0=0xfe;

   wela=1;

   wela=0;

   delay(1);

  

   P0=table[b]|dt;

   dula=1;

   dula=0;

  

   P0=0xfd;

   wela=1;

   wela=0;

   delay(1);

   P0=table[c];

   dula=1;

   dula=0;

  

   P0=0xfb;

   wela=1;

   wela=0;

   delay(1);

  

   P0=table[d];

   dula=1;

   dula=0;

  

   P0=0xf7;

   wela=1;


   wela=0;

   delay(1);  

}

uint key_scan()

{

       P3=0xf0;

       cord_hang=P3;

       P3=0x0f;

       cord_lie=P3;

       cord_hang=cord_hang|cord_lie;

       if(cord_hang!=0xff)                //消抖

       {

              delay(20);

              P3=0xf0;

              cord_hang=P3;

              P3=0x0f;

              cord_lie=P3;

              cord_hang=cord_hang|cord_lie;   

              if(cord_hang!=0xff)

              {

                     delay(20);

              P3=0xf0;

              cord_hang=P3;

              P3=0x0f;

              cord_lie=P3;

              cord_hang=cord_hang|cord_lie;   

              if(cord_hang!=0xff)

              return(cord_hang); //有键按下时候的返回值

              }

             

       }

       return(cord_hang);   //无键按下时候的返回值,为0xff

}

void key_num(int j)

{

       wei++;

       if(wei==5)

       {wei=1;a=16;b=16;c=16;d=16;}

     if(wei!=0)                                  //实时显示

       {

              switch(wei)

              {

                     case 1: a=j;s1=a; break;

                     case 2: b=j;s2=b; break;

                     case 3: c=j;s3=c; break;

                     case 4: d=j;s4=d; break;

              }

               

       }

}

 

void key_combin()

{

       switch(wei)

       {

              case 1: shu=s1; break;

              case 2: shu=s2+s1*10; break;

              case 3: shu=s3+s2*10+s1*100; break;

              case 4: shu=s4+s3*10+s2*100+s1*1000; break;

       }

       //s1=0;s2=0;s3=0;s4=0; 

}

void key_accept()

{    

       printf("请输入数据:");

       TI=0;  //使不会应为发送标示位而进入中断函数

       EA=1;

       ES=1;  //打开串行中断

       while (flag==0); //原地等待发送完数据

       flag=0;

       //P1=e;

       b=e&0x0f;             //显示低4位

       a=e&0xf0;            //显示高4位;

       a=a>>4;

       c=16;

       d=16;

       wei=4;

       EA=0;

       ES=0;

       TI=1;

      

}


void serial_init()

{

       SM0=0;

       SM1=1;

       REN=1;

       TMOD|=0x20;

       TR1=1;

       TH1=0xfd;

       TL1=0xfd;

       TI=1;

       EA=0;

       ES=0;

}

void miaobiao_init()

{

       TMOD|=0x01;

       TH0=0xfc;

       TL0=0x18;

       EA=1;

       ET0=1;

//     TR0=1;

       timer=0;

}

void timer0() interrupt 1

{

       TH0=0xfc;

       TL0=0x18;

       timer++;

       if(timer==10)

       {

              timer=0;

              miao_biao++;

              if(miao_biao==5999)

              miao_biao=0;


       }

}

void serial() interrupt 4

{

       if(RI==1)

       { e=SBUF;

       flag = 1;

       RI=0;}

}

void dian_ji_wei()

{

       flag_dian_ji=~flag_dian_ji;

       a=16;

       b=16;

       c=16;

       d=16;

}

void dian_ji_qudong()

{

       uint num=0;

       P2=0x08;

       for(num=0;num<3;num++)

       {

              if(dian_ji_fangxiang)

              {P2=_crol_(P2,1);if(P3==0x80)P3=0x08;}

              else

              {P2=_cror_(P2,1);if(P3==0x08)P3=0x80;}

              delay(5);

       }    

}

 void main()

 {

      uchar clr;

      serial_init();

       miaobiao_init();

       while(1)

       {    

              temp=key_scan();

              if(temp!=0xff)

              {

                     switch(temp)

                     {

                            case 0xee:key_num(1);break;

                            case 0xed:key_num(2);break;

                            case 0xeb:key_num(3);break;

                            case 0xe7:key_num(4);break;

                            case 0xde:key_num(5);break;

                            case 0xdd:key_num(6);break;

                            case 0xdb:key_num(7);break;

                            case 0xd7:key_num(8);break;

                            case 0xbe:key_num(9);break;

                            case 0xbd:key_num(10);break;

                            case 0xbb:{TR0=~TR0,wei=0;}break;            //秒表显示

                            case 0xb7:dian_ji_fangxiang=~dian_ji_fangxiang;break;                      //电机反向

                            case 0x7e:dian_ji_wei();break;

                            case 0x7d:key_combin();break;     //组合成10进制数

                            case 0x7b:printf("%d",shu);break; //把10进制数输出

                            case 0x77:key_accept();break;                //接收PC机的值。

                     }

                     while(key_scan()!=0xff);//松手检测

              }

              if(flag_dian_ji)

              {dian_ji_qudong();}

              else if(wei==0)

              {

                     clr=1;

                     dot=0x80;

                     d=miao_biao%10;

                     c=miao_biao/10%10;

                     b=miao_biao/100%10;

                     a=miao_biao/1000;

              }

              else if(wei!=0)

              {

                     dot=0;

                     if(clr)

                     {a=16;b=16;c=16;d=16;clr=16;}

             

              }

               display(a,b,c,d,dot);

       }

 }


四、结果与现象

矩阵键盘的第一个到第10个键盘,按下后,数码管会显示0—a ,按下第11个键后,数码管显示4位秒表;按下12个键后:电机反向;按下第13个键后:电机启动;按下第14个按键后,最新按下的4个数会整合成一个4位数,并在数码管在显示。按下第15个按键后,会把数据发送到PC机的串口调试助手里面。按下第16个按键后,会等待PC机串口发送数据并显示在数码管上。

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

单片机实验报告学生姓名学号专业指导教师学院信息与电气工程学院20xx年11月单片机实验报告实验一MCS51指令系统实验数据排序1实验目的熟悉MCS51指令系统掌握程序设计方法加深对内部存储器读写的认识熟悉仿真开...

单片机实验报告

通信与信息工程学院20xx20xx学年第二学期实验报告课程名称单片机原理及应用专业班级学号学生姓名指导教师日期20xx年4月15日1实验一单片机汇编语言程序设计一实验目的1学习MedWin或Keilc51仿真软...

单片机实验报告

题目单片机组成原理实验报告学院计算机科学与工程学院专业信息安全姓名学号20xx年12月8日实验一输入输出接口编程一实验目的1掌握Keil软件的基本使用12掌握单片机汇编语言基本编程二实验内容1学习用Keil软件...

51单片机课程设计实验报告

51单片机课程设计报告学院:专业班级:姓名:指导教师:设计时间:51单片机课程设计一、设计任务与要求1.任务:制作并调试51单片机学习板2.要求:(1)了解并能识别学习板上的各种元器件,会读元器件标示;(2)会…

单片机实验报告

海南大学届单片机实验报告4份论文题目学生姓名学号所在院系专业班级授课教师完成时间蜂鸣器实验实验目的1熟悉实验板中蜂鸣器工作原理掌握汇编编程控制蜂鸣器播放音乐2掌握单片机编程控制蜂鸣器发出不同频率声音的方法3了解...

单片机实验报告

单片机课程设计报告实验五系别物理与电子工程学院年级专业班级学号学生姓名指导教师设计时间常熟理工学院课程设计报告目录1题目22实验要求221实验目的222实验内容23总体设计231硬件设计232软件设计44运行结...

51单片机实验报告

08424020xx单片微型计算机原理学院班级学号姓名指导教师成绩120xx年6月08424020xx硬件实验实验一定时器中断实验实验内容fosc110592MHzT0方式2产生定时中断实现秒表功能数码管后两位...

单片机实验报告

单片机实验报告实验二并行口输入输出实验循环彩灯控制任务一1实现的功能P1口接8个开关P0口接8个灯每个开关对应一个灯实时读取开关状态开关闭合时灯亮开关断开时灯灭2硬件原理图3流程图4程序ORG0000H程序入口...

单片机实验报告

一实验目的1熟练单片机的结构组成及原理2软硬兼施采用硬件电路的焊接搭建和软件的设计调试下载亲自动手对硬件系统加深了解的同时软件编程也能得心应手3了解如何从硬件和软件上分析问题排除故障二实验内容MCS51MCS5...

单片机最小系统实验报告

单片机原理及应用技术设计课题系别专业学号姓名指导老师课程设计报告20xx年6月单片机最小系统流水灯的设计一单片机简介由于单片机技术在各个领域正得到越来越广泛的应用世界上许多记成电路生产家相继推出各种类型的单片机...

单片机实验报告

单片机原理及应用一实验目的实验报告实验要求二实验电路及汇编源程序程序要加注释三仿真结果或硬件调试结果分析实验一存储器读写一实验目的1掌握寄存器存储器读写等汇编指令2掌握编程软件编辑编译调试等基本操作二实验内容1...

单片机实验报告

单片机实验报告四姓名学号时间周一11-13地点计708指导老师:实验题目C51单片机片上资源开发实验一.实验目的与要求?学习单片机片上资源开发技术?研究用片上资源实现自动控制的方案二:实验环境在KeiluVis…

单片机实验报告(42篇)