单片微型计算机原理及应用 实验报告
学院名称 专业名称 学生姓名
学生学号 任课教师
实验报告成绩
教务处 制 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
#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
#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
#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
#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
#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
#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
#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
#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流水灯正常运行
总结:通过这次单片机实验,让我真真正正见识了单片机,基本上可以说是大学以来第一次真正可以看到自己完成“电子产品”的实验课,非常的有意义。在单片机实验课上,不仅提高了每个同学的动手能力,我们需要自己自己思考电路,自己接线,再自己下载程序,我们还要自己编写程序,在不懂的时候可以参考历程来设计程序。同时锻炼了我们的逻辑思维能力,可以说是一举多得。在单片机实验课上,我们所使用的实验箱也是相对完成,几乎没有损坏的,这个也是其他实验课上难以遇到的。我们的单片机实验器材非常完善好用。总之,这次单片机实验让我们获益良多,为将来成为电子工程师打下了坚实的基础。