第一篇:DXP 2004 第九章单片机综合实验板的制作
目录
一、新建工程...................................................................................................................................2
二、建立集成元件库.......................................................................................................................3
三、设计电路原理图.......................................................................................................................9
四、ERC检查.................................................................................................................................13
五、原理图报表.............................................................................................................................13
六、规划电路板.............................................................................................................................14
七、导入网络表和元件封装.........................................................................................................17
八、手工布局.................................................................................................................................17
九、设置网络类.............................................................................................................................18
十、设置布线规则.........................................................................................................................19
十一、自动布线、手动调整.........................................................................................................21
十二、DRC设计规划检查.............................................................................................................22
十三、3D效果图...........................................................................................................................23
十四、心得体会.............................................................................................................................24
一、新建工程
点击【File】→【New】→【Project】→【PCB Project】,由此创建一个新的PCB项目,执行菜单命令【File】→【Save Project】将项目更名为“单片机基础综合实验板.PrjPCB”并保存在指定文件夹下。
图1 创建项目
图2 保存项目
图3 放置文件
二、建立集成元件库
(1)建立集成元件库项目
1)在Protel DXP 2004 设计系统的主界面上执行菜单命令【File】→【New】→【Project】→【Integrated Library】,由此创建一个新的集成元件库项目。
图4 创建集成元件库项目 2)在该集成元件库项目下添加一个新的元件原理图文件和一个新的PCB元件封装库文件。在该集成项目上单击鼠标右键选择【Add New to Project】→【Schematic Library】【/PCB Library】,并保存,完成的工作面板如图6所示。
图5 创建元件库和封装文件
图6 【Project】工作面板
(2)制作原理图元件STC12C5A60S2、HD7279、LG5641AH、PL2303、DS18B20和USB口。1)单击【Project】工作面板中的“单片机基础综合实验板.SchLib”,切换到元件原理图库编辑界面下,系统将自动弹出【SCH Library】工作面板,并且存在一个一个默认名为”COMPONENT_1“的元件。
图7 元件原理图库工作界面
2)双击默认元件,对其属性进行编辑,编辑界面如图8。
图8 编辑COMPONENT_1属性
3)单击【SCH Library】工作面板上的Add键,可以添加一个新的自定义元件,如图9。
图9 自定义元件的添加
4)绘制所需元件。
(a)元件STC12C5A60S2
(b)元件HD7279
(c)元件LG5641AH
(d)元件DS18B20(e)元件PL2303
(f)USB接口
图10 绘制的元件
(3)制作元件封装
为6个自定义元件中STC12C5A60S2、LG5641AH两个器件需要绘制相应的元件封装。1)单击【Project】工作面板中的”单片机基础综合实验板.PcbLib”,切换到PCB元件封装库编辑器界面下,系统将自动弹出【PCB Library】工作面板,并且存在一个一个默认名为”PCBCOMPONENT_1“的元件,如图11。
图11 【PCB Library】工作面板
2)在PCB工作面板的空白区域单击鼠标右键,选择[New Blank Component]选项,再建一个元件封装如图12,然后对两个元件封装进行编辑。
图12 再建一个元件封装
3)完成后的STC12C5A60S2元件封装PLCC44zuo如图13所示。4)完成后的LG5641AH元件封装LEDDIP-12如图14所示。
图13元件封装STC12C5A60S2 图14元件封装LG5641AH(4)在元件库中找封装
1)双击所需编辑元件,点击Add添加元件封装,如图15所示。
图15 2)点击【Browse】,弹出的表格中默认的是自己制作的封装,如果想要其他封装,可以点击【find】在库中寻找自己所需的封装。
图16
三、设计电路原理图
为了本实验的PCB板的制作的方便,我将所有元器件全部集中在一张原理图中,下面我将把整张电路图分成10个小的电路图分别展示,最后将整张电路图展示。
(1)由于将所有部分集中在一张图纸中,所以在绘制原理图开始前,我们需要对我们原本的图纸进行设置,将其换成A3大小。
在系统主界面上执行【Design】→【Document Options】,更改图纸属性。
图17 选择【Document Options】
图18编辑图纸属性(2)根据所给电路绘制原理图
1)完成后的MCU电路如图19所示。
图19 MCU电路原理图
2)完成后的时钟电路如图20所示。
图20时钟电路原理图
3)完成后的电源接口和复位电路如图21所示。
图21电源接口和复位电路原理图 4)完成后的外扩RAM电路如图22所示。
图22外扩RAM电路原理图
5)完成后的DAC电路如图23所示。
图23 DAC电路原理图
6)完成后的232电路如图24所示。
图24 232电路原理图
7)完成后的温度传感器电路如图25所示。
图25温度传感器电路原理图 8)完成后的流水灯电路如图26所示。
图26流水灯电路电路原理图
9)完成后的键盘数码显示电路如图27所示。
图27键盘数码显示电路电路图
10)完成后的USB电路如图28所示。
图28 USB电路原理图(3)将这10个部分全部整理在一张原理图,并根据实际情况布局。
图29单片机基础综合实验板原理图
四、ERC检查
执行菜单命令【Project】→【Compile PCB Project】进行电气规格检查如图28所示,如果有错误将会弹出一个【Message】的对话框,此时需要根据系统所提示的信息进行修改,直到符合设计要求为止。
图30电气规格检查
五、原理图报表
完成原理图的设计操作后,还要根据设计的需要输出元件报表已经网络表等文件。1)执行菜单命令【Report】→【Bill of Materials】,生成元件报表,单击【Report】按钮保存该元件报表。
2)选择菜单命令【Design】→【Netlist For Project】→【Protel】,系统将在该工程项目下生成一个与该工程文件同名的网络表文件。
图31生成网络报表
六、规划电路板
1)点击软件左下角Files界面,选择PCB板向导。
图32 2)设置PCB板的大小
图33 3)将电源层设置为0。
图34 4)将PCB板设置成过孔式单轨道。
图35 5)点击向导完成PCB板的设置
图36利用向导制作的PCB图
七、导入网络表和元件封装
1)执行命令【Design】→【Import Changes From…】后,会弹出如图37所示的【Engineering Change Order】对话框。
图37【Engineering Change Order】对话框
2)在该对话框中单击
功能按钮检查原理图中的网络和元件封装是否正确。
功能按钮就可以将网络和元件封装加3)如果2)检查没有错误,那么单击载到PCB文件中,从而实现了从原理图向PCB的更新。4)单击按钮关闭【Engineering Change Order】对话框,这时网络和元件封装已经加载到PCB文件中了,如图38所示。
图38 导入网络表和元件封装
八、手工布局
按照之前布置的原理图模块对加载到PCB的元件进行布局,如图39所示。
图39 对PCB板进行手工布局
九、设置网络类
为了在自动布线的时候对同一个网络类中的所以对象一起操作,因此在布线之前可以对板子上的所有网络进行分类。
1)打开对象类对话框。在PCB编辑器的主菜单上执行菜单命令【Design】→【Classes】,即可进入对象类对话框,如图40所示。
图40生成网络类选项
2)建立一个新的网络类,并更名为”power”,如图40所示。3)向新建的网络类添加成员。
图41设置后的网络类列表
4)关闭对话框,完成设置。
十、设置布线规则
(1)【Electrial】规则的设置
选择【Electrial】规则下的【Clearance】规则,将【Constraints】中的【Minimum Clearance】设置为10mil。
图42安全间距设置
(2)【Routing】规则的设置
首先添加一个新的【Width】规则。在【Width】规则上单击鼠标右键,从弹出的快捷菜单中选择【New Rule】,并更名为“power”。
修改线宽和优先顺序。
图43导线宽度设置
图44【Width】规则中优先顺序设置
(3)【Manufacturing】规则的设置
由于232电路中元件封装过大,超过系统默认,因此有必要对【Manufacturing】规则下【HoleSize】更改允许孔径的范围。
图45孔尺寸的设置
十一、自动布线、手动调整
执行菜单命令【Auto Route】→【All】,系统将弹出自动布线器对话框,单击按钮,设置布线方向。
图46布线策略的选择
图47编辑方向对话框
图48 PCB布线图
十二、DRC设计规划检查
完成PCB的布线操作后,通常需要对PCB进行设计规则检查(DRC)执行菜单命令【Tools】→【Design Rule Check…】
图49DRC报告
十三、3D效果图
执行PCB编辑器中【View】→【Board in 3D】命令,查看该PCB的效果图,结果如图50。
图50 PCB的3D效果图
十四、心得体会
通过本周对Protel DXP的学习,让我学会了一些基本电路图绘制和PCB的制作。刚接触Protel DXP软件时,对其操作什么都不会,但在老师的讲解和操作指导下,以及自己的努力下。慢慢会做了,开始会建原理图文件和PCB文件,但都不会查找元件和绘制元件。
刚开始做Protel DXP时,最难的是对元件的查找和对元件库的管理和添加,还有PCB封装的绘制。的确对于不懂 Protel DXP的我们,实在很难找到成功的感觉,往往错误百出,到处都存在问题,每一个详细的步骤都要认真记下,不然后期都不会操作。
随着对Protel DXP的了解,我也慢慢地开始有感觉会做了。开始学习原理图元件的绘制了,在做原理图绘制之前要打开原理图绘制界面,在绘制原理图元件时要注意元件一般的尺寸大小适中,还有元件管脚电气属性的设置和消箭头的一些简单的方法。原理图的绘制完成后便是修改文件名称和添加元件库了。只要对这些基本方法都掌握后,就可以绘制一些基本的原理图了,绘制图形时一定要注意元件的摆放,以及原理图要求美观,清晰等等。
PCB的封装,是做Protel DXP很难的一步,制作图时都要以元器件实物的型号和大小为依据,实物元件的种类繁多,以种类的不同大小又不一,所以要以对待不同的PCB封装是不一样的。PBC封装尺寸的大小主要在管脚的距离上,管脚距离的大小决定了实物元件能否安装,要从原理图生成PCB就要保证每个元件都有对应的封装,不仅大小要对应符号也要对应。在这些步骤都完成后就可以从原理图生成PCB了,在从原理图生成PCB时要保证每个元件都是正确的,确保每个元件都被导入。
PCB生成后最主要的工作就是对元件的布局和布线了,PCB元件的布局的要求是功能元件要尽量在一起,主要功能集成块要放在电路板中央,重元件要有支架,开关和发热元件靠边放,高频部分布线要尽量短,最后元件摆放要整齐、美观。元件布局好后就是布线了,布线可以是单层,双层和多层的。布线后尽量不要存在飞线,布局好后就是布线了,布线可以是单层,双层和多层的。布线后尽量不要存在飞线,若布线存在极少飞线,依实际情况可不从新布线而手动布线。布线完后添加泪滴和敷铜,PCB就制作完成了,可以进行3D仿真观察。
Protel 的学习注重实际练习,练习多了便有了经验,经验积累多了便有了感觉,有了感觉便学会了Protel,所以在以后的学习中我定会从实际出发,加强练习。
第二篇:万年历单片机综合实验
综合实验报告
实验题目: 万年历
学生班级: 学生姓名: 学生学号: 指导教师: 实验时间:
摘要
本设计是电子万年历。具备三个功能:能显示:年、月、日、时、分、秒及星期信息,并具有可调整日期和时间功能。
我选用的是单片机STC89C52来实现电子万年历的功能。该电子万年历能够成功实现时钟运行,调整,显示年月日时分秒等信息。
该电子万年历使用12MHZ晶振与单片机STC89C52相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性,从而使得其成本降低,更适合我们大学生自主研发。所以在该设计与制作中我选用了单片机STC89C52,它是低功耗、高性能的CMOS型8位单片机。片内带有4KB的Flash存储器,且允许在系统内改写或用编程器编程。另外, 单片机STC89C52的指令系统和引脚与8051完全兼容,片内有128B 的RAM、32条I/O口线、2个16位定时计数器、5个中断源、一个全双工串行口等。
因此,采用单片机STC89C52原理制作的电子万年历,不仅仅在原理上能够成功实现计时等功能,也更经济,更适用,更符合我们实际生活的需要,对我们大学生来说也更加有用。
关键词:STC89S52,DS1302,LCD,PROTEUS
目录
一、实验要求:...............................................................................................................................3
1.1基本要求:.........................................................................................................................3 1.2拓展要求:.........................................................................................................................3
二、方案论证:...............................................................................................................................3
2.1.显示部分:...........................................................................................................................3 2.2.数字时钟:.........................................................................................................................3
三、总体方案:...............................................................................................................................4
四、系统硬件设计:.......................................................................................................................4
4.1.时间设置模块:...............................................................................................................4 4.2.时钟模块:...........................................................................................................................4 4.3.整点报时电路.....................................................................................................................5 4.4.LCD液晶显示模块:.......................................................................................................5
五、整体电路:...............................................................................................................................6
5.1.电路.....................................................................................................................................6
六、数字时钟使用说明:...............................................................................................................7
七、心得体会:...............................................................................................................................7
八、程序代码:...............................................................................................................................7
一、实验要求:
1.1基本要求:
1、能动态显示年、月、日、星期、小时、分钟、秒。
2、可用键盘进行日期时间的修改。1.2拓展要求:
3、具有闹钟功能:可设定闹钟时间,在时间到达后,发出报警时间,持续5秒。
二、方案论证:
2.1.显示部分: 显示部分是本次设计的重要部分,一般有以下两种方案: 方案一:
采用LED显示,分静态显示和动态显示。对于静态显示方式,所需的译码驱动装置很多,引线多而复杂,且可靠性也较低。而对于动态显示方式,虽可以避免静态显示的问题,但设计上如果处理不当,易造成亮度低,有闪烁等问题。方案二:
采用LCD显示。LCD液晶显示具有丰富多样性、灵活性、电路简单、易于控制而且功耗小等优点,对于信息量多的系统,是比较适合的。
鉴于上述原因,我们采用方案二。2.2.数字时钟:
数字时钟是本设计的核心的部分。根据需要可采用以下两种方案实现: 方案一:
方案完全用软件实现数字时钟。原理为:在单片机内部存储器设三个字节分别存放时钟的时、分、秒信息。利用定时器与软件结合实现1秒定时中断,每产生一次中断,存储器内相应的秒值加1;若秒值达到60,则将其清零,并将相应的分字节值加1;若分值达到60,则清零分字节,并将时字节值加1;若时值达到24,则将时字节清零。该方案具有硬件电路简单的特点,但当单片机不上电,程序将不执行。而且由于每次执行程序时,定时器都要重新赋初值,所以该时钟精度不高。
方案二:
方案采用Dallas公司的专用时钟芯片DS1302。该芯片内部采用石英晶体振荡器,其芯片精度不大于10ms/年,且具有完备的时钟闹钟功能,因此,可直接对其以用于显示或设置,使得软件编程相对简单。为保证时钟在电网电压不足或突然掉电等突发情况下仍能正常工作,芯片内部包含锂电池。当电网电压不足或突然掉电时,可使系统自动转换到内部锂电池供电系统。而且即使系统不上电,程序不执行时,锂电池也能保证芯片的正常运行,以备随 时提供正确的时间。
基于时钟芯片的上述优点,本设计采用方案二完成数字时钟的功能。
三、总体方案:
本设计采用STC89C52RC单片机作为本系统的控制模块。单片机可把由DS1302、LCD液晶显示模块中的数据利用软件来进行处理,从而把数据传输到显示模块,实现日历和修改的显示。以LCD液晶显示器为显示模块,把单片机传来的数据显示出来,并且显示多样化。在显示电路中,主要靠按键来实现日期的修改和选择。
四、系统硬件设计:
4.1.时间设置模块:
时间设置模块通过四个按键实现万年历的时间调整设置。KEY1键进入时间设置模式,KEY2键实现设置内容选择,KEY3键实现设置内容加1,KEY4键实现设置内容减1。
图1.时间设置模块
4.2.时钟模块: 时钟模块采用DS1302芯片,DS1302是DALLAS公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作可通过 4 AM/PM指示决定采用24或12小时格式DS1302与单片机之间能简单地采用同步串行的方式进行通信仅需用到三个口线:
RST复位、I/O数据线、SCLK串行时钟。时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW,其接线电路如图2所示:
图2.时钟模块
4.3.整点报时电路
整点报时电路由一个NPN三极管和蜂鸣器组成,当时间走到整点时分,会每间隔一秒发出一次报时,连响五次。
图3.报时电路
4.4.LCD液晶显示模块: LCD液晶显示模块采用LCD1602型号,具有很低的功耗,正常工作时电流仅2.0mA/5.0V。通过编程实现自动关闭屏幕能够更有效的降低功耗。LCD1602分两行显示,每行可显示多达16个字符。LCD1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,通过内部指令可实现对其显示多样的控制,并且还能利用空余的空间自定义字符。其接线如图4所示:
图4.LCD液晶显示
五、整体电路:
5.1.电路
图5.整体电路
六、数字时钟使用说明:
调整时间设定:在时间显示界面中按KEY1键后,进入时间调整,通过KEY2选择需要修改的或设定的时间。按KEY2键对应内容向右移动,KEY3键加1,KEY4键减1,设置完毕,自动退出设置功能。
七、心得体会:
通过这一周的课程设计,加深了我对于单片机和数字电路的认识,通过查阅大量的资料,我获得了以前在课堂上学不到的东西,我想这对于以后的毕业设计,或者工作也好,都是很有帮助的。在设计电路中,往往是先仿真后连接实物图,但有时候仿真和电路连接并不是完全一致的,例如仿真的连接示意图中,往往没有接高电平的16脚或14脚以及接低电平的7脚或8脚,因此在实际的电路连接中往往容易遗漏。在设计的过程中遇到了很多问题,本来自己的单片机基础就比较弱,又是第一次做这样的设计,难免会遇到过各种各样的问题。同时在设计的过程中发现了自己的不足之处,比如对以前所学过的知识理解得不够深刻,掌握得不够牢固,对单片机汇编语言掌握得不好。此次的电子万年历设计重在于仿真和接线,虽然能把电路图接出来,并能正常显示,但对于电路本身的原理并不是十分熟悉.总的来说,通过这次的设计实验更进一步地增强了实验的动手能力。
八、程序代码:
#include “reg51.h” #include “intrins.h” typedef unsigned char uint8;typedef unsigned int uint16;
#define LED_Y P2 #define LCD_DATA 1 #define LCD_COMMAND 0 #define WORDNUU 11
sbit ALARM=P2^0;sbit LCD_RS=P1^5;sbit LCD_RW=P1^6;sbit LCD_EN=P1^7;sbit RTC_SDA=P3^6;sbit RTC_SCL=P3^5;sbit RTC_RST=P3^4;sbit KEY1=P1^0;sbit KEY2=P1^1;sbit KEY3=P1^2;sbit KEY4=P1^3;
#define LCD_PORT P0 uint8 LCD_NO;uint16 i1,i2;uint8 bdata AA;sbit AA7 = AA^7;#define READ_SECOND #define WRITE_SECOND #define READ_MINE
#define WRITE_MINE
#define READ_HOUR
#define WRITE_HOUR #define READ_DAY #define WRITE_DAY #define READ_MONTH #define WRITE_MONTH #define READ_WEEK #define WRITE_WEEK #define READ_YEAR
#define WRITE_YEAR
uint8 SET;uint8 PRE_HOUR;uint8 DATE[16];uint8 TIME[16];
0x81 0x80 0x83 0x82 0x85 0x84 0x87 0x86 0x89 0x88 0x8b 0x8a 0x8d 0x8c 8
void delaynus(uint8 n){
uint8 i;
for(i=0;i } void RTC_Write(uint8 dat){ uint8 i; RTC_SCL=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delaynus(2); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续写8个二进制位数据 { RTC_SDA=dat&0x01; //取出dat的第0位数据写入1302 delaynus(2); //稍微等待,使硬件做好准备 RTC_SCL=1; //上升沿写入数据 delaynus(2); //稍微等待,使硬件做好准备 RTC_SCL=0; //重新拉低SCLK,形成脉冲 dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 } } uint8 RTC_Read(){ uint8 i,dat; delaynus(2); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续读8个二进制位数据 { dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位 if(RTC_SDA==1) //如果读出的数据是1 dat|=0x80; //将1取出,写在dat的最高位 RTC_SCL=1; //将SCLK置于高电平,为下降沿读出 delaynus(2);//稍微等待 RTC_SCL=0; //拉低SCLK,形成脉冲下降沿 delaynus(2);//稍微等待 } return dat; //将读出的数据返回 } void RTC_Write_Byte(uint8 addr,uint8 dat){ RTC_RST=0; //禁止数据传递 RTC_SCL=0; //确保写数居前SCLK被拉低 RTC_RST=1; //启动数据传输 delaynus(2); //稍微等待,使硬件做好准备 RTC_Write(addr); //写入命令字 RTC_Write(dat); //写数据 RTC_SCL=1; //将时钟电平置于已知状态 RTC_RST=0; //禁止数据传递 } uint8 RTC_Read_Byte(uint8 addr){ uint8 dat; RTC_RST=0; //拉低RST RTC_SCL=0; //确保写数居前SCLK被拉低 RTC_RST=1; //启动数据传输 RTC_Write(addr); //写入命令字 dat=RTC_Read(); //读出数据 RTC_SCL=1; //将时钟电平置于已知状态 RTC_RST=0; //禁止数据传递 return dat; //将读出的数据返回 } typedef struct __SYSTEMTIME__ { uint8 Second;uint8 Mine;uint8 Hour;uint8 Day;uint8 Month;uint8 Week;uint8 Year;}SYSTEMTIME; static SYSTEMTIME TIMETYPE; void CurrentTime(SYSTEMTIME *dat){ uint8 TimeValue; TimeValue=RTC_Read_Byte(READ_SECOND);dat->Second=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_MINE);dat->Mine=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_HOUR);dat->Hour=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_DAY);dat->Day=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_MONTH);dat->Month=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_WEEK);dat->Week=(TimeValue&0x0f); TimeValue=RTC_Read_Byte(READ_YEAR);dat->Year=(((TimeValue&0x70)>>4)*10)+(TimeValue&0x0f);} bit LCD_BUSY(){ bit result;LCD_RS=0;LCD_RW=1;LCD_EN=1;_nop_();_nop_();result=(bit)(LCD_PORT&0x80);LCD_EN=0;return result;} void LCD_Write(uint8 dat,uint8 type) //LCD写字符 { uint8 i;while((LCD_BUSY()&&i<100)){i++;} if(i>99)LCD_NO=1;LCD_RS=type;LCD_RW=0;LCD_EN=0;_nop_();_nop_();_nop_();_nop_();LCD_PORT=dat;_nop_();_nop_();_nop_();_nop_();LCD_EN=1;_nop_();_nop_();_nop_();_nop_();LCD_EN=0;} void LCD_INITIALIZE() //LCD初始化 { LCD_Write(0x06,LCD_COMMAND);LCD_Write(0x38,LCD_COMMAND);LCD_Write(0x0c,LCD_COMMAND);LCD_Write(0x01,LCD_COMMAND);} void LCD_Prints(uint8 *dat,uint8 add) //LCD打印函数 { LCD_Write(add|0x80,LCD_COMMAND);while(*dat!=' ')LCD_Write((*(dat++)),LCD_DATA);} void KEY_Delay(){ uint8 i,j;for(i=0;i<200;i++)for(j=0;j<200;j++);} void SET_YEAR(){ uint8 YEAR[3];LCD_Prints(“ YEAR SETTING ”,0);LCD_Prints(“ YEAR:20 ”,0x40);if((!KEY3)&&(TIMETYPE.Year<80)){KEY_Delay();i1=i2=0;TIMETYPE.Year++;} else if(TIMETYPE.Year>79)TIMETYPE.Year=0;if((!KEY4)&&(TIMETYPE.Year>0)){KEY_Delay();i1=i2=0;TIMETYPE.Year--;} YEAR[0]=(TIMETYPE.Year/10)+'0';YEAR[1]=(TIMETYPE.Year%10)+'0';YEAR[2]=' ';LCD_Prints(YEAR,0x49);} void SET_MONTH(){ uint8 MONTH[3];LCD_Prints(“ MONTH SETTING ”,0);LCD_Prints(“ MONTH: ”,0x40);if((!KEY3)&&(TIMETYPE.Month<13)){KEY_Delay();TIMETYPE.Month++;i1=i2=0;} else if(TIMETYPE.Month>12)TIMETYPE.Month=1;if((!KEY4)&&(TIMETYPE.Month>1)){KEY_Delay();TIMETYPE.Month--;i1=i2=0;} MONTH[0]=(TIMETYPE.Month/10)+'0';MONTH[1]=(TIMETYPE.Month%10)+'0';MONTH[2]=' ';LCD_Prints(MONTH,0x48);} void SET_DAY(){ uint8 DAY[3];LCD_Prints(“ DAY SETTING ”,0);LCD_Prints(“ DAY: ”,0x40);if((!KEY3)&&(TIMETYPE.Day<32)){KEY_Delay();TIMETYPE.Day++;i1=i2=0;} else if(TIMETYPE.Day>31)TIMETYPE.Day=1;if((!KEY4)&&(TIMETYPE.Day>1)){KEY_Delay();TIMETYPE.Day--;i1=i2=0;} DAY[0]=(TIMETYPE.Day/10)+'0';DAY[1]=(TIMETYPE.Day%10)+'0';DAY[2]=' ';LCD_Prints(DAY,0x46);} void SET_WEEK(){ uint8 WEEK[2];LCD_Prints(“ WEEK SETTING ”,0);LCD_Prints(“ WEEK: ”,0x40);if((!KEY3)&&(TIMETYPE.Week<8)){KEY_Delay();TIMETYPE.Week++;i1=i2=0;} else if(TIMETYPE.Week>7)TIMETYPE.Week=1;if((!KEY4)&&(TIMETYPE.Week>1)){KEY_Delay();TIMETYPE.Week--;i1=i2=0;} WEEK[0]=TIMETYPE.Week+'0';WEEK[1]=' ';LCD_Prints(WEEK,0x47);} void SET_HOUR(){ uint8 HOUR[3];LCD_Prints(“ HOUR SETTING ”,0);LCD_Prints(“ HOUR: ”,0x40);if((!KEY3)&&(TIMETYPE.Hour<24)){KEY_Delay();TIMETYPE.Hour++;i1=i2=0;} else if(TIMETYPE.Hour>23)TIMETYPE.Hour=0;if((!KEY4)&&(TIMETYPE.Hour>0)){KEY_Delay();TIMETYPE.Hour--;i1=i2=0;} HOUR[0]=(TIMETYPE.Hour/10)+'0';HOUR[1]=(TIMETYPE.Hour%10)+'0';HOUR[2]=' ';LCD_Prints(HOUR,0x47);} void SET_MINE(){ uint8 MINE[3];LCD_Prints(“ MINE SETTING ”,0);LCD_Prints(“ MINE: ”,0x40);if((!KEY3)&&(TIMETYPE.Mine<60)){KEY_Delay();TIMETYPE.Mine++;i1=i2=0;} else if(TIMETYPE.Mine>59)TIMETYPE.Mine=0;if((!KEY4)&&(TIMETYPE.Mine>0)){KEY_Delay();TIMETYPE.Mine--;i1=i2=0;} MINE[0]=(TIMETYPE.Mine/10)+'0';MINE[1]=(TIMETYPE.Mine%10)+'0';MINE[2]=' ';LCD_Prints(MINE,0x47);} void SET_SECOND(){ uint8 SECOND[3];LCD_Prints(“ SECOND SETTING ”,0);LCD_Prints(“ SECOND: ”,0x40);if((!KEY3)&&(TIMETYPE.Second<60)){KEY_Delay();TIMETYPE.Second++;i1=i2=0;} else if(TIMETYPE.Second>59)TIMETYPE.Second=0;if((!KEY4)&&(TIMETYPE.Second>0)){KEY_Delay();TIMETYPE.Second--;i1=i2=0;} SECOND[0]=(TIMETYPE.Second/10)+'0';SECOND[1]=(TIMETYPE.Second%10)+'0';SECOND[2]=' ';LCD_Prints(SECOND,0x48);} void Write_Time(){ uint8 year,month,day,hour,mine,second,week;year=((TIMETYPE.Year/10)<<4)|(TIMETYPE.Year%10);month=((TIMETYPE.Month/10)<<4)|(TIMETYPE.Month%10);day=((TIMETYPE.Day/10)<<4)|(TIMETYPE.Day%10);week=TIMETYPE.Week;hour=((TIMETYPE.Hour/10)<<4)|(TIMETYPE.Hour%10);mine=((TIMETYPE.Mine/10)<<4)|(TIMETYPE.Mine%10);second=((TIMETYPE.Second/10)<<4)|(TIMETYPE.Second%10);RTC_Write_Byte(0x8e,0x00);//写入允许 RTC_Write_Byte(0x80,WRITE_SECOND|0x80);RTC_Write_Byte(0x8e,0x80);//禁止写入 RTC_Write_Byte(0x8e,0x00);//写入允许 RTC_Write_Byte(WRITE_YEAR,year);//写入新的秒数 RTC_Write_Byte(WRITE_MONTH,month);//写入新的秒数 RTC_Write_Byte(WRITE_DAY,day);//写入新的秒数 RTC_Write_Byte(WRITE_HOUR,hour);//写入新的秒数 RTC_Write_Byte(WRITE_MINE,mine&0x7f);//写入新的秒数 RTC_Write_Byte(WRITE_WEEK,week);//写入新的秒数 RTC_Write_Byte(WRITE_SECOND,second);RTC_Write_Byte(0x8e,0x00);//写入允许 RTC_Write_Byte(0x8e,0x80);} void SET_TIME(){ uint8 i;CurrentTime(&TIMETYPE);while(1){ switch(i) { case 0:SET_YEAR();break; case 1:SET_MONTH();break; case 2:SET_DAY();break; case 3:SET_WEEK();break; case 4:SET_HOUR();break; case 5:SET_MINE();break; case 6:SET_SECOND();break; } if(!KEY2){i++;KEY_Delay();i1=i2=0;} while(!KEY2); if(i==7){i=0;Write_Time();break;} i1++; if(i1==10){i2++;i1=0;} if(i2==100){i=0;Write_Time();break;} } SET = 1;} void TIMESETTING(){ if(!KEY1){SET_TIME();} } void LCD_DISP(){ DATE[0]='2';DATE[1]='0';DATE[4]='/';DATE[7]='/';DATE[10]='/';DATE[11]=' ';DATE[14]=' ';DATE[16]=' ';TIME[2]=':';TIME[5]=':';} void LCD_Disp_Time() //读显时间 { DATE[2]=TIMETYPE.Year/10+'0';DATE[3]=TIMETYPE.Year%10+'0';DATE[5]=TIMETYPE.Month/10+'0';DATE[6]=TIMETYPE.Month%10+'0';DATE[8]=TIMETYPE.Day/10+'0';DATE[9]=TIMETYPE.Day%10+'0';DATE[11]=TIMETYPE.Week+'0'; TIME[0]=TIMETYPE.Hour/10+'0';TIME[1]=TIMETYPE.Hour%10+'0';TIME[3]=TIMETYPE.Mine/10+'0';TIME[4]=TIMETYPE.Mine%10+'0';TIME[6]=TIMETYPE.Second/10+'0';TIME[7]=TIMETYPE.Second%10+'0'; LCD_Prints(DATE,0x02);LCD_Prints(TIME,0x44);} void main(){ uint8 INIT = 1; TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256; EA = 1;ET0 = 1;TR0 = 1; ALARM = 0;LCD_INITIALIZE(); //LCD初始化 LCD_DISP(); //液晶显示初始值 PRE_HOUR = TIME[1]; while(1){ if((!KEY1)&&(!LCD_NO))TIMESETTING(); if(SET == 1) { SET = 0; LCD_INITIALIZE();//LCD初始化 } CurrentTime(&TIMETYPE); LCD_Disp_Time(); if(INIT == 1) { INIT = 0; PRE_HOUR = TIME[1]; } } } void timer0()interrupt 1 { uint16 i,TIM; TH0=(65536-45872)/256;TL0=(65536-45872)%256;TIM++; if(TIM == 10){ TIM = 0; if(PRE_HOUR!= TIME[1]) { i++; ALARM =~ ALARM; if(i == 10) { i = 0; PRE_HOUR = TIME[1]; } } } } 18 实验 一、MCS51单片机基本开发环境 1. 实验目的: 1)熟悉软件的集成开发环境 2)掌握单片机软件设计流程 3)掌握单片机存贮器结构及各窗口之间的联系 2. 实验内容: 1)用三种方法实现将累加器A内容改为20H 方法1--MOV A,#20H 方法2—MOV R0,#20H MOV A,R0 方法3—MOV R0,#20H XCH A,R0 心得:越往下做实验时就越感觉这题根本不能说是题目,但不得不说在没接触过编程软件,刚开始学的汇编,第一次做的实验就光这道题都觉得不知道做什么.所以凡是总有开始,不了解情况的多简单的都会觉得难.2)将58H位单元置为1,观察内部RAM中2BH内容的变化 代码: SETB 2BH.0 JMP $ END 心得:这是关于内部存储中对单元和字节了解,不理解很容易做错.比如开始写的指令为 MOV R0,#58H;MOV @R0,#1 这是错误的指令。这就需要认真去了解单片机中的字节地址与位地址的关系。80C51中有位寻址区和字节寻址区。题目中58H为位地址,2BH为字节地址,且58H为2B字节的最低位。由于58H属于位寻址区,可用位操作指令 SETB 进行置位,SETB 2BH.0 执行后,2BH中内容变为01 3)如果当前状态为有进位、工作寄存器使用区2,请用3种方法设置这种状态 代码: ANL PSW,#01H MOV A,PSW CJNE A,#01,LAB2 LAB1:JMP LAB1 LAB2: SETB PSW.4 MOV P0,#01H MOV R0,#18H CLR PSW.3 MOV C,P0.0 MOV PSW,R0 MOV PSW.4,C CPL C MOV PSW.3,C END 心得:以上LAB2写了三段代码,可分别完成题目要求。不过实验时只是对代码进行了错误调试,没有对结果进行检验。其中值得注意的是对于布尔(位)操作指令的用法,比如传送指令必须经累加器C,如第二段中MOV P0,#01H;MOV C,P0.0,以及对于位寻址的方式(如需用到“.”隔开)的应用。4)编一个小程序将内部RAM中的20H单元的内容送到21H单元并调试 代码: MOV R0,#20H MOV @R0,#10H MOV R1,#21H MOV @R1,20H JMP $ END 5)用程序将堆栈指针指向60H,然后在堆栈中依次压入01,02,03,04,05五个数,观察哪些单元内容发生了变化,各变为多少?从哪些窗口可以发现这些变化?顺序将堆栈中的五个数放入30H~34H五个单元中,编程实现之。 代码: MOV R1,#60H MOV SP,R1 MOV DPL,#1H LAB1:PUSH DPL INC DPL MOV A,DPL CJNE A,#6,LAB1 POP 34H POP 33H POP 32H POP 31H POP 30H JMP $ END 6)将外部数据存贮器1000H~100FH 16个单元中存放00H~0FH 代码: MOV DPTR,#1000H MOV R1,#10H LOOP:MOVX @DPTR,#1234H MOVX A,@DPTR MOV @R1,A INC DPTR INC R1 CJNE R1,#40H,LOOP JMP $ END 心得:此处需要访问片外存储空间,需要借助寄存器DPTR,需注意其为16位的寄存器,在使用时若与八位寄存器进行数据交换时需分为高八位DPH与低八位DPL来用。7)若要求程序从0010H单元开始运行,可用两种方法实现? 方法一 ORG 0010H 方法二 AJMP 0010H 3. 选做实验内容:数据传送 目的: 1)掌握8051单片机内部数据存贮器、外部数据存贮器的数据传送特点和应用 2)掌握MOV,MOVX和MOVC类指令的用法及区别 内容: 1)将片内RAM数据区20H为首地址的十六个字节传送到30H为首地址的数据区,即:20H~2FH送30H~3FH 代码: ORG 0000H JMP MAIN ORG 0030H MAIN:MOV R0,#20H MOV R1,#30H LOOP:MOV @R0,#1234H MOVA,@R0 MOV @R1,A INC R0 INC R1 CJNE R1,#30H,LOOP JMP $ END 2)将外部数据存储器2000H~200FH单元的十六个数传送至内部数据存储器的30H~3FH 代码: ORG 0000H JMP MAIN ORG 0030H MAIN: MOV DPTR,#2000H MOV R1,#30H LOOP:MOVX @DPTR,#12H MOVX A,@DPTR MOV @R1,A INC DPTR INC R1 CJNE R1,#40H,LOOP JMP $ END 总体心得体会: 第一次做实验主要是熟悉了解了下单片机编程软件的使用,开始接触时在对其软件不是太了解的情况下实验编程做的确实很乱,不清楚该怎样进行,比如不知如何进行对指令的调试,也不清楚该如何观察结果,没有一个整体的概念,所以在了解其开发环境上花了不少时间。经过一段时间的摸索后也终于了解了其具体的使用,也能够顺利的对指令的编程运用。运行指令时遇到的一些问题需要注意的也在上面各题中做了说明。还有需要注意的是:进入软件仿真时需要对存储空间进行查看的方法是在Address窗口中输入:d:00h 显示内部数据存储器从00h开始的单元; x:1000h 显示外部数据存储器从1000h开始的单元; c:0000H 显示程序存储器内容。还有由于伪指令 END 定义的原因,在程序末需加一条死循环调转指令(如 JMP $)使程序不会进入其他未知空间执行其他指令。实验 二、加、减法实验 1. 实验目的 1)正确使用单片机的加减运算指令 2)掌握不同指令对于程序状态字的影响及程序状态字的意义、用处 3)掌握ADD,ADDC,SUBB和DA A等指令的用法 4)学习模块化程序设计方法 2. 实验内容 1)编写3字节二进制加法子程序,并用主程序调用不同的加数和被加数来检测该子程序的正确性。需考虑有进位和无进位情况。程序入口为: 加数:22H,21H,20H三字节,22H为最高位 被加数:32H,31H,30H三字节,32H为最高位 程序出口为: 23H,22H,21H,20H四字节,23H为最高位 例如:地址:23 22 21 20 32 31 30 执行前数据: 01 23 45 FF 01 01 执行后数据:01 00 24 46 代码: ORG 0000H AJMP MAIN ORG 30H MAIN: MOV 22H,#01H MOV 21H,#23H MOV 20H,#45H MOV 32H,#0FFH MOV 1H,#01H MOV 30H,#01H ACALL ADDI HERE:JMP HERE ORG 100H ADDI: PUSH PSW MOV R0, #20H;加数1地址、和的地址 MOV R1, #30H;加数2地址 CLR C MOV R2, #3;循环3次 LOOP: MOV A, @R0;取 ADDC A, @R1;加 MOV @R0, A;存 INC R0 INC R1 DJNZ R2, LOOP CLR A ADDC A, #0;得到进位 MOV 23H, A;保存 POP PSW RET END 2)编写三字节二进制减法子程序 入口:被减数: 52H,51H,50H, 50H为最低位 减数: 42H,41H,40H, 40H为最低位 出口:差:外部数据存贮器2003H~2000H(2000H为最低位)用主程序调用多组数据来调试,需考虑无借位和有借位两种情况。例如: 执行前:地址: 52 51 50 42 41 40 数据: 90 80 70 10 10 10 执行后:地址: 2003 2002 2001 2000 数据: 00 80 70 60 代码: ORG 0000H AJMP MAIN ORG 30H MAIN: MOV 52H,#90H MOV 51H,#80H MOV 50H,#70H MOV 42H,#10H MOV 41H,#10H MOV 40H,#10H ACALL SUB1 HERE:JMP HERE SUB1: PUSH PSW MOV R0, #50H;被减数地址 MOV R1, #40H;减数地址 MOV DPTR, #2000H;差的地址 CLR C MOV R2, #3;循环3次 LOOP: MOV A, @R0;取 SUBB A, @R1;减 MOVX @DPTR, A;存 INC R0 INC R1 INC DPTR DJNZ R2, LOOP CLR A SUBB A, #0;得到借位 MOVX @DPTR, A;存 POP PSW RET END 3)编写10位十进制加法子程序(十进制数采用压缩BCD码存放)入口: 加数:24H—20H,低地址放低字节 被加数:29H—25H,低地址放低字节 出口 和:4005H—4000H,低地址放低字节 要求调用多组数据调试,注意观察PSW的变化,理解DA A指令的含义。例如: 执行前地址:24 23 22 21 20 29 28 27 26 25 数据:12 34 56 78 90 88 99 33 12 74 执行后地址:4005 4004 4003 4002 4001 4000 数据: 01 01 33 89 91 64 代码: ORG 0000H AJMP MAIN ORG 30H MAIN: MOV 24H,#12H MOV 23H,#34H MOV 22H,#56H MOV 21H,#78H MOV 20H,#90H MOV 29H,#88H MOV 28H,#99H MOV 27H,#33H MOV 26H,#12H MOV 5H,#74H ACALL ADD2 HERE:JMP HERE ADD2: PUSH PSW MOV R0, #20H;加数1地址 MOV R1, #25H;加数2地址 MOV DPTR,#4000H CLR C MOV R2, #5;循环5次 LOOP: MOV A, @R0;取 ADDC A, @R1;加 DA A;调整为BCD码 MOVX @DPTR, A;存 INC R0 INC R1 INC DPTR DJNZ R2, LOOP POP PSW RET END 实验一清0、移数 将片内20H~2FH及片外0010H~001FH单元清0; 然后将片内30H~3FH的数据移到片外0000H~000FH中;判断: 若(30H)≤10,则求其平方存到31H中,并将位00H置1(其它位清0)若(30H)=10,则将AA存到31H中,并位01H置1(其它位清0)若(30H)≥10,则减10存到31H中,并位02H置1(其它位清0) 实验二加法、排序 有两个长度为10的无符号数分别放在片内20H和30H为首的存储单元中(低位),求其对应项之和(带进位位),结果放在40H为首的单元中(若最高位有进位则存在后续单元中),然后按升序排列放在50H为首的单元中 实验三查表、散转 设有一表格,表中数为:00H、11H、22H、33H、44H、55H、66H、77H、88H、99H、AAH、BBH、CCH、DDH、EEH、FFH。根据片外0001H单元的低4位的数,取出表中相应的值存到片内30H中;根据片外0001H单元的高4位的数,将片内RAM区中可位寻址的相应的位置1(从位00H~位0FH,只可有一个位地址为1) 实验四外中断 P1.0~P1.7接8个发光二极管,管脚INT0、INT1接两个按键,分别定义为“L”和“R”。 要求:上电全灭,按 “L”(或R)键,最右(左)侧灯亮,每按一次“L” ”(或R)键,则亮的灯向左(右)移一位,当移到最左(右)端时,灯全灭 实验五定时器 P1.0、P1.1分别接两个发光二极管,INT0脚接 一按键做开关,按一次开关,则启动,两个发 光管一亮一灭,亮灭时间均为1秒;再按一次 开关,则关闭,即两个发光管都灭。 实验六定时器、计数器 P3.2口输出周期为2S的方波,T1口为脉冲输入端,记录输入的脉冲个数,脉冲个数由P1口所接的8个数码管显示(二进制),设一按键作为开关控制系统运行,关闭时数码管全灭,P3.2无输出。 单片机技术实验 教 案 冯 杰 实验一(1)顺序结构程序设计 一、实验目的 掌握汇编语言设计和调试方法。 二、实验内容 把外部RAM中2000h单元的内容拆开,高位送2001h单元,低位送2002h单元,2001h、2002h高位清零,一般本程序用于把数据送显示缓冲区时用。 三、程序流程 四、实验步骤 1、LED环境 ⑴在“P.”状态下按“0→EV/UN”,装载实验所需的代码程序。 ⑵在“P.”状态下键入0000,然后按“STEP”或“EXEC”进入实验项目的调试与运行。 2、PC环境 在与PC联机状态下,编译、连接、下载PH51se02.asm,用连续或单步方式运行程序。 3、运行结果检查 ⑴在单步运行时每走一步可观察其运行结果。 ⑵在连续运行状态下,应按“暂停图标”或实验箱上的“暂停按钮”,使系统无条件退出用户运行状态返回监控,然后再用相应的命令键观察与检查2000~2002h中内容变化情况。 五、思考 如何用断点方式调试本程序。 ORG 0000H LJMP START ORG 0030H START: MOV DPTR,#2000H MOVX A,@DPTR ANL A,#0F0H SWAP A MOV DPTR,#2001H MOVX @DPTR,A MOV DPTR ,#2000H MOVX A,@DPTR ANL A,0FH MOV DPTR,#2002H MOVX @DPTR,A SJMP $ END 实验一(2)循环结构程序设计 一、实验目的 熟悉MCS-51指令系统,掌握程序设计方法。 二、实验内容 编写并调试一个排序子程序,其功能为用冒泡法将内容RAM中几个单元字节无符号的正整数,按从小到大的次序重新排列。 三、程序框图 四、实验步骤 1、LED环境 ⑴在“P.”状态下按“0→EV/UN”,装载实验所需的代码程序。 ⑵对片内RAM地址50h~5AH进行不规则置数。 ⑶在“P.”状态下键入0000,然后按“STEP”或“EXEC”进入实验项目的调试与运行。 2、PC环境 在与PC联机状态下,编译、连接、下载PH51se05.asm,用连续或单步方式运行程序。 3、运行结果检查 ⑴在单步运行时每走一步可观察其运行结果。 ⑵在连续运行状态下,应按“暂停图标”或实验箱上的“暂停按钮”,使系统无条件退出用户运行状态返回监控,然后再用相应的命令键观察与检查片内50~5Ah中内容是否按从 小到大排列。 五、思考:修改程序把50~5Ah中内容按从小到大排列。 ORG 0000H LJMP START ORG 0030H MOV R7,#09H MOV R6,#00H;清除标志 CLR C MOV A,@R0 INC R0 SUBB A,@R0 JC LOOP1 MOV R6,#01H DEC R0 MOV A,@R0 INC R0 XCH A,@R0 MOV @R0,A DJNZ R7,START1 CJNE R6,#00H,START SJMP $ END START: MOV R0,#50H START1: DEC R0 INC R0 LOOP1: 实验一(3)选择结构程序设计 一、实验目的 掌握汇编语言的编程。 二、实验内容 编写程序,根据送入的数据转移运行。 三、程序框图 四、实验步骤 1、LED环境 ⑴在“P.”状态下按“0→EV/UN”,装载实验所需的代码程序。⑵在20H中分次送入00、01、02、03。 ⑶在“P.”状态下键入0A10,然后按“STEP”或“EXEC”进入实验项目的调试与运行。 2、PC环境 在与PC联机状态下,编译、连接、下载PH51se08.asm,用连续或单步方式运行程序。 3、运行结果检查 (1)在单步运行时每走一步可观察其运行结果。 (2)在连续运行状态下,应按“暂停图标”或实验箱上的“暂停按钮”,使系统无条件退出用户运行状态返回监控,然后观察每次运行程序后,数码管上数字循环情况。 ORG 0000H LJMP START ORG 0030H START: MOV 20H,#00H MOV A,20H MOV B,#03H MUL AB MOV DPTR,#TAB JMP @A+DPTR SJMP $ ORG 3000H TAB: LJMP LOOPA LJMP LOOPB LJMP LOOPC LOOPA: MOV A,#01H LOOPA1: MOV P1,A LCALL DELAY1S RL A LJMP LOOPA1 LOOPB: MOV A,#03H LOOPB1: MOV P1,A LCALL DELAY1S RL A LJMP LOOPB1 LOOPC: MOV A,#05H LOOPC1: MOV P1,A LCALL DELAY1S RL A LJMP LOOPC1 DELAY1S: DELAY1S3: DELAY1S2: DELAY1S1: MOV R7,#10 MOV R6,#200 MOV R5,#250 DJNZ R5,DELAY1S1 DJNZ R6,DELAY1S2 DJNZ R7,DELAY1S3 RET END 实验二 中断实验 一、实验目的 熟悉单片机中断概念及中断编程方法。 二、实验内容 编写程序,从P3.3输入脉冲,记录输入脉冲个数,并用P1口外部链接的发光二极管显示技术结果。 二、参考程序 ORG 0000H LJMP START ORG 0013H LJMP INT1_COUNT ORG 0030H START: MOV SP,#60H MOV A,#00H SETB IT1;下降边沿触发方式 SETB EX1;开启INT1中断 SETB EA SJMP $ INT1_COUNT: INC A MOV P1,A RETI END 实验三 LED显示实验 一、实验要求 利用实验系统提供的显示设备,动态显示一行数据。 二、实验目的 ⑴了解数码管动态显示的原理; ⑵了解用总线方式控制数码管显示。 三、实验说明 本实验系统提供了8位七段码LED显示电路,学生只要按地址输出相应数据,就可以实现对显示器的控制。 四、程序框图 ORG 0000H LJMP START ORG 0030H START: MOV SP,#60H MOV 50H,#8CH;显示字符P.MOV 51H,#40H MOV 52H,#79H MOV 53H,#24H MOV 54H,#30H MOV 55H,#19H MOV 56H,#12H MOV 57H,#02H LOOP1: LCALL DISPLAY LJMP LOOP1 DISPLAY: MOV P2,#0FH MOV P0,50H LCALL DELAY20MS MOV P2,#1FH MOV P0,51H LCALL DELAY20MS MOV P2,#2FH MOV P0,52H LCALL DELAY20MS MOV P2,#3FH MOV P0,53H LCALL DELAY20MS MOV P2,#4FH MOV P0,54H LCALL DELAY20MS MOV P2,#5FH MOV P0,55H LCALL DELAY20MS MOV P2,#6FH MOV P0,56H LCALL DELAY20MS MOV P2,#7FH MOV P0,57H LCALL DELAY20MS LJMP DISPLAY DELAY20MS: MOV R7,#20 DELAY1: MOV R6,#100 DELAY2: DJNZ R6,DELAY2 DJNZ R7,DELAY1 RET TAB: DB 40H,79H,24H,30H,19H,12H,02H;0 1 2 3 4 5 6 DB 78H,00H,10H,08H,03H,46H,21H,06H,0EH;7 8 9 A B C D E F的字符码 TAB1: DB 8CH;P.TAB2: DB 7FH;END 的字符码的字符码 空,不显示的字符 键盘电路实验 电路图: 程序: ;用int1中断实现按键功能,键值存放在4fh单元中;通过P1口输出按键值,用发光二极管显示按键值;通过P2.4--P2.6和三八译码器输出八列按键扫描码;通过P2.0---P2.3读入按键的行值;行列值组合,就是按键的键值 ORG 0000H LJMP START ORG 0013H LJMP key_value ORG 0030H START: MOV 4fH,#00h;存放按键键值单元 MOV P1,#00H MOV P2,#0FFH setb ex1 setb it1 setb ea KEY_SCAN: MOV P2,#0FH LCALL DELAY5MS MOV P2,#1FH LCALL DELAY5MS MOV P2,#2FH LCALL DELAY5MS MOV P2,#3FH LCALL DELAY5MS MOV P2,#4FH LCALL DELAY5MS MOV P2,#5FH LCALL DELAY5MS MOV P2,#6FH LCALL DELAY5MS MOV P2,#7FH LCALL DELAY5MS LJMP KEY_SCAN DELAY5MS: MOV R7,#40 DELAY1: MOV R6,#100 DELAY2: DJNZ R6,DELAY2 DJNZ R7,DELAY1 RET KEY_VALUE: PUSH ACC PUSH PSW MOV A,P2 MOV 4FH,A MOV P1,A POP PSW POP ACC RETI END LED和键盘综合实验 电路图: 参考程序: ORG 0000H LJMP START ORG 0013H LJMP KEY_VALUE ORG 0030H START: MOV SP,#60H MOV 4fH,#00h;存放按键键值单元 MOV P2,#0FFH setb ex1 setb it1 setb ea MOV 50H,#0CH;显示字符P.MOV 51H,#0CH MOV 52H,#7FH MOV 53H,#7FH MOV 54H,#7FH MOV 55H,#7FH MOV 56H,#7FH MOV 57H,#0CH LOOP1: LCALL DISPLAY LJMP LOOP1 DISPLAY: MOV P2,#0FH MOV P0,50H LCALL DELAY20MS MOV P2,#1FH MOV P0,51H LCALL DELAY20MS MOV P2,#2FH MOV P0,52H LCALL DELAY20MS MOV P2,#3FH MOV P0,53H LCALL DELAY20MS MOV P2,#4FH MOV P0,54H LCALL DELAY20MS MOV P2,#5FH MOV P0,55H LCALL DELAY20MS MOV P2,#6FH MOV P0,56H LCALL DELAY20MS MOV P2,#7FH MOV P0,57H LCALL DELAY20MS LJMP DISPLAY DELAY20MS: MOV R7,#20 DELAY1: MOV R6,#100 DELAY2: DJNZ R6,DELAY2 DJNZ R7,DELAY1 RET KEY_VALUE: PUSH ACC PUSH PSW MOV 4FH,P2 LCALL KEY_VALUE_DISP POP PSW POP ACC RETI KEY_VALUE_DISP: MOV A,4FH ANL A,#0F0H SWAP A MOV DPTR,#TAB MOVC A,@A+DPTR MOV 56H,A MOV A,4FH ANL A,#0FH MOVC A,@A+DPTR MOV 57H,A RET TAB: DB 40H,79H,24H,30H,19H,12H,02H;0 1 2 3 4 5 6的字符码 DB 78H,00H,10H,08H,03H,46H,21H,06H,0EH;7 8 9 A B C D E F的字符码 TAB1: DB 8CH;P.的字符码 TAB2: DB 7FH;空,不显示的字符 END 实验四 A/D转换实验 一、实验目的 (1)掌握A/D转换与单片机接口的方法;(2)了解A/D芯片0809转换性能及编程方法;(3)通过实验了解单片机如何进行数据采集。 二、实验内容 利用实验系统上的0809做A/D转换器,实验系统上的电位器提供模拟量输入,编制程序,将模拟量转换成数字,通过数码管显示出来。 三、程序框图 四、实验电路 五、实验步骤 把0809的零通道INT0用插针接至AINl孔,0809CS位FFE0孔,运行程序,数码管显示0809.XX,后二位显示当前采集的电压转换的数字量,调节W1,该二位将随着电压变化而相应变化。 六、思考 修改程序,用其它通道轮流采样显示。 实验五 电脑时钟(定时器、中断综合实验) 一、实验目的 熟悉MCS-51定时器,串行口和中断初始化编程方法,了解定时器的应用实时程序的设计与调试技巧。 二、实验内容 编写程序,从本实验系统键盘上输入时间初值,用定时器产生0.1S定时中断,对时钟计数器计数,并将数值实时地送数码管显示。 三、程序框图 四、实验步骤 连续运行程序,在键盘上输入时间初值,按执行键EXEC执行,数码管上实时显示时间值。 五、思考 (1)电子钟走时精度和程序中那些常数有关? (2)修改程序使定时器工作方式改变,调节有关参数,进一步提高精度。 六、参考程序 ORG 0000H LJMP START ORG 000BH LJMP T0_INT ORG 0030H START: MOV 50H,#00H;时的低位字符码 MOV 51H,#00H;时的高位字符码 MOV 52H,#00H;“-”的字符码 MOV 53H,#00H;分的低位字符码 MOV 54H,#00H;分的高位字符码 MOV 55H,#00H;“-”的字符码 MOV 56H,#00H;秒的低位字符码 MOV 57H,#00H;秒的高位字符码 MOV 5FH,#00H;存放小时的单元 MOV 5EH,#00H;存放分钟的单元 MOV 5DH,#00H;存放秒的单元 MOV 5CH,#00H;存放T0中断次数,50次为1秒 MOV SP,#60H;设置堆栈栈顶 MOV TH0,#???;设置T0定时器初值 MOV TL0,#??? MOV TMOD,#00000001H;T0工作在定时方式,工作方式0 SETB ET0;开放T0中断 SETB EA;开放总中断 SETB TR0;启动定时器T0 LOOP: mov P2,#11111110H MOV R0,#50H loop1: MOV R7,#08H LOOP2: MOV A,@R0 MOV P1,A LCALL DELAY INC R0 MOV A,P2 RL A MOV P2,A DJNZ R7, LOOP2 LJMP LOOP SJMP $ DELAY: MOV R6,#2;延时程序 DELAY1: MOV R5,#10 DELAY2: MOV R4,#100 DELAY3: DJNZ R4,DELAY3 DJNZ R5,DELAY2 DJNZ R6,DELAY1 RET 16 T0_INT: CLR TR0 PUSH ACC MOV A,5CH CJNE A,#50H,T0_INT1 MOV 5CH,#00H MOV A,5DH CJNE A,#59H,T0_INT2 MOV 5DH,#00H MOV A,5EH CJNE A,#59H,T0_INT3 MOV 5EH,#00H MOV A,5FH CJNE A,#23H,T0_INT4 MOV 5FH,#00H LJMP T0_END T0_INT1: INC 5CH LJMP T0_END T0_INT2: INC 5DH LJMP T0_END T0_INT3: INC 5EH LJMP T0_END T0_INT4: INC 5FH T0_END: MOV A,5FH MOV B,#10 DIV AB MOV 51H,A MOV A,B MOV 50H,A MOV A,5EH MOV B,#10 DIV AB MOV 54H,A MOV A,B MOV 53H,A MOV A,5DH MOV B,#10 DIV AB MOV 57H,A MOV A,B MOV 56H,A POP ACC MOV TH0,#??? MOV TL0,#??? SETB TR0 RETI 实验六 LCD液晶显示屏实验 一、实验目的 ⑴掌握单片机扩展液晶显示接口的设计与编程。⑵利用字符式液晶显示器显示字符。 二、实验内容 编制程序,在液晶显示器上显示: 学生所在的院系的汉语拼音字母和学生的名字。分两行显示。 三、实验电路 四、参考程序 DAT1 DAT2 EQU EQU 30H;第一参数单元 31H;第二参数单元 32H;指令代码单元 0100H;指令通道地址 0000H;数据通道地址 COM EQU C_ADD EQU D_ADD EQU org 0000h ljmp main org 0030h;主程序 MAIN: MOV SP,#60H; lcall delay;上电延时 LCALL INT;初始化 LCALL CLEAR;清缓冲区 TEST: LCALL hgnu_disp;显示“WELCOM TO HGNU” LCALL PL_XW_ZKB;显示 “P_L :” “X_W :” “ZKB:” sjmp test ;上电延时子程序 delay: MOV R6,#50H;MOV R7,#00H;DELY1: NOP DJNZ R7,DELY1;上电延时 DJNZ R6,DELY1;ret;读状态字子程序 R_ST: MOV DPTR,#C_ADD;设置指令通道 MOVX A,@DPTR;RET;判断状态位STA1,STA0子程序(读写指令和数据),在指令的读,写 ;数据之前这两个标志必须同时为“1” ST01: LCALL R_ST;JNB ACC.0,ST01;JNB ACC.1,ST01;RET;判断状位STA2子程序(数据自动读状态),该位 ;在数据自动操作过程中取代STA0和STA1有效。在连续读过程中每读一次;之前都要确认STA2=1 ST2: LCALL R_ST;JNB ACC.2,ST2;RET;判断STA3子程序(数据自动写状态)ST3: LCALL R_ST;JNB ACC.3,ST3;RET;判断状态位STA6子程序(屏读/屏拷贝状态)ST6: LCALL R_ST;JB ACC.6,ERR;RET ERR: LJMP ST6;;出错处理 ;写指令和写数据子程序..;双字节参数指令写入入口 PR1: LCALL ST01;判断状态位STA1,STA0 MOV A,DAT1;取第一参数单元数据 LCALL PR13;写入参数;单字节参数指令写入入口 PR11: LCALL ST01;判断状态位STA1,STA0 MOV A,DAT2;取第二参数单元数据 LCALL PR13;写入参数 ;无参数指令写入入口 PR12: LCALL ST01;无参数指令写入入口 MOV A,COM;取指令代码单元数据 MOV DPTR,#c_ADD;设置指令通道地址/数据写入入口 LJMP PR14;写入指令代码 PR13: MOV DPTR,#D_ADD;设置数据通道地址/数据写入入口 PR14: MOVX @DPTR,A;写入操作 RET;读数据子程序 PR2: LCALL ST01;判断状态位 MOV DPTR,#D_ADD;设置数据通道地址 MOVX A,@DPTR;读数据操作 MOV DAT2,A;数据存入第二参数/数据单元 RET;初始化子程序 INT: ;显示区域设置 MOV DAT1,#00H;设置文本显示区首地址 MOV DAT2,#00h;MOV COM,#40H;LCALL PR1;双字节参数指令写入入口 MOV DAT1,#16;设置文本显示区域宽度 MOV DAT2,#00H;即一行显示所占字节数 MOV COM,#41H;LCALL PR1;双字节参数指令写入入口 MOV DAT1,#00H;设置显示区域首地址 MOV DAT2,#00H;或文本属性区域首地址 MOV COM,#42H;LCALL PR1;双字节参数指令写入入口 MOV DAT1,#10H;设置图形显示区域宽度 MOV DAT2,#00H;或为文本属性区域狂宽度 MOV COM,#43H;即一行显示所占字节数 LCALL PR1;双字节参数指令写入入口 ;显示光标设置 MOV COM,#0A1H;光标形状设置 LCALL PR12; ;设置光标初始位置,是字符行和字符列,第0行第15列 MOV DAT1,#0;光标行位置 MOV DAT2,#0;光标列位置 MOV COM,#21H;LCALL PR1;双字节参数指令写入入口 ;显示方式设置,使用内部字符发生器 MOV COM,#80H;显示方式设置,逻辑“或”合成 LCALL PR12;无参数指令写入入口+ MOV COM,#97H;仅用文本显示 LCALL PR12;无参数指令写入入口 ;显示开关方式 RET ;写数据子程序,8*8点阵 ;R6中装入显示位置的列数(字符的个数),每行16个字符,R7中装入显示位置距左上角的字符行数 ;5FH单元中装入待显示的字符码 DISP: mov b,r7 mov a,#16 mul ab mov r7,a CLR C mov a,R6 ADD A,R7 MOV R6,A;R7*16+R6 MOV DAT1,R6;设置显示RAM首地址,水平方向字符数 MOV DAT2,#00H;固定送00H MOV COM,#24H;地址指针指令 LCALL PR1;MOV dat2,5fH;取要显示的字符 MOV COM,#0c4H;数据写,地址不变 LCALL PR11;写入数据 RET;清显示缓冲区(16*8单元)clear: MOV 5FH,#00H MOV R5,#0 CLEAR0: MOV R4,#0 CLEAR1: MOV A,R5 MOV R7,A MOV A,R4 MOV R6,A CLEAR2: LCALL DISP INC R4 CJNE R4,#16,CLEAR1 mov r4,#00h INC R5 CJNE R5,#8,CLEAR0 CLEAR9: RET;显示频率、相位、占空比、相位差等字符。(P_L :;PL_XW_ZKB:MOV R7,#3 MOV R6,#0 MOV 5fh,#30H;“P” LCALL DISP MOV R7,#3 MOV R6,#1 MOV 5fh,#3FH;“_” LCALL DISP MOV R7,#3 MOV R6,#2 MOV 5fh,#2CH;“L” X_W : ZKB:) LCALL DISP MOV R7,#3 MOV R6,#3 MOV 5fh,#1AH;“: ” LCALL DISP MOV R6,#0 MOV 5fh,#38H;“X” LCALL DISP MOV R7,#5 MOV R6,#1 MOV 5fh,#3FH;“_” LCALL DISP MOV R7,#5 MOV R6,#2 MOV 5fh,#37H;“W” LCALL DISP MOV R7,#5 MOV R6,#3 MOV 5fh,#1AH;“: ” LCALL DISP MOV R7,#5 MOV R7,#7 MOV R6,#0 MOV 5fh,#3AH;“Z” LCALL DISP MOV R7,#7 MOV R6,#1 MOV 5fh,#2BH;“K” LCALL DISP MOV R7,#7 MOV R6,#2 MOV 5fh,#22H;“B ” LCALL DISP MOV R7,#7 MOV R6,#3 MOV 5fh,#1AH;“: ” LCALL DISP RET;顶行显示“黄冈师院物科院“的英文名称。;”welcome to hgnu!“ hgnu_DISP: MOV R7,#0;显示位置的行列数 MOV R6,#0 MOV 5fh,#37H;”W“ LCALL DISP MOV R7,#0 MOV R6,#1 MOV 5fh,#25H;”E“ LCALL DISP MOV R7,#0 MOV R6,#2 MOV 5fh,#2CH;”L“ LCALL DISP MOV R7,#0 MOV R6,#3 MOV 5fh,#23H;”C“ LCALL DISP MOV R7,#0 MOV R6,#4 MOV 5fh,#2FH;”0“ LCALL DISP MOV R7,#0 MOV R6,#5 MOV 5fh,#2DH;”M“ LCALL DISP MOV R7,#0 MOV R6,#6 MOV 5fh,#25H;”E“ LCALL DISP MOV R7,#0 MOV R6,#7 MOV 5fh,#00H;” “ LCALL DISP MOV R7,#0 MOV R6,#8 MOV 5fh,#34H;”T“ LCALL DISP MOV R7,#0 MOV R6,#9 MOV 5fh,#2FH;”O“ LCALL DISP MOV R7,#0 MOV R6,#10 MOV 5fh,#00H;” “ LCALL DISP MOV R7,#0 MOV R6,#11 MOV 5fh,#28H;”H“ LCALL DISP MOV R7,#0 MOV R6,#12 MOV 5fh,#27H;”G“ LCALL DISP MOV R7,#0 MOV R6,#13 MOV 5fh,#2EH;”N“ LCALL DISP MOV R7,#0 MOV R6,#14 MOV 5fh,#35H;”U“ LCALL DISP RET tab: db 10h,11h,12h,13h,14h,15h,16h,17h,18h,19h;”0-----9“ db 21h,22h,23h,24h,25h,26h;”A-----F" end 实验七 直流电机转速测量与控制实验 一、实验目的 1.掌握直流电机的驱动原理。2.了解直流电机调速的方法。 二、实验内容 1.用0832 D/A转换电路后的输出经放大后驱动直流电机。 2.编制程序改变0832输出经放大后的方波信号的占空比来控制电机转速。本实验中 D/A输出为双极性输出,因此电机可以正反向旋转。 三、程序流程 三、实验电路 五、参考程序 DATA_TH0 EQU 00H DATA_TL0 EQU 00H;信号周期为130ms DATA_TH1 EQU 20H DATA_TL1 EQU 00H;高电平时间65ms ORG 0000H LJMP MAIN ORG 0003H LJMP INT_0;启动电机按键 ORG 000BH LJMP T_0;T0确定输出信号的周期(或者频率)ORG 0013H LJMP INT_1;电机转动方向控制按键 ORG 001BH LJMP T_1;T1确定输出信号高电平的时间期 ORG 0030H MAIN: MOV SP,#60H CLR P1.0 CLR P1.1;关闭电机 setb 20h.0;初始化电机正转 clr 20h.1;初始状态时,电机停止转动 MOV TMOD,#11H SETB IT0 SETB EX0 SETB IT1 SETB EX1 SETB ET0 SETB ET1 SETB EA SJMP $ T_0: JNB 20H.1,T_01; MOV TH1,#DATA_TH1 MOV TL1,#DATA_TL1 SETB TR1 MOV TH0,#DATA_TH0 MOV TL0,#DATA_TL0 SETB TR0 JNB 20H.0,T_02 setb P1.0 clr P1.1 LJMP T_05 T_02: clr P1.0 setb P1.1 LJMP T_05 T_01: CLR P1.0 CLR P1.1 CLR TR0 CLR TR1 RETI CLR TR1 T_05: T_1: clr p1.0 clr p1.1 RETI int_1: CPL 20H.1;电机启动标志求反,开启电机或者关闭电机 JNB 20H.1,INT_11;启动标志不为1,则停止电机,关闭定时器 MOV TH1,#DATA_TH1;启动标志为1,则开启定时器1和定时器2,输出PWM波 MOV TL1,#DATA_TL1 SETB TR1 MOV TH0,#DATA_TH0 MOV TL0,#DATA_TL0 SETB TR0 JNB 20H.0,INT_12;转动方向标志不为1,则反转,否则正转 setb P1.0 clr P1.1 LJMP INT_19 setb P1.1 LJMP INT_19 INT_12: clr P1.0 INT_11: CLR P1.0 CLR P1.1 CLR TR0 CLR TR1 INT_19: RETI 26 INT_0: CPL 20H.0 RETI END 实验八 步进电机控制实验 一、实验目的 1.了解步进电机控制的基本原理。2.掌握步进电机转动编程方法。 二、实验内容 从键盘上输入正、反转命令,转速参数和转动步数显示在显示器上,CPU再读取显示器上显示的正、反转命令,转速级数(16级)和转动步数后执行。转动步数减为零时停止转动。 三、实验电路图 四、参考程序 ORG 0000H ljmp main ORG 000BH LJMP COUNT0 ORG 001BH LJMP COUNT1 ORG 0100H MAIN: MOV P0,#0FFH;输送脉冲口,SETB P1.2;MOV R0,#1;延时变化变量 LOOP1: MOV P0,#0FCH LCALL DELAY MOV P0,#0F6H LCALL DELAY MOV P0,#0F3H LCALL DELAY MOV P0,#0F9H LCALL DELAY JNB P1.2,LOOP2 MOV TMOD,#01010101B MOV TH0,#0FFH MOV TL0,#0FFH MOV TH1,#0FFH MOV TL1,#0FFH SETB TR0 SETB TR1 SETB ET0 SETB ET1 SETB EA MOV DPTR,#TABLE MOV A,R0 MOVC A,@A+DPTR MOV P2,A JMP LOOP1 LOOP2: MOV P0,#0FCH LCALL DELAY MOV P0,#0F9H LCALL DELAY MOV P0,#0F3H LCALL DELAY MOV P0,#0F6H LCALL DELAY JB P1.2,LOOP1 MOV TMOD,#01010101B MOV TH0,#0FFH MOV TL0,#0FFH MOV TH1,#0FFH MOV TL1,#0FFH 28 SETB TR0 SETB TR1 SETB ET0 SETB ET1 SETB EA MOV DPTR,#TABLE MOV A,R0 MOVC A,@A+DPTR MOV P2,A JMP LOOP2 SJMP $ COUNT0: MOV TH0,#0FFH;减速中断 MOV TL0,#0FFH CJNE R0,#9,L4 JMP L5 L4: INC R0 L5: setb TR0 RETI COUNT1: MOV TH1,#0FFH;加速中断 MOV TL1,#0FFH CJNE R0,#1,L6 JMP L7 L6: DEC R0 L7: setb TR1 RETI DELAY: MOV A,R0;延时 MOV R1,A L1: MOV R2,#50 L2: MOV R3,#250 L3: DJNZ R3,L3 DJNZ R2,L2 DJNZ R1,L1 RET TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH;显示程序查表,共阴 END第三篇:单片机实验
第四篇:单片机实验
第五篇:2013单片机实验教案