单片机课程报告.docx
《单片机课程报告.docx》由会员分享,可在线阅读,更多相关《单片机课程报告.docx(48页珍藏版)》请在冰豆网上搜索。
单片机课程报告
中南大学
微控制器技术实验报告
年级:
大三
学号:
*****
姓名:
***
专业班级:
自动化0706
指导老师:
****
二零一零年五月
第1章实验目的及要求
1、学习KeilC51集成开发工具的操作及调试程序的方法,包括:
仿真调试与脱机运行间的切换方法;
2、熟悉TD-51单片机系统板及实验系统的结构及使用;
3、进行MCS51单片机指令系统软件编程设计与硬件接口功能设计;
4、学习并掌握KeilC51与Proteus仿真软件联机进行单片机接口电路的设计与编程调试;
5、完成指定MCS51单片机综合设计题。
第2章实验内容
本实验分为软件与硬件两大部分,软件部分只需要尽心软件编程调试即可,硬件部分既可以利用实验室提供的设备器材进行联机调试,也可以应用虚拟软件若Proteus进行模拟仿真。
要求做实验前需进行充分的准备,软件部分先写好程序、硬件部分编号线路图,或者用虚拟软件运行成功后在到实验室利用单片机等设备进行在线调试运行。
第3章软、硬件环境
软件环境:
KEILuv3,PROTEUS7.4
硬件环境:
PC机,TD-51系统板
第4章软件编程设计实验
4.1实验内容
实验一 清零程序与拆字程序设计
根据实验指导书之“第二章单片机原理实验”(P17~P23页)内容,熟悉实验环境及方法,清零程序:
把7000H–7FFFH的内容清零。
实验二 拼字程序与数据传送程序设计
1、折字程序:
把7000H的内容拆开,高位送7001H低位,低位送7002H低位。
7001H,7002H高位清零。
2、拼字程序:
把7000H,7001H的低位相拼后送人7002H,一般本程序用于把显示缓冲区的数据取出拼装成个字节。
3、数据传输子程序:
把(R2,R3)源RAM区首址内的(R6,R7)个字节数据,传送到(R4,R5)目的RAM区。
实验三 排序程序与散转程序设计
1、编写并调试一个排序子程序,其功能为用冒泡法将内部RAM中几个单元字节无符号的正整数,按从小到大的次序重新排列。
2、编写散转程序,根据8032片内20H中的内容(00或01或02或03)进行散转。
4.2实验程序流程图及算法
1、
清零程序清单:
ORG0000H
START:
MOVR0,#00H
MOVR1,#10H;循环次数
MOVDPTR,#7000H
D0:
MOVA,#00H
MOVX@DPTR,A;清零
INCDPTR;地址加一
INCR0
CJNER0,#00H,D0
DJNZR1,D0
END
图4-1清零程序流程图
为了验证程序的结果,可以将清零先改成置一,这样就可以看这个程序是否正确。
2.折字程序:
拆字流程图如图二所示:
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVDPTR,#7000H
MOVA,#33H;7000H中送33H
MOVX@DPTR,A
MOVXA,@DPTR
SWAPAANLA,#0FH;屏蔽高四位
MOVDPTR,#7001H
MOVX@DPTR,A;送7000H高位至7001H
MOVA,#01H
MOVDPTR,#7000H图4-2拆字程序流程图
MOVXA,@DPTR
ANLA,#0FH
MOVDPTR,#7002H;送7000H低位至7002H
MOVX@DPTR,A
END
3.拼字程序:
拆字程序流程图见右图4-3。
程序清单:
ORG0000H
LJMPMAIN
ORG0100H
MOVDPTR,#7000H
MOVA,#05H
MOVX@DPTR,A
MOVXA,@DPTR
ANLA,#0FH
SWAPA
MOVR0,A
MOVDPTR,#7001H
MOVA,#01H
MOVX@DPTR,A
MOVXA,@DPTR
ANLA,#0FH图4-3拼字程序流程图
ORLA,R0
MOVDPTR,#7002H
MOVX@DPTR,A
END
4.数据传输子程序
程序流程图见图4-4。
图4-4数据传输指令图4-5散转指令流程图
传输指令清单:
;(R2,R3)->(R4,R5)
;(R6,R7)个字节
;(R0,R1)作为计数值,与6、7相等时,传送完毕
ORG0000H
AJMPMAIN
MAIN:
MOVR2,#1;设置各初始值
MOVR3,#2
MOVR4,#1
MOVR5,#2AH
MOVR6,#0
MOVR7,#6
MOVR0,#00H
MOVR1,#0;R0R1计数初值
CJNER6,#0,S
CJNER7,#0,S
LJMPE
S:
MOVDPH,R2;源地址数据给A
MOVDPL,R3
MOVXA,@DPTR
INCDPTR
MOVR2,DPH
MOVR3,DPL
MOVDPH,R4;A给目的地址
MOVDPL,R5
MOVX@DPTR,A
INCDPTR
MOVR4,DPH
MOVR5,DPL
MOVDPH,R0;计数值R0R1+1
MOVDPL,R1
INCDPTR
MOVR0,DPH
MOVR1,DPL
MOVA,R1;R1异或R7,若A=0,R1=R7
XRLA,R7
JNZS
MOVA,R0
XRLA,R6;若R1=r7且R0=R6,传送完毕
JNZS
E:
END
5.散装程序流程图见图4-5。
程序清单
ORG0000H
LJMPMAIN
ORG0100H
MAIN:
MOVA,20H
RLA
ADDA,20H
MOVDPTR,#TABLE
JMP@A+DPTR
TABLE:
LJMPPM0;散转入口
LJMPPM1
LJMPPM2
LJMPPM3
PM0:
MOVR0,#00H;子程序0
MOVR3,#10H
MOVR1,#30H
L1:
MOVA,R0
MOV@R1,A
INCR0
INCR1
DJNZR3,L1
LJMPEXIT
PM1:
MOVDPTR,#7000H;子程序1
MOVA,#33H
MOVX@DPTR,A
MOVXA,@DPTR
INCDPTR
MOVR0,A
ANLA,#0FH
MOVX@DPTR,A
MOVA,R0
SWAPA
ANLA,#0FH
INCDPTR
MOVX@DPTR,A
LJMPEXIT
PM2:
MOV11H,#0FH;子程序2
AJMPEXIT
PM3:
MOV12H,#0FEH;子程序3
AJMPEXIT
EXIT:
NOP
END
6.冒泡程序
流程图件图4-6
程序清单:
;冒泡法排序;(R0)为数据开始地址指针(R1)为数据块字节数;实现从小到大排序
ORG0000H
LJMPMAIN
MAIN:
MOVR0,#50H
MOVR1,#5H
LCALLMAPE
END
MAPE:
DECR1
MOVR4,R0
CLRPSW.5;清冒泡标志
MAP10:
MOVR3,R1
MOVR0,R4;数据块起始地址指针
MAOP11:
MOVR2,@R0;取前数
INCR0
MOVA,@R0;取后数
CLRC
SUBBA,R2
JCMAP12;前数小于后数,不变
SETBPSW.5;置冒泡标志
MOVA,@R0
INCR0
MOV@R0,A
INCR0
MOV@R0,R2
MAOP12:
DJNZR3,MAOP11
JBCPSW.5,MAOP10
MAPE:
RET
图4-6冒泡法排序
4.2实验调试步骤
1.输入程序,检查无误后,编译、链接程序,首先给系统复位,然后点击
命令进入调试状态。
2、点击
命令复位,点击
命令运行整个程序,观察存储器窗口的结果。
、
3、另外在程序出错时可点击
命令单步运行程序,观察每一步运行情况,找出错误之处。
4.3实验结果及分析
清零、拆字、拼字实验均满足要求,其中清零实验为了验证结果正确性,可以将清零改成置一。
运用汇编编写程序后,可以参考实验指导书进行c语言编程,强化理解c语言。
散装程序,用途及广,可以实现多个目标的跳转,具有散装功能。
冒泡排序一般有两种方法,一个是规定排序次数,进行内外两次循环,也可在外循环设置标志位,只有当内循环需要转换数据时,才进行外循环,否则程序结束。
明显,带有标志位的冒泡法排序相对来说时间复杂度要小,本实验即采用第二种冒泡法排序。
典型的排序程序还有快速法,查找法等,这里没有进行编写。
第5章硬件程序设计实验
5.1静态存储器扩展实验
1、实验要求及内容:
编写实验程序,在单片机内部一段连续RAM空间30H~3FH中写入初值00H~0FH,然后将这16个数传送到RAM的0000H~000FH中,最后再将外部RAM的0000H~000FH空间的内容传送到片内RAM的40H~4FH单元中。
为了更好的看到实验效果,添加一显示灯泡,用以表征数据是否正确传输。
如果有有传送错误,则令指示灯闪烁
2、实验程序设计及硬件实现
①:
画程序流程图,如5-1
图5-1SRAM程序流程图
②:
根据流程图编写汇编语言程序。
程序如下:
ORG0000H
AJMPMAIN
MAIN:
MOVP3.5,#1;P3.5外接指示灯指示运行状态(长亮则运行正常,闪烁则出错)
MOVR0,#30H;将00H-0FH写入RAM内30H-3FH
MOVA,#00H
MOVR1,#10H
L1:
MOV@R0,A
INCR0
INCDPTR
INCR0
DJNZR1,L2
MOVR1,#10H;写入内部RAM中
MOVDPTR,#0000H
MOVR0,#40H
L3:
MOVXA,@DPTR
MOV@R0,A
INCDPTR
INCR0
DJNZR1,L3
ER:
MOVP3.5,#0;P3.5闪烁子程序
INCA
DJNZR1,L1
MOVR1,#10H;写入外部RAM中
MOVDPTR,#0000H
MOVR0,#30H
L2:
MOVA,@R0
MOVX@DPTR,A
MOVXA,@DPTR
CJNEA,@R0,L4
L4:
LCALLER;传送出错,调用闪烁子程序
LCALLDELAY
MOVP3.5,#1
LCALLDELAY
JMPER
RET
;延时子程序
DELAY:
MOVR6,#50HD2:
MOVR7,#0FFH
D1:
DJNZR7,D1
DJNZR6,D2
RET
END
③:
判断程序正误。
输入程序,检查无误后,编译、链接程序,先在KeilC中模拟运行,直至正确为止。
④:
按照图5-1进行接线,联机调试运行程序。
图5-1扩展存储器实验线路图
⑤:
脱机运行程序,学习并掌握脱机联机模式之间的切换方法。
5.2数字量输入输出实验
5.2.1实时输入输出
1、实验内容
P1口是8位准双向口,每一位均可独立定义为输入输出。
编写实验程序,将P1口的低4位定义为输出,高4位定义为输入,数字量从P1口的高4位输入,从P1口的低4位输出控制发光二极管的亮灭。
2、实验程序设计及硬件实现
P1口是准双向口,在其作为输入口使用时,首先要写先写入高电平,然后再读P1口数据才是准确的。
所以,程序的开始就应该说明P1口的高4为为输入,也就是将高4位写“1”,指令为:
MOVP1,#0F0H
程序清单:
ORG0000H
AJMPMAIN
MAIN:
MOVP1,#0F0H;定义高4位为输入
MOVA,P1
ANLA,#0F0H
SWAPA
MOVP1,A
AJMPE
E:
SJMP$
END
图5-2基本输入输出程序流程图
此程序的关键点在于:
P1口是准双向口,在其作为输入口使用时,首先要写“1”,然后再读P1口数据才是准确的。
所以,程序的开始就应该说明P1口的高4为为输入,也就是将高4位写“1”,指令为:
MOVP1,#0F0H
硬件接线及运行后状态:
图5-3基本输入输出电路图及Proteus仿真结果
5.2.2方波发生器
1、实验内容:
单片机集成的定时器可以产生定时中断,利用定时器0和定时器1,编写实验程序在P1.0及P1.1引脚上输出方波信号,通过示波器观察实验现象并测量波形周期。
2、实验程序设计及硬件实现
程序清单:
MOVTMOD,#10H;定时器1工作方式1
MOVTH1,#0FFH;设置计数初值
MOVTL1,#83H
SETBEA;开中断
SETBET1;定时器1允许中断
SETBTR1;定时开始
SJMP$;等待中断
中断服务程序:
MOVTH1,#0FFH;重新设置计数初值
MOVTL1,#83H
CPLP1.0;输出取反
RETI;中断返回
按照实验指导书上硬件接线图进行接线,联机进行调试分析。
5.2.3键盘扫描与数码管显示设计
1、实验内容:
使用汇编语言编程,实现如下功能:
在4*4小键盘上按键输入,并将其内容显示在LCD上。
2、实验程序设计及硬件实现
①原理阐述
矩阵键盘的运行原理:
键盘的列线接电阻后接+5V的电源,另一端接单片机的P3.0~P3.3口,行线接在单片机的P3.4~P3.7口上。
键盘采用扫描的方式,程序开始运行时,检测的方法是单片机的P3.4~P3.7口输出全“0”,读取P3.4~P3.7口的状态,若P3.4~P3.7口有高电平,则有键按下,否则没有键按下。
若有键按下,通过延时去抖。
去除键抖动后,当检测到有键按下后,延时一段时间在做下一步的检测判断。
若有键按下,通过程序判断是哪个按键按下并通过程序判断此键所代表的具体数值(在程序中将每个按键赋予一个固定的值,从0到F),然后查表后的键值送到数码管显示。
LCD液晶显式原理:
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图。
程序开始时,对液晶进行了初始化设置,约定了显示格式。
由于液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志位,即读忙信号和光标地址BF为低电平,表示不忙,否则此指令失效。
要显示字符时,程序先输入显示字符地址,也就是告诉模块在哪里显示字符,液晶就可以正常显示。
②方案讨论
独立式键盘由一组相互独立的按键组成。
这些按键直接与单片机的I/O口相连,即每个按键盘独占一个I/O口,接口简单。
这里采用查询方法,利用判断指令实现键盘功能。
矩阵键盘输入:
矩阵键盘是4*4的16位键盘,键盘的行线和列线分别接单片机的P3.0~P3.3和P3,4~P3.7口上,键盘采用键盘扫描的工作方式。
LCD显示输出:
将LCD的输入端D0到D7接在单片机的P1端口,数据通过P2口送入LCD,LCD内部有数据译码器,能将数据转换为电压变化,并显示。
RS端接P2.1,RW接P2.0,E接P2.2,VSS与滑动变阻器一端接地,VDD与滑动变阻器另一端接+5V,VEE接划动端,通过滑动变阻器改变LCD的显示亮度,使之能正常显示。
硬件接线参考图5-5,图为Proteus运行结果。
图5-44*4键盘扫描输入及显示功能Proteus仿真结果图
③部分程序流程框图。
图5-5LCD显示子程序
图5-64*4矩阵键盘流程图
④程序清单:
程序中设置编有头文件LCD1602.h、input.h、hardware.h,函数文件有:
LCD1602.c、input.c、SHIYAN.c。
SHIYAN.c为最终所需文件。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
/*--hardwar.h文件硬件抽取层---*/
#ifndef__HARDWAR_H__
#define__HARDWAR_H__
#include
/*--LCD数据、控制口定义-----*/
#defineLCD_DATAP1//LCD的数据口
sbitLCD_BUSY=LCD_DATA^7;//LCD忙信号位
sbitLCD_RW=P2^0;//LCD读写控制
sbitLCD_RS=P2^1;//LCD寄存器选择
sbitLCD_EN=P2^2;//LCD使能信号*/
/*----I2C-EEROM接口定义------------*/
SbitSDA=P2^4;//I2C总线数据
SbitSCL=P2^3;//I2C总线时钟
/*------DS1302接口定义-----*/
sbitreset=P2^7;
sbitsclk=P2^6;
sbitio=P2^5;
externvoid_nop_(void);
#endif
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
/***********键盘输入头文件程序********/
//*.hfile
#ifndef__SHURU_H__
#define__SHURU_H__
bitpkey();//判断有没有键按下
unsignedcharkbscan(void);//键盘扫描
voidinput(void);//号码输入
voiddelay(void);//消抖动
externunsignedcharkey;
#endif
/*-------------------------------------------------LCD1602.H文件LCD1602的一些命令定义--------------------------------------------------*/
#ifndef__LCD_H__
#define__LCD_H__
#defineLCD_GO_HOME0x02//AC=0,光标、画面回HOME位
//输入方式设置
#defineLCD_AC_AUTO_INCREMENT0x06//数据读、写操作后,AC自动增一
#defineLCD_AC_AUTO_DECREASE0x04//数据读、写操作后,AC自动减一
#defineLCD_MOVE_ENABLE0x05//数据读、写操作,画面平移
#defineLCD_MOVE_DISENABLE0x04//数据读、写操作,画面不动
//设置显示、光标及闪烁开、关
#defineLCD_DISPLAY_ON0x0C//显示开
#defineLCD_DISPLAY_OFF0x08//显示关
#defineLCD_CURSOR_ON0x0A//光标显示
#defineLCD_CURSOR_OFF0x08//光标不显示
#defineLCD_CURSOR_BLINK_ON0x09//光标闪烁
#defineLCD_CURSOR_BLINK_OFF0x08//光标不闪烁
//光标、画面移动,不影响DDRAM
#defineLCD_LEFT_MOVE0x18//LCD显示左移一位
#defineLCD_RIGHT_MOVE0x1C//LCD显示右移一位
#defineLCD_CURSOR_LEFT_MOVE0x10//光标左移一位
#defineLCD_CURSOR_RIGHT_MOVE0x14//光标右移一位
//工作方式设置
#defineLCD_DISPLAY_DOUBLE_LINE0x38//两行显示
#defineLCD_DISPLAY_SINGLE_LINE0x30//单行显示
voidLCD_cls(void);
voidLCD_write_data(unsignedchar);
voidLCD_initial(void);
voidLCD_set_position(unsignedchar);
voidLCD_prints(unsignedchar*);
voidLCD_printc(unsignedchar);
#endif
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
/*-------主文件设置-----------------*/
#include"reg51.h"
#include"LCD1602.h"
#include"hardware.h"
charcodetab[4][4]={{'1','4','7','#'},{'2','5','8','0'},
{'3','6','9','*'},{'A','B','C','D'}};//0到F的16个键植
voiddelay(unsignedchara)
{
unsignedchari;
while(a--)
for(i=100;i>0;i--)
;
}
charkbscan()//键盘扫描
{
unsignedcharhang,lie,key;
if(P3!
=0x0f)
delay(5);
if(P3!
=0x0f)
{
switch(P3&0x0f)
{
case0x0e:
lie=0;break;
case0x0d:
lie=1;break;
case0x0b:
lie=2;break;
case7:
lie=3;break;
}
P3=0xf0;
P3=0xf0;
switch(P3&0xf0)
{
case0xe0:
hang=0;break;
case0xd0:
hang=1;break;
case0xb0:
hang=2;break;
case0x70:
hang=3;break;
}
P3=0x0f;
while(P3!
=0x0f);
key=tab[hang