单片机实验报告 下载本文

单片微型计算机原理及应用 实验报告

学院名称 专业名称 学生姓名

学生学号 任课教师

实验报告成绩

教务处 制 2015年 1 月 13 日

1. 单片机实验平台简介

实验采用风标电子微控制器仿真实验实训箱,包含丰富的硬件资源与接口电路、多种处理器模块。系统采用“核心板+底板”双层结构,通过更换不同型号核心板,可学习不同系列的单片机及CPLD等。此实验系统针对快速掌握运用单片机和CPLD而开发的,含大量的硬件资源,能不同程度地满足现代电子技术实验的要求。同时,本系统丰富的功能单元,能够做出超出大纲要求的的综合实验。

2.Keil uVision 4软件简介

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,在功能上、结构性、可读性、可维护性上有明显的优势。提供了包括C编译器、宏汇编、连接器、库管理和一个强大的仿真调试器。使用C语言编程,Keil几乎就是必选,其方便易用、强大的软件仿真调试工具令人事半功倍。

实验一

I/O开关量输入实验

[实验目的]

熟悉单片机的最小系统,了解单片机I/O的结构;掌握按键键值的读入和处理;学习简单程序的编写。

[实验内容]

MCU-AT89S52 P10 P11 P00~P07 8位独立按键 K1 K2 8位独立LED D1~D8 [实验要求]

1、利用单片机,按键和发光二极管,构成一个LED灯控制电路;

2、上电时, 点亮LED, 按下K1时, LED向左移一位 ,按下K2时, LED向右移一位。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。 3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int

/**********单片机IO口引脚定义********************************************/ #define LED P0 sbit K1 = P1^0; sbit K2 = P1^1;

/**********函数定义******************************************************/ uchar scan_key();

void proc_key(uchar key_v); void delayms(uchar ms);

/**********主函数********************************************************/ void main(void) { uchar key_s,key_v; key_v = 0x03; //初始化IO口 LED = 0xfe; while(1) { key_s = scan_key(); if(key_s != key_v) //判断按键是否按下 { delayms(10); //延时消抖 key_s = scan_key(); if(key_s != key_v) { key_v = key_s; proc_key(key_v); } } } }

/**********键盘扫描函数**************************************************/ uchar scan_key() { uchar key_s; key_s = 0x00; key_s |= K2; key_s <<= 1; key_s |= K1; return key_s; //返回按键号 }

/**********键盘处理函数**************************************************/ void proc_key(uchar key_v) { if((key_v & 0x01) == 0) { LED = _cror_(LED,1); //循环右移一位 }

else if((key_v & 0x02) == 0) { LED = _crol_(LED, 1); //循环左移一位 } }

/***********延时函数*****************************************************/ void delayms(uchar ms) // 延时子程序 { uchar i; while(ms--) { for(i = 0; i < 120; i++); } }

[实验现象及结果]

上电时, 点亮P00的LE,当按下K1时, LED向右移一位,按下K2时, LED向左移一位.

实验二 I/O驱动实验

[实验目的]

了解I/O口的电气特性和驱动能力。掌握程序编写的方法。了解LED电路中加入限

流电阻的原因。

[实验内容]

MCU-AT89S52 P00~ P07 8位独立LED D1~ D8 [实验要求]

利用单片机及8个发光二极管等器件,构成一个流水灯单片机系统。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。

3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

4、如果无仿真工程时,可跳过下列步骤。有相应的仿真工程文件时,可进行下列步骤:

a、双击打开P_PROTEUS文件夹中的后缀为DSN的仿真工程文件。

b、在处理器芯片AT89C52器件上,鼠标右键单击,选择Edit Properties选项,或者双击AT89C52芯片,在Program File的浏览选项中添加上面步骤中生成的HEX文件。点击OK,完成HEX文件添加。

c、选择菜单Debug的下拉菜单Start/Restart Debugging选项。此时程序已处于调试状态,同样再次选择菜单Debug,选择Execute选项,程序开始运行。可通过人机接口观察程序的效果。

5、连接ISP下载器一端到USB接口,另一端连到目标板。打开实验台电源,参考产品说明书中的ISP下载软件使用方法对程序进行下载。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int

/*********************引脚定义********************/ #define LED P0

/*********************延时函数********************/ void delayms(uchar ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } }

/*********************主函数**********************/ void main(void) { LED = 0xfe; //初始化P0口 while(1) { //延时 delayms(250); LED = _crol_(LED,1); //循环右移1位,点亮下一个LED

}

}

[实验现象及结果]

实现LED流水灯

实验三

外部中断计数实验

[实验目的]

掌握单片机外部中断的设置,中断函数的处理。

[实验内容]

MCU-AT89S52 P00~P07 P10~P13 P32 8位共阳数码管 SA~SH C0~C3 8位独立按键 K1

[实验要求]

在单片机接一个按键作为外部的中断输入信号,通过数码管显示中断次数。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。

3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char #define uint unsigned int

/**********************共阳数码管编码表***************************/ unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3

0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off

unsigned char dis_buf[4]; // 显示缓冲区 uint int0_cnt=0; //计数初始化

/**********************函数定义***********************************/ void update_disbuf(); void delayms(uint j);

/**********************主函数*************************************/ void main(void) { IE=0X81; //开总中断和外中断0 IT0=1; //下降沿触发 P0=0x00; //初始化io口 P1=1; dis_buf[0]=dis_code[0]; //缓冲器初始化 dis_buf[1]=dis_code[0]; dis_buf[2]=dis_code[0]; dis_buf[3]=dis_code[0]; while(1) { P0=dis_buf[3]; P1=0x01; // 显示千位 delayms(5); P0=0xff;

P0=dis_buf[2]; // 显示百位 P1=0x02; delayms(5); P0=0xff; P0=dis_buf[1]; // 显示十位 P1=0x04; delayms(5); P0=0xff;

P0=dis_buf[0]; // 显示个位 P1=0x08; delayms(5); P0=0xff; } }

/*********************INT0中断处理函数*****************************/ void ex_int0()interrupt 0 { EX0=0; //关闭中断 int0_cnt++; //计数器加1

if(int0_cnt>9999) //判断 int0_cnt=0; dis_buf[3]=dis_code[int0_cnt/1000]; //分离出千位数 dis_buf[2]=dis_code[int0_cnt00/100]; //分离出百位数 dis_buf[1]=dis_code[int0_cnt0/10]; //分离出十位数 dis_buf[0]=dis_code[int0_cnt]; //分离出个位数 EX0=1; //开中断 }

/*********************延时函数*************************************/ void delayms(uint j) { uchar i; for(;j>0;j--) { i=250; while(--i); i=249; while(--i); }

}

[实验现象及结果]

通过一个按键来提供中断信号,但是由于按键有抖动现象,所以每按一次有可能产生多次计数脉冲,当有外部中断时(用按键K1模拟外部中断),计数器加1.

实验四

计数器实验

[实验目的]

1.掌握定时器,计数器的寄存器设置。 2.学会定时器中断函数的处理。

[实验内容]

MCU-AT89S52 P00~P07 P20~P23 P34-频率输入 8位共阳数码管 SA~SH C0~C3 [实验要求]

利用定时器和计数器组成一个测频电路。通过数码管显示。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。 3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int #define out P0 //IO端口定义

/*******共阳数码管 0 , 1 ,2 ,3 , 4 ,5 ,6 , 7, 8 ,9 ******/ uchar code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x01};

uint i = 0; //全局变量 uint cnt=0;

/***********主函数*******************************************************/ void main(void) { int j; TMOD=0x15; // 定时器0工作于计数方式,工作方式1,16位计数 // 定时器1工作于定时方式,工作方式1,16位定时 TH0=0; // 清零计数器 TL0=0; TH1=0x4C; // 12M晶振工作下,定时50ms TL1=0x00; TR0=1; // 启动定时器0 TR1=1; // 启动定时器1 IE=0x88; // 打开定时中断1和总中断 while(1) { P2=0x00; // 输出百位

out = seg[cnt/100]; P2 = 0x01; for(j=0;j<100;j++); P2=0x00; out = seg[cnt0/10]; // 输出十位 P2 = 0x02; for(j=0;j<100;j++); P2=0x00; out = seg[cnt]; // 输出个位 P2 = 0x04; for(j=0;j<100;j++); } }

/***********计数器T0中断处理函数******************************************/ void Timer1_ISR() interrupt 3 { static char j = 0; i++; TH1=0x4C; // 重设定时器值,50ms @ 12MHz XTAL TL1=0x00; if(++j == 20) // 50ms * 20 = 1S { j = 0; i = (TH0 << 8) | TL0; // 1S内的计数值 cnt=i; i=0; TH0 = 0; // 清零计数 TL0 = 0; } }

[实验现象及结果]]

对外部脉冲进行计数,并通过4位数码管显示计数值

实验五

RAM读写实验

[实验目的]

掌握RAM的读写方法;理解RAM和ROM的作用。

[实验要求]

MCU-AT89S52 P00~P07 P20 ~P21 8位共阳数码管 SA~SH C0~C1 [实验要求]

在DATA区定义一个字符变量并写入数据,把写入RAM中的数据读出来并用数码管显示出来。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。 3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int

uchar data dis_digit; //申明一个全局变量 /*********************共阳数码管编码表*****************************************/

uchar code dis_code[16]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};// 4, 5, 6, 7, 8, 9,a,b,c,d,e,f

uchar data dis_buf[2];//数据缓冲器

uchar data RW_Add; //在DATA区定义一个字符变量 void delayms(uchar ms); /*********************主函数***************************************************/ void main(void) {

uchar i; P0 = 0xff; //关闭段码 P2 = 0x00; //关闭位选 dis_buf[0] = 0xbf; // 显示\ dis_buf[1] = 0xbf; // 显示\ dis_digit = 0x01; while(1) { RW_Add=0x78; //写入的字节 dis_buf[0]=dis_code[(RW_Add&0xf0)>>4]; //写入5 dis_buf[1]=dis_code[RW_Add&0x0f]; //写入8 dis_digit=0x01; for(i=0;i<2;i++) { P0=dis_buf[i]; // 显示数据 P2=dis_digit; delayms(5); //延时 P0=0xff; dis_digit<<=1; //左移1位 } } }

/***************延时函*********************************************************/ void delayms(unsigned char ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } }

[实验现象及结果

向内存中写入数据0x58,然后读出,用两位数码管显示读出的值

验六

PWM发生器实验

[实验目的]

PWM波形产生原理;了解占空比的概念;熟悉定时器的使用和中断程序的编写。

[实验内容]

MCU-AT89S52 P00 USB示波器 示波器探头 [实验要求]

P00引脚输出不同占空比的PWM波形。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。 3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int

/**********引脚定义*****************************************************/

uchar PWM_T = 0; //占空比控制变量 sbit PWM_OUT=P0^0; //占空比输出脚

void main(void) {

bit flag = 1; //控制灯渐亮渐熄方式 uint n;

TMOD=0x02; //定时器0,工作模式2,8位定时模式

TH0=241; //写入预置初值241到定时器0,使15微秒溢出一次

(11.0592MHz)

TL0=241; //写入预置值 TR0=1; //启动定时器

ET0=1; //允许定时器0中断 EA=1; //允许总中断 PWM_OUT=1; //初始化P1

while(1) {

for(n=0;n<30000;n++); //延时,将响应定时器中断 if(flag==1) PWM_T++; else

PWM_T--;

if(PWM_T>=10) //设置级别为10 flag=0;

if(PWM_T==0) //限定最低级别为0 flag = 1; } }

/*********************定时器中断0**************************************/ timer0() interrupt 1 using 2 {

static uchar t ; //t用来保存当前时间在一秒中的比例位置 t++; //每15微秒增加1 if(t==10) //1.5毫秒的时钟周期 { t=0; //使t=0,开始新的PWM周期 PWM_OUT=0; //输出0 }

if(PWM_T==t) //按照当前占空比切换输出为高电平 PWM_OUT=1; //输出1 }

[实验现象及结果]

通过对P0^0脚占空比调整输出10个级别的调整波形,可通过示波器观察,或者是驱动LED,可以看到其亮暗变化

验七

PWM蜂鸣器实验

[实验目的]

掌握定时器的使用;掌握蜂鸣器的发声原理;熟悉PWM波形的产生。

[实验内容]

MCU-AT89S52 P00 蜂鸣器 BUZ [实验要求]

用定时器设计PWM波形驱动蜂鸣器发声.

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。 3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include //头文件 #include #include

#define uint unsigned int #define uchar unsigned char sbit BUZZER=P0^0;//发声音口 uchar code T0_H[16]={0xFF,0xFB,0xFB,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}; //定时器延时高位 uchar code T0_L[16]={0xF1,0x4,0x90,0xC,0x44,0xAC,0x9,0x34,0x82,0xC8,0x06,0x22,0x56,0x85,0x9A,0xC1}; //定时器延时低位 uchar code music[32]={8,0,8,9,8,0xB,0xA,0,8,0,8,9,8,0xC,0xB,0,8,0,8,0xF,0xD,0xB,0xA,9,0xE,0,0xE,0xD,0xB,0xC,0xB,0x0}; //音律选择

uchar code music_L[32]={2,1,1,4,4,4,4,4,2,1,1,4,4,4,4,4,2,1,1,4,4,4,4,4,2,1,1,4,4,4,4,4}; //延时长度 uchar a,b;

void delay_music(uint v) //延时 {

while(v!=0) v--; }

void delay_music1(uint j)//延时 { while(j!=0) { j--; delay_music(200); } }

void delay_music2(uint j)//延时 { while(j!=0) { j--; delay_music1(80); } }

/************************主函数****************************************/ void main() {//uint i; uchar k,n,m; delay_music(100); TMOD=0x11; //初始化定时器 TH1=0xfc; TL1=0x66; EA=1; //开中断 ET0=0; TR0=0; ET1=0; TR1=0; while(1) { ET1=1; //打开定时器 TR1=1; //启动计数 for(k=0;k<32;k++) //循环32次 { n=music[k]; m=music_L[k]; a=T0_H[n]; b=T0_L[n]; delay_music2(m);

} } }

/**********************定时计数器T1中断处理****************************/ time1 () interrupt 3 using 3 //定时器中断 { TH1=a; //初始化定时器计数器 TL1=b; BUZZER=!BUZZER; //蜂鸣器取反 }

[实验现象及结果]

蜂鸣器演奏歌曲

验八

外扩WDT看门狗实验

[实验目的]

理解硬件看门狗的作用,比较硬件看门狗同软件看门狗的差别。

[实验内容]

MCU-AT89S52 看门狗电路 P10 P11 P00~ P07 RST WDT /RESET 8位独立开关 SW1 8位独立LED D1~ D8 74LS04反相器 A1 Y1 注意:AT89S52是高电平复位,因此在使用外部看门狗电路的时候需要在看门狗电路引脚RESET后加反相器,经反相个后送到单片机的RST引脚完成复位操作。

[实验要求]

用外部看门狗实现对单片机的复位当不喂看门狗的时候,系统会自动复位使得流水灯不能运行当按时喂狗后,系统不会自动复位,流水等能在此次运行。

[实验步骤]

1、打开Uv4 IDE环境,选择菜单Project的下拉菜单Open Project选项, 加载后缀名为uvproj的工程文件。

2、选择菜单Project的下拉菜单Options for Target选项。在弹出的窗口中,选择output选项,在Creat HEX File的勾选项中,勾选。这样才能生成HEX文件。

3、选择菜单Project的下拉菜单Build target选项,如无错误或特别警告,编译链接完成后就会产生相应工程的HEX文件了。

[程序及注释]

#include #include

#define uchar unsigned char //数据类型宏定义 #define uint unsigned int /********引脚定

**************************************************************/ #define LED P0 sbit SW1=P1^0; sbit WDT=P1^1; /********延时函

**************************************************************/ void delayms(uchar ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } }

/*********主函

***************************************************************/ void main(void) { LED = 0xfe; //初始化LED WDT=1; _nop_(); //初始化看门狗 WDT=0; _nop_(); WDT=1; _nop_(); WDT=0; while(1) { if(SW1) //SW1=1时,喂狗 { WDT=1; _nop_(); WDT=0;

}

}

_nop_(); WDT=1; _nop_(); WDT=0; }

delayms(150); //延时 delayms(150);

LED = _crol_(LED,1);//循环右移1位,点亮下一个LED

[实验现象及结果]

1.当开关SW1置高时,程序清除硬件看门狗 LED流水灯正常运行

总结:通过这次单片机实验,让我真真正正见识了单片机,基本上可以说是大学以来第一次真正可以看到自己完成“电子产品”的实验课,非常的有意义。在单片机实验课上,不仅提高了每个同学的动手能力,我们需要自己自己思考电路,自己接线,再自己下载程序,我们还要自己编写程序,在不懂的时候可以参考历程来设计程序。同时锻炼了我们的逻辑思维能力,可以说是一举多得。在单片机实验课上,我们所使用的实验箱也是相对完成,几乎没有损坏的,这个也是其他实验课上难以遇到的。我们的单片机实验器材非常完善好用。总之,这次单片机实验让我们获益良多,为将来成为电子工程师打下了坚实的基础。