学 号 10780220
实习报告
起止日期: 2013 年 6 月 24 日 至 2013 年 7 月 19 日
计算机与信息工程学院
20##年 7 月 19 日
目录
第一章 系统开发与调试.............................................. 1
1.1生产实习介绍................................................ 1
1.1.1生产实习的目的......................................... 1
1.1.2生产实习的意义......................................... 1
1.1.3生产实习的重要性....................................... 1
1.2 单片机开发系统介绍.......................................... 2
1.2.1 STC12C5A60S2单片机.................................... 2
1.2.2 LCD1602............................................... 7
1.2.3 系统原理图............................................ 8
1.3单片机开发板的焊接.......................................... 9
1.3.1焊接操作要领及注意事项................................. 9
1.3.2注意事项.............................................. 10
第二章 开发板的调试与检测......................................... 12
2.1开发板硬件调试............................................. 12
2.2开发板软件调试............................................. 12
2.3测试程序................................................... 12
2.3.1流水灯................................................ 12
2.3.2数码管................................................ 13
2.3.3按键控制数码管........................................ 15
2.3.4 LCD1602显示.......................................... 16
2.3.5串口发送.............................................. 21
2.3.6串口接收.............................................. 23
2.3.7 A/D数模转换显示...................................... 25
第三章 开发板拓展应用............................................. 34
3.1利用蜂鸣器弹奏音乐......................................... 34
3.1.1蜂鸣器音调控制原理.................................... 34
3.1.2蜂鸣器弹奏音乐的程序.................................. 34
第四章 开发过程中遇见的问题现象以及解决方法....................... 40
4.1硬件问题................................................... 40
4.2软件问题................................................... 40
第五章 实习体会................................................... 40
第六章 参考文献................................................... 40
1.1生产实习介绍
本次生产实习是学校教务规定,由电子信息工程教研室组织在电信楼实验室进行的一个单片机的开发、生产与应用的实习。此实习的目的旨在理论学习的基础上,通过完成一个涉及51单片机多种资源应用并具有综合功能的最小系统目标板的设计与编程应用,通过我们独立进行单片机开发板的焊接、调试以及应用扩展,提高我们的专业技能,为今后工作或是深造打好坚实的基础,让我们真正从这次实习中收获到对自己有价值的东西。
此次生产实习是将理论知识与实际应用结合起来,从实际出发分析、研究和解决问题,将单片机的知识系统化,而且能对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、纠错、调试、焊接技术相关仪器设备的使用技能方面得到全面的锻炼和提高,为今后独立进行某些单片机应用系统的开发设计打下坚实基础。
生产实习是电子信息工程专业教学计划的一个重要部分,是培养学生理论学习与实践相结合的重要实践性教学环节。通过生产实习使学生了解实习单位的工作方式和工作流程;对以后大单片机课程设计,帝业设计做基础,了解一个开发板的开发制作的整个过程以及元器件的采购;对生产现场、生产过程中的电子信息设备、计算机设备的应用状况有较为深刻的认识,掌握常规电子信息设备的使用维护方法;在实践中进一步加强专业教育,了解本专业工程技术岗位和生产劳动岗位的工作情况和工作内容,培养团队精神和吃苦耐劳的精神;同时可以使学生学到企业的管理经验和工人师傅的艰苦创业精神,激励学生奋发向上的开拓精神。
系统原理及功能介绍
1.2.1 STC12C5A60S2单片机
1.增强型8051 CPU,1T,单时钟/机器周期,指令代码完全兼容传统8051
2.工作电压:STC12C5A60S2系列工作电压:5.5V- 3.3V(5V单片机)STC12LE5A60S2系列工作电压:3.6V- 2.2V(3V单片机)
2.工作频率范围:0 - 35MHz,相当于普通8051的 0~420MHz
3.用户应用程序空间8K /16K / 20K / 32K / 40K / 48K / 52K / 60K / 62K字节......
4.片上集成1280字节RAM 6.通用I/O口(36/40/44个),复位后为:准双向口/弱上拉(普通8051传统I/O口) 可设置成四种模式:准双向口/弱上拉,推挽/强上拉,仅为输入/高阻,开漏 每个I/O口驱动能力均可达到20mA,但整个芯片最大不要超过55mA
5. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器 可通过串口(P3.0/P3.1)直接下载用户程序,数秒即可完成一片
6.有EEPROM功能(STC12C5A62S2/AD/PWM无内部EEPROM)
7. 看门狗
8.内部集成MAX810专用复位电路(外部晶体12M以下时,复位脚可直接1K电阻到地)
9.外部掉电检测电路:在P4.6口有一个低压门槛比较器5V单片机为1.32V,误差为+/-5%,3.3V单片机为1.30V,误差为+/-3%
10.时钟源:外部高精度晶体/时钟,内部R/C振荡器(温漂为+/-5%到+/-10%以内) 1用户在下载用户程序时,可选择是使用内部R/C振荡器还是外部晶体/时钟常温下内部R/C振荡器频率为:5.0V单片机为:11MHz~15.5MHz 3.3V单片机为: 8MHz~12MHz 精度要求不高时,可选择使用内部时钟,但因为有制造误差和温漂,以实际测试为准
11.共4个16位定时器 两个与传统8051兼容的定时器/计数器,16位定时器T0和T1,没有定时器2,但有独立波特率发生器做串行通讯的波特率发生器再加上2路PCA模块可再实现2个16位定时器
12. 2个时钟输出口,可由T0的溢出在P3.4/T0输出时钟,可由T1的溢出在P3.5/T1输出时钟
13.外部中断I/O口7路,传统的下降沿中断或低电平触发中断,并新增支持上升沿中断的PCA模块,Power Down模式可由外部中断唤醒,INT0/P3.2, INT1/P3.3, T0/P3.4, T1/P3.5, RxD/P3.0, CCP0/P1.3(也可通过寄存器设置到P4.2 ), CCP1/P1.4 (也可通过寄存器设置到P4.3)
14. PWM(2路)/PCA(可编程计数器阵列,2路)也可用来当2路D/A使用-也可用来再实现2个定时器也可用来再实现2个外部中断(上升沿中断/下降沿中断均可分别或同时支持)
15.A/D转换, 10位精度ADC,共8路,转换速度可达250K/S(每秒钟25万次) 18.通用全双工异步串行口(UART),由于STC12系列是高速的8051,可再用定时器或PCA软件实现多串口
16. STC12C5A60S2系列有双串口,后缀有S2标志的才有双串口,RxD2/P1.2(可通过寄存器设置到P4.2),TxD2/P1.3(可通过寄存器设置到P4.3)
16.工作温度范围:-40 - +85℃(工业级) / 0 - 75℃(商业级)
17.封装: PDIP-40,LQFP-44,LQFP-48 I/O口不够时,可用2到3根普通I/O口线外接 74HC164/165/595(均可级联)来扩展I/O口, 还可用A/D做按键扫描来节省I/O口,或用双CPU,三线通信,还多了串口。
STC12C5A60S2 为可电气烧录清洗的 8051 相容单芯片,其内部程序代码容量为4KB
STC12C5A60S2主要功能列举如下:
1、为一般控制应用的 8 位单芯片
2、晶片内部具时钟振荡器(传统最高工作频率可至 12MHz)
3、内部程式存储器(ROM)为 4KB
4、内部数据存储器(RAM)为 128B
5、外部程序存储器可扩充至 64KB
6、外部数据存储器可扩充至 64KB
7、32 条双向输入输出线,且每条均可以单独做 I/O 的控制
8、5 个中断向量源
9、2 组独立的 16 位定时器
10、1 个全多工串行通信端口
11、8751 及 8752 单芯片具有数据保密的功能
12、单芯片提供位逻辑运算指令
STC12C5A60S2
STC12C5A60S2各引脚功能介绍:
VCC:
STC12C5A60S2 电源正端输入,接+5V。
VSS:
电源地端。
XTAL1:
单芯片系统时钟的反相放大器输入端。
XTAL2:
系统时钟的反相放大器输出端,一般在设计上只要在 XTAL1 和 XTAL2 上接上一只石英振荡晶体系统就可以动作了,此外可以在两引脚与地之间加入一 20PF 的小电容,可以使系统更稳定,避免噪声干扰而死机。
RESET:
STC12C5A60S2的重置引脚,高电平动作,当要对晶片重置时,只要对此引脚电平提升至高电平并保持两个机器周期以上的时间,AT89S51便能完成系统重置的各项动作,使得内部特殊功能寄存器之内容均被设成已知状态,并且至地址0000H处开始读入程序代码而执行程序。
EA/Vpp:
"EA"为英文"External Access"的缩写,表示存取外部程序代码之意,低电平动作,也就是说当此引脚接低电平后,系统会取用外部的程序代码(存于外部EPROM中)来执行程序。因此在8031及8032中,EA引脚必须接低电平,因为其内部无程序存储器空间。如果是使用 8751 内部程序空间时,此引脚要接成高电平。此外,在将程序代码烧录至8751内部EPROM时,可以利用此引脚来输入21V的烧录高压(Vpp)。
ALE/PROG:
ALE是英文"Address Latch Enable"的缩写,表示地址锁存器启用信号。STC12C5A60S2可以利用这支引脚来触发外部的8位锁存器(如74LS373),将端口0的地址总线(A0~A7)锁进锁存器中,因为STC12C5A60S2是以多工的方式送出地址及数据。平时在程序执行时ALE引脚的输出频率约是系统工作频率的1/6,因此可以用来驱动其他周边晶片的时基输入。此外在烧录8751程序代码时,此引脚会被当成程序规划的特殊功能来使用。
PSEN:
此为"Program Store Enable"的缩写,其意为程序储存启用,当8051被设成为读取外部程序代码工作模式时(EA=0),会送出此信号以便取得程序代码,通常这支脚是接到EPROM的OE脚。AT89S51可以利用PSEN及RD引脚分别启用存在外部的RAM与EPROM,使得数据存储器与程序存储器可以合并在一起而共用64K的定址范围。
PORT0(P0.0~P0.7):
端口0是一个8位宽的开路汲极(Open Drain)双向输出入端口,共有8个位,P0.0表示位0,P0.1表示位1,依此类推。其他三个I/O端口(P1、P2、P3)则不具有此电路组态,而是内部有一提升电路,P0在当做I/O用时可以推动8个LS的TTL负载。如果当EA引脚为低电平时(即取用外部程序代码或数据存储器),P0就以多工方式提供地址总线(A0~A7)及数据总线(D0~D7)。设计者必须外加一锁存器将端口0送出的地址栓锁住成为A0~A7,再配合端口2所送出的A8~A15合成一完整的16位地址总线,而定址到64K的外部存储器空间。
PORT2(P2.0~P2.7):
端口2是具有内部提升电路的双向I/O端口,每一个引脚可以推动4个LS的TTL负载,若将端口2的输出设为高电平时,此端口便能当成输入端口来使用。P2除了当做一般I/O端口使用外,若是在STC12C5A60S2扩充外接程序存储器或数据存储器时,也提供地址总线的高字节A8~A15,这个时候P2便不能当做I/O来使用了。
PORT1(P1.0~P1.7):
端口1也是具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个LS TTL负载,同样地若将端口1的输出设为高电平,便是由此端口来输入数据。如果是使用8052或是8032的话,P1.0又当做定时器2的外部脉冲输入脚,而P1.1可以有T2EX功能,可以做外部中断输入的触发脚位。
PORT3(P3.0~P3.7):
端口3也具有内部提升电路的双向I/O端口,其输出缓冲器可以推动4个TTL负载,同时还多工具有其他的额外特殊功能,包括串行通信、外部中断控制、计时计数控制及外部数据存储器内容的读取或写入控制等功能。
其引脚分配如下:
P3.0:RXD,串行通信输入。
P3.1:TXD,串行通信输出。
P3.2:INT0,外部中断0输入。
P3.3:INT1,外部中断1输入。
P3.4:T0,计时计数器0输入。
P3.5:T1,计时计数器1输入。
P3.6:WR:外部数据存储器的写入信号。
P3.7:RD,外部数据存储器的读取信号。
STC12C5A60S2实体图
1.2.2 LCD1602
简介
1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
市面上字符液晶大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
管脚功能
1602采用标准的16脚接口,其中:
第1脚:VSS为电源地
第2脚:VCC接5V电源正极
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会 产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。
第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极
LCD1602管脚图
特性
3.3V或5V工作电压,对比度可调
内含复位电路
提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能
有80字节显示数据存储器DDRAM
内建有192个5X7点阵的字型的字符发生器CGROM
8个可由用户自定义的5X7的字符发生器CGRAM
1.2.3 系统原理图
图1系统原理图
焊接操作要领
1.焊件表面处理
一般在焊接前焊件需要进行表面清理工作,去除焊接面上的锈迹,油污,灰尘等影响焊接质量的杂质。手工操作中常用机械刮磨和酒精,丙酮擦洗等简单易行的方法。
2.预焊
预焊就是将要锡焊的元器件引线或导电的焊接部位预先用焊锡润湿,一般也称为镀锡,上锡,搪锡等,靠金属的扩散形成结合层后而使焊件表面“镀”上一层焊锡。
预焊并非锡焊不可缺少的操作,但对手工烙铁焊接特别是维修,调试,研制工作几乎可以说是必不可少的。
3.不要用过量的焊剂
适量的焊剂是必不可缺的,但不要认为越多越好。过量的松香不仅造成焊后焊点周围需要清洗的工作量,而且延长了加热时间(松香融化,挥发需要并带走热量),降低工作效率;而当加热时间不足时又容易夹杂到焊锡中形成“夹渣”缺陷;对开关元件的焊接,过量的焊剂容易流到触点处,从而造成接触不良。
合适的焊剂量应该是松香水仅能浸湿将要形成的焊点,不要让松香水透过印制板流到元件面或插座孔里(如IC插座)。对使用松香芯的焊丝来说,基本不需要再涂焊剂。
4. 保持烙铁头的清洁
因为焊接时烙铁头长期处于高温状态,又接触焊剂等受热分解的物质,其表面很容易氧化而形成一层黑色杂质,这些杂质几乎形成隔热层,使烙铁头失去加热作用。因此要随时在烙铁架上蹭去杂质。用一块湿布或湿海绵随时擦烙铁头,也是常用的方法。
5. 加热要靠焊锡桥
非流水线作业中,一次焊接的焊点形状使多种多样的,我们不可能不断换烙铁头。要提高烙铁头加热的效率,需要形成热量传递的焊锡桥。所谓焊锡桥,就是靠烙铁上保留少量焊锡作为加热时烙铁头与焊件之间传热的桥梁。
显然由于金属液的导热效率远高于空气,而使焊件很快被加热到焊接温度,如图四。应注意作为焊锡桥的锡保留量不可过多。
6. 焊锡量要合适
过量的焊锡不但毫无必要地消耗了较贵的锡,而且增加了焊接时间,相应降低了工作速度。更为严重的是在高密度的电路中,过量的锡很容易造成不易察觉的短路。
但是焊锡过少不能形成牢固的结合,降低焊点强度,特别是在板上焊导线时,焊锡不足往往造成导线脱落。
7. 焊件要牢固
在焊锡凝固之前不要使焊件移动或振动,特别使用镊子夹住焊件时一定要等焊锡凝固再移去镊子。这是因为焊锡凝固过程是结晶过程,根据结晶理论,在结晶期间受到外力(焊件移动)会改变结晶条件,导致晶体粗大,造成所谓“冷焊”。外观现象是表面无光泽呈豆渣状;焊点内部结构疏松,容易有气隙和裂隙,造成焊点强度降低,导电性能差。因此,在焊锡凝固前一定要保持焊件静止,实际操作时可以用各种适宜的方法将焊件固定,或使用可靠的夹持措施。
8. 烙铁撤离有讲究
烙铁处理要及时,而且撤离时的角度和方向对焊点形成有一定关系。
撤烙铁时轻轻旋转一下,可保持焊点适当的焊料,这需要在实际操作中体会。
电子元器件插装的原则
插装的顺序 :先低后高,先小后大,先轻后重。
元器件的标识 :电子元器件的标记和色码部位应朝上,以便于辩认;横向插件的数值读法应从左至右,而竖向插件的数值读法则应从下至上。
元器件的间距在印制板上的元器件之间的距离不能小于1mm;引线间距要大于2mm(必要时,引线要套上绝缘套管)。一般元器件应紧密安装,使元器件贴在印制板上,紧贴的容限在0.5mm左右。
1.3.2注意事项
锡线是手工焊接电路板,最便捷的焊料,由于大部分锡线内含松香等助焊剂,使用锡线可以减少工序,提高焊接作业的效率;锡线按其金属成分可分为无铅焊锡和有铅焊锡,成分区别的锡线具有区别的熔点,用途亦各有区别。在使用的时候,必须符合相关的安全规定;只能由合格的技术人维修;如果不这样,在使用本设备的时候,可能导致意外事故。
运作以前,用锡线测温计先测定温度很重要。使用热回复性等热性能好的锡线,在使用无铅焊锡进行焊接作业时,由于对零件的耐热性,安全作业的考虑,有必要选定最合适的锡线,根据了解电烙铁的区别焊接作业的区别,选择最合适的烙铁头是很重要的。合适的烙铁头可以降低烙铁头的温度,增加作业的效率。烙铁头的维护也非常重要。
当心焊料烫伤,当心被飞溅的溶液状态的焊料烫伤。穿防护服避免烫伤。通过戴防护罩方式来保护眼睛。在焊接或拆焊过程中使用胶粘剂的时候,尤其要注意胶粘剂生产厂家的警告信息。如果配合空气净化器使用,必须确保空气净化器连接正常并处于正常的运作状态。不整洁的运作区间会增加意外事故发生的可能性。在不使用本设备的时候,请将本设备放回安全的地方。避免所有易燃物体靠近热的焊笔,包括气体和固体。
即使在关断电源或者取下烙铁头及套筒后,烙铁头和套筒仍然需要一段时间冷却。在焊接结束后,焊点及被焊接元器件仍然非常热。防止被电击,不要用手接触接地部位,如焊笔套筒,发热体等。儿童及未受培训的人不能靠近运作区间,绝不能允许其他未受培训的人使用或触摸电源线。
第二章 开发板的调试与检测
2.1开发板硬件调试
根据完成的电路板实现程序运行前,对电路板先进行检测,先测试开发板供电是否正常,插上电源看看供电指示灯是否正常点亮。然后再在程序的调试中测试个电路模块和器件是否能正常使用,这样以便快速准确找出错误并解决错误。例如首先可以测试电阻、二极管极性是否焊反,芯片有没出现虚焊的现象,以至于板子不能正常使用。
2.2开发板软件调试
STC12C5A60S2单片机可以实现多种的实验程序,例如LED指示灯实验;跑马灯实验;中断操作;A/D转换;按键输入实验等。调试过程中我们用的是Keil uvision2软件,其操作步骤如下:
(1)建立一个文件夹用来存放项目。
(2)(2)打开Keil软件,选择Project->New Project。
(3)选择Atmel->AT89S52->同意添加8051启动代码。
(4)(4)File->New (新建源文件,编程)->保存(汇编语言以.asm结尾;C语言以.C结尾)
(5)添加源文件到Project。
(6)生成.hex文件。
2.3测试程序
2.3.1流水灯
#include<reg51.h>
typedef unsigned int uint16;
//#define time 100
/*void ms (unsigned int x)
{
unsigned char i;
while(x--)
{
for(i=0;i<200;i++);
}
}*/
main()
{
int j,a1;
uint16 x;
//for(i=0;i<2;i++)
while(1)
{
a1=0xfe;
for(j=0;j<8;j++)
{
P1=a1;
//ms(time);
for(x=0;x<50000;x++);
P1=0xff;
for(x=0;x<50000;x++);
P1=a1;
for(x=0;x<60000;x++);
a1=(a1<<1)|0x01;
}
}
}
2.3.2数码管
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void Delay(uint del)
{
uint i,j,k;
for(i=0; i<del; i++)
for(j=0; j<1000; j++)
for(k=0; k<1000; k++)
;
}
void main (void)
{
int i;
P1=0x00;//数码管点亮控制
while(1)
{
for(i=0;i<2;i++)
{
P0 = 0xfe;
Delay(1);
P0 = 0xfd;
Delay(1);
P0 = 0xfb;
Delay(1);
P0 = 0xf7;
Delay(1);
P0 = 0xef;
Delay(1);
P0 = 0xdf;
Delay(1);
P0 = 0xbf;
Delay(1);
P0 = 0x7f;
Delay(1);
}
for(i=0;i<2;i++)
{
P0 = 0x7f;
Delay(1);
P0 = 0xbf;
Delay(1);
P0 = 0xdf;
Delay(1);
P0 = 0xef;
Delay(1);
P0 = 0xf7;
Delay(1);
P0 = 0xfb;
Delay(1);
P0 = 0xfd;
Delay(1);
P0 = 0xfe;
Delay(1);
}
for(i=0;i<2;i++)
{
P0=0x00;
Delay(1);
P0=0xff;
Delay(1);
}
}
}
2.3.3按键控制数码管
#ifndef _ANJIAN_H_
#define _ANJIAN_H_
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef char int8;
typedef int int16;
sbit K0=P1^0;
sbit K1=P1^1;
sbit K2=P1^2;
sbit K3=P1^3;
sbit K4=P1^4;
sbit K5=P1^5;
sbit K6=P1^6;
sbit K7=P1^7;
sbit WL1=P2^3;
sbit WL2=P2^2;
sbit WL3=P2^1;
sbit WL4=P2^0;
#endif
2.3.4 LCD1602显示
#include "reg51.h"
#include"absacc.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
/* 液晶1602口地址 */
#define wr_com XBYTE[0xC000] //写命令
#define wr_data XBYTE[0xC100] //写数据
#define rd_com XBYTE[0xC200] //读命令
#define rd_data XBYTE[0xC300] //读数据
void lcd_init(void); // lcd初始化
void write_cmd(BYTE cmd); // lcd写命令
//void write_string(unsigned char *s); // 写字符串
void write_data(BYTE dat) ; // 写数据
void set_display_place(BYTE line,column);
void write_string_lcd(BYTE line,column,unsigned char *string);
//void write_data_lcd(BYTE line,column,dat);
//void crti(unsigned long dat);
//void crt_r(float x,BYTE N);
void Delay(WORD n)
{
WORD x;
while(n--)
{
x=500;
while(x--);
}
}
/*
void Delay2(WORD n)
{
WORD x;
while(n--)
{
x=5000;
while(x--);
}
}
*/
/************************************************************************
Function name: write_cmd
Descriptions: 向lcd输入指令
************************************************************************/
void write_cmd(BYTE cmd)
{
BYTE dl;
do {
dl=rd_com;
} while((dl&0x80)!=0); //判忙
wr_com= cmd;
Delay(1);
}
/**********************************************************************
Function name: write_data
Descriptions: 写入数据
**********************************************************************/
void write_data(BYTE dat)
{
BYTE dl;
do {
dl=rd_com;
} while((dl&0x80)!=0); //判忙
wr_data= dat;
Delay(1);
}
/***********************************************************************
Function name: write_string
Descriptions: 写入字符串
***********************************************************************/
void write_string(BYTE *s)
{
while(*s != '\0') //'\0'为字符串结束标志
{
write_data(*s);
s++;
}
}
/**********************************************************************
Function name: set_display_place
Descriptions: 设置字符的显示位置
**********************************************************************/
void set_display_place(BYTE line,column)
{
BYTE address;
if(line == 1)
{
address = 0x80 + column;
}
else if(line == 2)
{
address = 0xc0 + column;
}
write_cmd(address);
}
/*******************************************************************
Function name: 将字符串写到指定的位置
Descriptions: 将字符串显示在lcd的特定位置
*******************************************************************/
void write_string_lcd(BYTE line,column,unsigned char *string)
{
set_display_place(line,column);
write_string(string);
Delay(1);
}
/******************************************************************
Function name: 将字符写到指定的位置
Descriptions: 将字符串显示在lcd的特定位置
*******************************************************************/
/*void write_data_lcd(BYTE line,column,dat)
{
set_display_place(line,column);
write_data(dat);
Delay(1);
}
*/
/***************************************************
************液晶模块初始化******************************
****************************************************/
void lcd_init(void)
{
write_cmd(0x38);//
write_cmd(0x38);//
write_cmd(0x06);//
write_cmd(0x0c);//
write_cmd(0x01);//
}
/*****************LED显示位置********************/
void main()
{
//SP=0x60;
lcd_init();
while(1)
{write_string_lcd(1,1," 0123456789 ");
write_string_lcd(2,1," ABCDEDGHIJ ");
}
}
2.3.5串口发送
/*串行发送*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit K0=P1^0;
sbit K4=P1^4;
uchar Operation_No=0; //操作代码
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //数码管代码
void delay(uint ms)
{
uchar i;
while(ms--);
for(i=0;i<120;i++);
}
//向串口发送字符
void Putc_to_SerialPort(uchar c)
{
SBUF=c;
while(TI==0); //收到时中断
TI=0; //清除中断
}
void uart_init()
{
SCON=0x50; //串口模式1,允许接收
TMOD=0x20; //T1工作模式2
PCON=0x00; //波特率不倍增
TH1=0xfd; //设置计数初值
TL1=0xfd;
TI=RI=0;
TR1=1; //启动定时器
IE=0x90; //允许串口中断
}
main()
{
uart_init();
K4=0;
LED1=LED2=1;
while(1)
{
delay(100);
if(K0==0)
{
while(K0==0)
Operation_No=(Operation_No+1)%4;
switch(Operation_No) //根据操作代码发送A/B/C或停止发送
{
case 0: Putc_to_SerialPort('X');
LED1=LED2=1;
break;
case 1: Putc_to_SerialPort('A');
LED1=~LED1;LED2=1;
break;
case 2: Putc_to_SerialPort('B');
LED2=~LED2;LED1=1;
break;
case 3: Putc_to_SerialPort('C');
LED1=~LED1;LED2=LED1;
break;
}
}
}
}
void uart_interrupt() interrupt 4
{
if(RI)
{
RI=0;
if(SBUF>=0&&SBUF<=10)
P0=DSY_CODE[SBUF];
else
P0=0x00;
}
}
2.3.6串口接收
/*串行接收*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit K0=P1^0;
sbit K4=P1^4;
uchar numx=-1;
void delay(uint ms)
{
uchar i;
while(ms--);
for(i=0;i<120;i++);
}
void uart_init()
{
SCON=0x50; //串口模式1,允许接收
TMOD=0x20; //T1工作模式2
TH1=0xfd; //波特率9600
TL1=0xfd;
PCON=0x00; //波特率不倍增
RI=0;
TI=0;
TR1=1; //启动定时器
IE=0x90; //允许中断
}
main()
{
uart_init();
K4=0;
while(1)
{
delay(100);
if(K0==0)
{
while(K0==0);
numx=(numx+1)%11;
SBUF=numx;
while(TI==0);
TI=0;
}
}
}
void uart_interrupt() interrupt 4
{
if(RI)
{
RI=0;
switch(SBUF)
{
case 'X':LED1=LED2=1;break;
case 'A':LED1=0;LED2=1;break;
case 'B':LED2=0;LED1=1;break;
case 'C':LED1=LED2=0;
}
}
2.3.7 A/D数模转换显示
#include "reg51.h"
#include "intrins.h"
#include"absacc.h"
#include"math.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
/* AD .......... */
sfr P1ASF = 0x9D; //P1 ................
sfr ADC_CONTR = 0xBC; //AD ..........
sfr ADC_RES = 0xBD; //AD ............
sfr ADC_RESL = 0xBE; //AD ............
sfr AUXR1 = 0xA2; //AD ..............
#define ADC_POWER 0x80 //AD ............
#define ADC_FLAG 0x10 //AD ..........
#define ADC_START 0x08 //AD ..........
#define ADRJ1 0x40 //AD ............ 2 ..+.. 8 ..
#define ADC_SPEEDLL 0x00 //AD ..............540 ..........
#define ADC_SPEEDL 0x20 //AD ..............360 ..........
#define ADC_SPEEDH 0x40 //AD ..............180 ..........
#define ADC_SPEEDHH 0x60 //AD ..............90 ..........
/* .... 1602 ...... */
#define wr_com XBYTE[0xC000] //......
#define wr_data XBYTE[0xC100] //......
#define rd_com XBYTE[0xC200] //......
#define rd_data XBYTE[0xC300] //......
unsigned char ah;
unsigned char AD_val_h; //AD ............
unsigned char AD_val_l; //AD ............
unsigned long AD_val;
float AD_float;
void InitADC();
void SendData(BYTE dat);
//void GetADCResult(BYTE ch);
void Delay(WORD n);
void Delay2(WORD n);
void ShowResult(BYTE ch);
void lcd_init(void); // lcd ......
void write_cmd(BYTE cmd); // lcd ......
//void write_string(unsigned char *s); // ........
void write_data(BYTE dat) ; // ......
void set_display_place(BYTE line,column);
void write_string_lcd(BYTE line,column,unsigned char *string);
/********************************************************************
Function name: write_cmd
Descriptions: .. lcd ........
********************************************************************/
void write_cmd(BYTE cmd)
{
BYTE dl;
do {
dl=rd_com;
} while((dl&0x80)!=0); //....
wr_com= cmd;
Delay(1);
}
/*******************************************************************
Function name: write_data
Descriptions: ........
*******************************************************************/
void write_data(BYTE dat)
{
BYTE dl;
do {
dl=rd_com;
} while((dl&0x80)!=0); //....
wr_data= dat;
Delay(1);
}
/********************************************************************
Function name: write_string
Descriptions: ..........
********************************************************************/
void write_string(BYTE *s)
{
while(*s != '\0') //'\0'................
{
write_data(*s);
s++;
}
}
/***************************************************************
Function name: set_display_place
Descriptions: ..................
**************************************************************/
void set_display_place(BYTE line,column)
{
BYTE address;
if(line == 1)
{
address = 0x80 + column;
}
else if(line == 2)
{
address = 0xc0 + column;
}
write_cmd(address);
}
/*****************************************************************
Function name: ......................
Descriptions: .............. lcd ..........
*****************************************************************/
void write_string_lcd(BYTE line,column,unsigned char *string)
{
set_display_place(line,column);
write_string(string);
Delay(1);
}
/***************************************************
************..............******************************
****************************************************/
void lcd_init(void)
{
write_cmd(0x38);//
write_cmd(0x38);//
write_cmd(0x06);//
write_cmd(0x0c);//
write_cmd(0x01);//
}
void crti(unsigned long dat)
{
unsigned char dhi;
unsigned char dli;
unsigned char ddi;
unsigned char dei;
unsigned long datah;
unsigned long datal;
datah=dat;
dhi=0;
if (datah>=10)
{
do
{
datah/=10;
dhi++;
}while(datah>=10);
datah=dat;
ddi=dhi;
for (dli=0;dli<dhi;dli++)
{
datal=1;
for (dei=0;dei<ddi;dei++)
{
datal*=10;
}
datah=dat/datal;
dat=dat%datal;
datah+=0x30;
write_data(datah);
ddi--;
}
dat+=0x30;
write_data(dat);
}
else
{
dat=dat+0x30;
write_data(dat);
}
}
/*****************..........****************/
void crt_r(float x,unsigned char N)
{
unsigned char dli;
unsigned int dath;
unsigned int dat;
if (x<0.0)
{
dat=0x2d;
write_data(dat);
Delay(1);
x=fabs(x);
}
dath=(int)x;
crti(dath);
if (N>0)
{
dat=0x2e;
write_data(dat);
Delay(1);
dat=1;
for (dli=0;dli<N;dli++)
{
dat*=10;
}
dath=(int)(x*dat)-dath*dat;
crti(dath);
}
}
void crt_U()
{
write_string_lcd(2,0, "U:");
set_display_place(2,3);
crt_r(AD_float,3);
}
void GetADCResult(BYTE ch) //AD ....
{
AUXR1 &=~ADRJ1;
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG));
ADC_CONTR &=~ADC_FLAG;
AD_val_h=ADC_RES;
AD_val_l=ADC_RESL;
AD_val=AD_val_h*4+AD_val_l;
}
void InitADC()
{
P1ASF=0xff;
ADC_RES=0;
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
Delay(1);
}
void Delay(WORD n)
{
WORD x;
while(n--)
{
x=500;
while(x--);
}
}
void Delay2(WORD n)
{
WORD x;
while(n--)
{
x=5000;
while(x--);
}
}
void main()
{
SP=0x60;
InitADC();
lcd_init();
AUXR1 &=~ADRJ1;
while(1)
{
write_string_lcd(1,2, "P1.7");
GetADCResult(7);
AD_float=AD_val*5.0/1024.0;
crt_U();
Delay2(10);
}
}
第三章 开发板拓展应用
3.1利用蜂鸣器弹奏音乐
3.1.1蜂鸣器音调控制原理
通过调整PWM的占宽比来实现蜂鸣器的音调控制,并通过LED灯的点亮来模拟音调的高低,高音灯亮的多,低音灯亮的少。
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。
脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。
与占宽比对应的是占空比,占宽比是高电平的时间在整个一个周期内所占时间的比重。占宽比越高,通电时间越长,所产生的音调越高,而与之相反,占空比越高,音调越低,所以把不同的占宽比设定为特殊的音阶,就能实现音乐的播放,由于方波与蜂鸣器,所以产生的音乐不是很好,音调比较尖锐。
3.1.2蜂鸣器弹奏音乐的程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar Count;
sbit Speak =P1^2; //蜂鸣器器控制脚
sbit P36=P3^6;
sbit RS=P2^5;
unsigned char code LED[8]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};
/*以下数组是音符编码*/
unsigned char code SONG[] ={ //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
//路边的野华不要采
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,
0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,
0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,
0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,
0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,
};
/********************************************************************
* 名称 : Time0_Init()
* 功能 : 定时器的初始化,定时时间可用光碟中软件计算,11.0592MZ晶振,10ms
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Init()
{
TMOD = 0x01;
IE = 0x82;
TH0 = 0xDC;
TL0 = 0x00;
}
/********************************************************************
* 名称 : Time0_Int()
* 功能 : 定时器中断,中断中实现 Count 加一
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TH0 = 0xDC;
TL0 = 0x00;
Count++; //长度加1
}
/********************************************************************
* 名称 : Delay_xMs()
* 功能 : 延时子程序,经过软件调试,测得延时程序大概为55us.
* 输入 : x
* 输出 : 无
***********************************************************************/
void Delay_xMs(uint x)
{
uint i,j;
for(i=0; i<x; i++)
{
for(j=0; j<3; j++);
}
}
/********************************************************************
* 名称 : Play_Song()
* 功能 : 播放蜂鸣器控制程序
* 输入 : i (选择播放哪首歌曲,0为“祝你平安”,1为“路边的野花你不要采”
* 输出 : 无
***********************************************************************/
void Play_Song(uchar i)
{
uchar Temp1,Temp2;
int a;
uint Addr;
Count = 0; //中断计数器清0
Addr = i * 217;
while(1)
{
Temp1 = SONG[Addr++]; //音符地址加一
if (Temp1 == 0xFF) //休止符
{
TR0 = 0;
Delay_xMs(100);
}
else if (Temp1 == 0x00) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[Addr++]; //街拍地址加一 注释: 音符地址始终是偶数 节拍地址是奇数
TR0 = 1;
while(1)
{
Speak = ~Speak; //音符① 这两句话是确定音符的
a=(int)(Temp1/8); // LED 一 有音符判断LED亮多少
if(a>=0&&a<8)
P0=LED[a]; // LED 二 让LED亮相应的个数
else (P0=0xfc);
Delay_xMs(Temp1); //音符② 一二组合确定音符
if(Temp2 == Count) //有Temp2 判断节拍
{
Count = 0;
break;
}
}
}
}
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
RS=1;
P36=0;
Time0_Init(); //定时器0中断初始化
while(1)
{
Play_Song(0); //Play_Song(0)为祝你平安 Play_Song(1)为路边的野花你不要裁
Play_Song(1);
}
第四章 开发过程中遇见的问题现象以及解决方法
4.1硬件问题
数码管显示少一个,四个只有3个显示,最后重新拿焊锡补了下发现虚焊,经过调试发现无误。
测试LCD1602显示的时候字体全是黑框,怎么往外拧都是黑的,然后把可变电阻往里拧了次,发现居然变暗了,显示出了字体。
4.2软件问题
最后扩展的时候,蜂鸣器音乐演奏没问题,但是LED灯显示功放大小的显示,出现了问题,后来发现,是设定音阶的时候出现了问题,更正已无误
第五章 实习体会
通过这次实习,我们通过手动的焊接,虽然以前焊接过万用表,但是这个板子明显比那个万用表复杂许多,而且,单片机的板子各种焊接都才尝试了,如底座,针脚与插板还有贴片的焊接。而软件测试则实现了许多功能,以前只能在书本上的知识得到了实现、编辑以及应用,从而带动了我们的兴趣。让我们对于本专业有了更深的理解,和对于前进的方向有了明确的认识,让我们对自己的未来有着充分的信心。
第六章 参考文献
[1] 张毅刚等.单片机原理机应用[M].高等教育出版社,2008
[2] 何立民主编.MCS-51单片机原理机应用系统设计.北京航空航天大学出版社,1990
[3] 涂时亮,单片机软件设计技术.重庆:科学文献出版社重庆分社,1987
[4]李广弟等.单片机基础[M].北京航空航天出版社,2001.
[5]王东峰等.单片机C语言应用100例[M].电子工业出版社,2009.
[6]陈海宴.51单片机原理及应用[M].北京航空航天大学出版社,2010.
[7]刘守义等.单片机技术基础[M].西安电子科技大学出版社,2007.
[8]钟富昭等.8051单片机典型模块设计与应用[M].人民邮电出版社,2007.
[9]李平等.单片机入门与开发[M].机械工业出版社,2008.
测控技术与仪器生产实习说明目录前言2实习制作任务书3第1章方案的论证4第2章硬件的焊接5第3章芯片的介绍531单片机STC89C5…
燕山大学单片机生产实习报告一、生产实习的目的和意义:生产实习是培养本科学生理论联系实际,提高实际动手操作能力的重要教学环节。本专业…
学号10780220实习报告生产实习起止日期20xx年6月24日至20xx年7月19日学班成生姓名岳维启级电子信息科学与技术2班绩…
学号实习报告生产实习起止日期20xx年6月24日至20xx年7月19日学班成生姓名级绩10电信科1班指导教师签字计算机与信息工程学…
电子工艺实习总结报告姓专班学名业机械电子工程级机电102号指导教师成一实习目的与要求绩1切实培养单片机应用系统的实践设计开发能力采…
桂林电子科技大学职业技术学院单片机实训报告红外遥控学院系电子信息工程系专业电子信息工程技术学号1212220xx7学生姓名李建军指…
目录一概述11设计制作产品的背景目的意义12设计制作产品的设计要求13分工情况工作计划及本人所总结工作14本课题的基本内容重点及难…
温度控制系统设计目名院业级号导教师基于51单片机的温度控制系统设计王金辉王涌工学院自动化自动化919xxxxxxxxxxxx910…
51姓名单片机实习报告学院电气与控制工程学院专业班级学号目录一前言二实训的目的及要求三实训原理四硬件的安装与调试五软件部分六系统测…
为期四周的单片机实习结束了,回忆起这次实习的经历,自己感到受益匪浅,收获颇丰。通过对单片机小系统的设计、焊接、装配,掌握电路原理图…