第4脚VDD,第5脚GND,请问这是什么型号的单片机

国内销售专线:2 / 8
在线QQ咨询:
拨打销售专线:
联系邮箱:
公司传真:
&& 液晶屏(LCD)
连接方式:PIN
外形尺寸:130*62*2.2
有效区尺寸:127*55
显示方式:stn
驱动模式:1/4duty,1/3bias,5v
视角方向:6 o'clock
运行温度:-20 ℃---+70 ℃
储存温度:-40 ℃----+80 ℃
编号:JDL0414M03
背光源:LED
工艺类别:COB
外形尺寸:100*61*9
可视区尺寸:57*49
点阵数:4COM X 14SEG
控制器:HT1621
背光颜色:白色侧背光
LCD特性:STN 蓝膜,负显,全透,6H
是否共用模组:否
模块类型:笔段液晶模块
产品别名:0414模块、0414液晶模块
连接方式:PIN
外形尺寸:52.5*38*2.8
有效区尺寸:44.5*35.5
显示方式:HTN
驱动模式:静止驱动,5v
视角方向:6 o'clock
运行温度:-30 ℃---+80 ℃
储存温度:-40 ℃----+90 ℃
连接方式:PIN
外形尺寸:103*25*2.85
有效区尺寸:100*20
显示方式:TN
驱动模式:5v
视角方向:6 o'clock
运行温度:-20 ℃---+70 ℃
储存温度:-30 ℃----+80 ℃
显示效果图
连接方式:PIN
外形尺寸:57*40*2.8
有效区尺寸:56*34
显示方式:HTN
驱动模式:1/4DUTY,1/3BIAS,5v
视角方向:6 o'clock
运行温度:-20 ℃---+70 ℃
储存温度:-30 ℃----+80 ℃
LCM编号:0417E00
背 光 源:LED(白色 IMAX=40mA)
工艺类别:COB
外形尺寸:158*50.5*11.5
可视区尺寸:84.2*32
视角方向:12 o'clock
LCD显示模式:HTN,全透,负显
控制器:PCF8576&
驱动方式:1/4DUTY, 1/3BIAS,VOP 4.5V,VDD5.0V
第1脚:SDL
第2脚:SCL
第3脚:VDD
第4脚:GND
第5脚:VLCD
第6脚:LEDA
第7脚:LEDK
产品介绍:&
1. DRIVE METHOD:1/1DUTY, 1/1BIAS,VOP 4.5V,VDD 5V
2. VIEWING ANGLE:12'CLOCK
3. DISPLAY TYPE:TN,TRANSMISSIVE/NEGATIVE.
4. OPERATING TEMP: -20°C TO +70°C
5. STORAGE TEMP: -30°C TO +80°C
6. BACKLIGHT: RED&
是否公用模组:否&
模块类型:笔段式
产品别名:0417段码液晶显示屏、LCD显示屏、0417液晶显示屏、段显LCD显示屏
发布时间:
产品结构视图
LCD编号:0418O04
连接方式:PIN
外形尺寸:92.5*43.5*9.5&&&
有效区尺寸:78*33
LCD属性:HTN,全透,负性,12点
产品别名:0418段码液晶显示屏、LCD显示屏、0418液晶显示屏、段显LCD显示屏
连接方式:PIN
外形尺寸:93*31.25*9.9
有效区尺寸:72*24.6
LCD特性:TN,全透,正性,12点
产品别名:0418段码液晶显示屏、LCD显示屏、0418液晶显示屏、段显LCD
连接方式:PIN
外形尺寸:81*34*10.4
有效区尺寸:54.43*24.04
LCD属性:HTN,全透,负性,12点.
产品别名:0428段码液晶屏、LCD显示屏、液晶显示屏、段显LCD
HTN,投射,负显
LCD模块:1/4占空比,1/3偏压比
白色LED背光
产品尺寸:81*34*10.4
显示区域:54.43*24.04
绝对最大额定值
LCD驱动电压
直流电气特性
VDD = 5.0V ± 0.2V , GND = 0V , Ta = 25°C
逻辑供电电压
输入高电压
输入低电压
输出高电压
输出低电压
连接方式:PIN
外形尺寸:82*29.5*9.5
有效区尺寸:57.5*22
LCD属性:HTN,全图,负性,12点
产品别名:0425段码液晶屏、LCD显示屏、液晶显示屏、段显LCD
LCD编号:0428G00
连接方式:PIN
外形尺寸:105*65.3*11.7
有效区尺寸:65.5*35.5
LCD属性:HTN,全透,负性,12点.
产品别名:0428段码液晶屏、LCD显示屏、液晶显示屏、段显LCD
HTN,投射,负显
LCD模块:1/4占空比,1/3偏压比
白色LED背光
产品尺寸:105.0(W) * 65.3(L) * 11.7(H)(Max)
显示区域:65.5(W) * 35.5 (L)
绝对最大额定值
LCD驱动电压
直流电气特性
VDD = 5.0V ± 0.2V , GND = 0V , Ta = 25°C
逻辑供电电压
输入高电压
输入低电压
输出高电压
输出低电压
LCM编号: 0428H01
外形尺寸: 93.8*53.8*10.2
可视区尺寸: 66*40
视角方向:12 o'clock
控制器: HT1621
驱动方式: 1/4duty, 1/3bias
LCD显示模式: TN,全透,正显
工作温度: -0℃-50℃
存储温度: -10℃-60℃
连接方式: PIN
背光颜色: 白色
第1脚:VDD
第2脚:GND
第3脚:DATA
1. DRIVE METHOD:1/1DUTY, 1/1BIAS,VOP 4.5V,VDD 5V
2. VIEWING ANGLE:12'CLOCK&
3. DISPLAY TYPE:TN,TRANSMISSIVE/P0SITIVE.&
4. OPERATING TEMP: -20°C TO +70°C
5. STORAGE TEMP: -30°C TO +80°C&
6. BACKLIGHT: WHITE&
是否公用模组: 否&
模块类型: 笔段式
产品别名: 0428段码液晶屏、0428 LCD显示屏、0428液晶显示屏、段显LCD
Copyright&
深圳市兴宇合电子有限公司 [拥有十几年经验的、、、生产厂家!]
国内销售专线:2 / 8 前台电话:6 地址:深圳市宝安区石岩镇宏发工业园16栋5楼
传真:7 &&当前位置: >>
51单片机自学笔记
第1天 从哪儿开始你的单片机学习. 单片机技术是非常有趣的一门技术, 但是许多初学者往往苦于找不到正确的学习方法和 合适的学习工具而一直在门外徘徊, 今天就和大家分享一下几位书呆子是如何幸运的找到学 习 51 单片机的“神秘武器”的,并告诉大家如何使用这些工具,最后和大家一起冲出困惑、 不解和原地踏步的重围,快速踏上 51 单片机学习和应用的溜光大道,去领略探索中发现的 美景。1.1神秘武器的得来从前,有个贫穷的书呆子,他的名字叫阿范。他的智商不高,可就是有股子轴劲儿,相 信知识可以改变命运,他就刻苦学习,脑袋里装了许多知识,把内存都装的差不多了,以至 于运行速度都很慢了。 因为他是工业自动化专业的, 听很多老师和学哥说嵌入式在将来会很 有发展,而且还告诉他,要想把嵌入式弄明白,51 单片机的学习是基础,阿范很听话,每 天就拿本 51 单片机的教材看啊看啊?1 一年过去了,阿范还是在看书,把那本“宝典”看了很多遍,很多知识都背下来了,可 就是不会编程序。正当阿范百思不得其解之时,在一个风雨交加的深夜,一个神秘老人突然 出现在阿范的面前,他用祥和而温暖的眼神看着阿范,微笑着? 神秘老人: “孩子,是你用执着、勤奋、刻苦打动了我,我真的不想让你再在黑暗中摸 索前进了,所以,我这次现身是给你光明,给你方向、给你真正的宝典来了,不过,你要答 应我, 当你真正掌握了这些知识, 一定要帮我把这些知识传授给那些像你一样对单片机感兴 趣又勤奋的孩子们,你能做到吗?” 阿范: “神秘老人,请相信我,我一定能。 ” 神秘老人: “那好吧,现在我就告诉你为什么你这些年都没有学好单片机的原因了,你 要认真听好” 第一、选择比努力更重要,你这些年用的书不适合你,那些书都是给会的人准备的。还 有部分书中的例程不完整,或者有些错误,或者就是全对,程序太长,又没有注释,所以我 给你的第一个“法宝”――“葵花宝典” 。 第二、 这些年你只是看书, 从不实战, 你连 “枪” 都没有, 怎么能在实践中取得胜利呢? 所以我给你的第二个“法宝”――实用开发板一块 第三、为了把程序下载到单片机中,我再给你一条下载线,至于电脑我就不给你了,现 在电脑都便宜了,自己去买吧;还有就是要准备一个编程软件和一个下载程序用的软件,这 个我也帮不了你,你自己去网上下载一个就行。至于怎么用,你看葵花宝典就可以了。 第四、我走后就不会再出现了,机会你自己要把握好,为了帮你在最困难的时候能度过 难关,我再给你一些锦囊,当你在需要的时候就打开看看。你都记住要学好单片机要准备什 么了吗?” 阿范: “我记住了,要准备电脑、实验板、下载线、编程软件、下载软件、葵花宝典和 锦囊。 ” 神秘老人: “记住就好,千万切忌只看书不实战,那我就走了。 ” 阿范: “神秘老人,神秘老人?您给弟子个学名吧! ” 神秘老人: “好吧,你以后就叫行者吧。孩子,记住,你答应我的事,当你学会以后帮2 我把这些知识传授给那些像你一样对单片机感兴趣又勤奋的孩子们,你要遵守承诺。 ” 阿范: “师傅?弟子记住了,多谢师傅?”1.2单片机的身世20 世纪 70 年代,美国仙童公司首先推出了第一款单片 机 F-8,随后 Intel 公司推出了 MCS-48 单片机系列,这个 阶段的单片机性能较弱,属于中、低档产品;此后,随着集 成技术的提高以及 CMOS 技术的发展,Intel 公司于 1980 年 推出了 8 位高档 MCS-51 系列单片机,性能得到了很大的提 高,应用领域大为扩展;1983 年 Intel 公司推出了 16 位 MCS-96 系列单片机,加入了许多外围接口。如:模/数转换 器(AD) 、看门狗、脉宽调制器(PWM)等,其他一些公司也 相继推出了自己的高性能的单片机系统; 近年来, 许多公司 先后推出了性能更高的 32 位单片机,单片机的应用达到了 一个更高的层次。本小节都什么内容: 1、单片机的发展; 2 、 51 、 AVR 、 430 、 PIC 等几大主流单片机的 区别; 3、初学者最好先学 51;目前,无论是从单片机的位数来分,还是从生产单片机的公 司来分,单片机的型号都是非常多,单说 51 系列兼容单片机, 学单片机和学 就有飞利浦的 87LPC 系列,华邦的 W78 系列,达拉斯的 DS87 系 开车差不多,如果还 列,现代的 GSM97 系列等等,目前在我国比较流行的就是美国 没练熟,先找个性价 ATMEL 公司的 89S51,它是一种带 Flash ROM 的单片机,可以多 比高一点的车来练 次重复编程,使用方便。 习,开坏了也不心 接着上面的话题再给大家介绍一下我们经常在各种刊物上 疼。51 单片机简单、 看到的 AVR 系列、PIC 系列和 MSP430 系列单片机是怎么回事, 易学、即使带电拔插 以便让大家对单片机的发展有一个较全面的认识,在没有学习 也没什么大问题,当 单片机之前这是一个令很多初学者非常困惑的问题,这么多的 然最好别这样。 单片机我该先学哪一种呢? AVR 系列单片机也是 ATMEL 公司生产的一种 8 位单片机, 它 编者语录 采用 RISC 精简指令集,它的一条指令的运行速度可以达到纳秒 级,速度快,功耗低,片内资源丰富,一般都集成模/数转换 器 、 PWM、SPI、USART、I2C 等资源,大大简化了外围电路的设计,AVR 单片机是 8 位单片机中的 高端产品,由于它的出色性能目前应用范围越来越大;430 单片机是美国 TI 公司生产的, 它采用的是 RISC 的指令集,这款单片机除了资源丰富,其主要特点是超低功耗,但是多数 都内存不大;PIC 系列单片机,它是美国 MICROCHIP 公司生产的另一种 8 位单片机,它采用 的也是 RISC 的指令集,资源较丰富,而且型号非常多,适用于不同场合的应用。 虽然上述几款单片机的影响力都很大,应用都很广,但是 51 系列单片机在很多领域还 有大量的应用,而且作为初学者 51 系列是首选,因为它毕竟简单。1.3单片机都能干什么单片机都能干什么?许多初学者会有这样的问题。单片机以其高可靠性、高性价比、低 电压、 低功耗等一系列优点, 近几年得到迅猛发展和大范围推广, 广泛应用于工业控制系统, 数据采集系统、智能化仪器仪表,及通讯设备、日常消费类产品、玩具等。并且已经深入到3 工业生产的各个环节以及人民生活的各层次中,如车间流水线控制、自动化系统等、智能型 家用电器(冰箱、空调、彩电)等,无不含有单片机。1.4神秘老人的法宝1.4.1 实验开发板学单片机必须得有块实验开发板, 可是当年行者学单片机时还没有 ISP 功能, 要买一个 仿真器,一个编程器,一个实验板和一台电脑,那时那儿买得起,无奈只好把学习单片机的 想法放一放了。现在好了,一切都变的简单了,下图是一块简单的实验板图片(当然还有一 块实验开发板在后面的章节里会出现) ,可以完成 LED 闪烁、数码管显示、独立按按键、温 度测量、串口通讯、数字心率检测等实验。具体各部分电路图及原理和应用程序会在后面讲 解。图 1-1 实验开发板1.4.2 下载线下载线给大家介绍两种,首先介绍一种是并口的,外观图如图 1-2 所示,这种下载线在 比较老的台式电脑上面可以用,新的电脑或笔记本4 神秘老人的法宝: 1、葵花宝典一部; 2、实验开发板一块; 3、下载线一条; 4、编程软件和下载软件; 5、电脑一台; 6、神秘的锦囊就在身边;图 1-2 并口下载线外观图电脑都没有并口了,不可以用了,这种下载线的优点就是 成本低,适合在多种下载软件上使用。这款下载线的电路 原理图如图 1-3 所示。利用了一片 74LS244,起到缓冲作用,当下载结束后,下载线和用户 电路的信号线都变成高阻状态,减少对用户电路板的影响。其中 MOSI 与 51 单片机的 P1.5 相连,MISO 与 51 单片机的 P1.6 相连,SCK 与 51 单片机的 P1.7 相连,RESET 与 51 单片机 的复位引脚 RST 相连。这个下载线自己就可以 DIY 一个,很好用的,当然还有其他的电路, 这里就不一一介绍了。图 1-3 并口下载线原理图下面再介绍另一款下载线,下载线外形图如图 1-4 所示,它是 USB 接口的,使用方便, 能够满足现在的新式电脑的要求。电路原理图如图 1-5 所示,其中包含一片 MEGA8 单片机, 需要编写驱动程序,还要安装 USB 驱动软件,不过网上有很多大侠提供的,具体工作原理就 部多讲了。图 1-4 USB 下载线外观图5 1.4.3 电源单片机需要 5V 的电源,通常我们得到 5V 电源的方法是用变压器、整流电路、滤波电路 和稳压电路制作一个 5V 电源, 参考电路如图 1-5 所示。 经变压器变压可以将 220V 交流电变 成 7V 或 9V 的交流电,再经过 4 个整流二极管整流变成脉动的直流,再通过 C1 和 C2 滤波, 然后通过 7805 稳压,最后通过 C3 和 C4 滤波即可得到+5V 直流电,D3 是一个发光二极管, 起到电源工作是否正常的指示作用,D2 的作用是当直接接直流电,并且把正负极弄反了时, 起到保护作用。 如果不想自己制作电源,当只需要 5V 电源是时,可以用一条 USB 线把电脑 USB 口的 5V 电引到板子上使用,图 1-6 是一条 USB 电源线。图 1-5 电源电路图 1-6 USB 电源线1.4.4 编程软件编程软件有很多,其中以 KEIL 和伟福 WAVE6000 应用较广,在此先简单介绍一下伟福 WAVE6000 编程软件(KEIL 软件在后面再讲) ,该软件可以在南京伟福实业有限公司网站 http://www.wave-cn.com/的下载专区中下载,打开软件安装程序,点击“setup” ,然户按 着提示点击“下一步”即可完成安装,打开桌面上的图标,界面如图 1-7 所示。使用方法在 后面讲。6 图 1-7 wave6000 打开界面1.4.5 下载软件可以完成下载任务的软件很多, 这里介绍一款下载软件, 该软件是由智峰工作室研发的, 它可以支持多种接口,如串口、并口、USB 口等。打开软件界面如图 1-8 所示。7 图 1-8 智峰下载软件1.5一个古老的神灯几乎在每本单片机的书中都提到发光二极管的实验,所以行者在此也来说说“神灯”的 有关问题。 图 1-9 是普通发光二极管的外形图及电路符号,从实物图上看,管脚长的是阳极,如果 是用过的可以看二极管里面有一个三角形状的片, 大片的一侧是阴极, 但是有些黄色的二极 管正好相反,如果想弄个清楚,最好是用万用表测量,因为二极管具有单向导电性。 当电 路如图 1-10 所示接线时,发光二极管就会发光;千万不要认为小灯实 验没有用哦! ! !图 1-9 二极管外形图及电路符号而如果把电源或二极管任何一个元件反接,则二极管都不会发光。图 1-10 发光二极管实物接线图图 1-11 发光二极管接线原理图接着上面的内容,行者提个小问题:如果我有规律的把电池正接、反接,那会怎样呢? 如果频率合适的话是不就会看见发光二极管闪烁了, 当然如果特别快就看不出闪烁了, 而是 一直亮,只是没有原来那么亮而已,当然行者可没有那么快的伸手,这个还是单片机厉害, 后面给大家展示老单的伸手。 对了,行者还有个小问题,图 1-11 中的电阻该用多 大的呢?不串接电阻不行吗?很多初学电子的朋友在选 择参数时最头痛了。不用电阻是不行的,这个电阻起到限 注意了 哦! ! ! 流作用,一般常用的普通发光二极管通 10mA 电流较为合 电阻选择时还要考虑功率 适,所以可以估算电阻的阻值了,如果我们选择+5V 电源 呢,如 1/4W,1/8W 等, 供电,就应该选择约 500 欧姆的电阻(忽略二极管导通时 要根据你的“爱房 R”判 的压降) ,可是电阻不是想买多少欧姆就能买到的,可以 断噢! ! ! 参考电阻的标称值来选择(电阻标称值见附录 G),一般我8 们可以选择 470 欧姆,当然再大点或小点都可以,只是发光二极管要么就偏暗要么偏亮。 关于发光二极管的封装和颜色再说说,封装主要有图 1-10 中这样的,再就是贴片的, 一般贴片的价格高一些;关于颜色,普通红、黄、绿的比较便宜,几角钱一个,蓝光的、翠 绿光的比较贵,要几元钱,当然也和你的购货渠道有关,一般网上的便宜一些。 不说了,还是快点让神灯闪起来吧,玩个一亮一灭的鬼火。把单片机先接上,当然现在 对于初学者来说, 还没看见单片机的真面目呢, 有关单片机的外在形象和内芯世界后面再讲, 现在只是展示给大家先看看而已。 电路图 1-12 所示,是单片机控制一个 .LED 的电路图,要求完成 LED 闪烁的任务。+5 4 .7 K40C3 1 0u FV CCR2 1 0kEA319RST5 6 7 818C1 3 0p FY1 1 2M Hz19 20XN 1D GP0. 0 P0. 1 8 9S5 1 P0. 2 P0. 3 P1. 4 P0. 4 P1. 5 P0. 5 P1. 6 P0. 6 P1. 7 P0. 739 38 37 36 35 34 33 329 8 7 6 5 4 3 2 1R1D1+5X2C2 3 0p F图 1-12 单片机控制一个 LED 发光二极管首先, 将该电路的实际接线接好, 然后打开编程软件 WAVE6000, 新建一个文件如图 1-13 所示,然后将该文件保存,保存时文件的扩展名要为“asm” ,表示编写的是汇编程序。图 1-13 WAVE6000 中新建一个文件9 编写程序代码如图 1-14 所示,程序代码写完就可以编译了,让软件帮我们把程序变成 单片机能够认识的“.HEX”文件,当图 1-14 中下方出现的都是绿色的对号时表示编译通过。图 1-14 编写 LED 闪烁程序并编译接下来就可以打开下载软件, 如图 1-15 所示, 将 “编程器及接口” 选项设置为 “USBASP” , 选择芯片选项设置为你用的芯片型号,其他如图中所示设置,然后点击“调入 Flash”找到 在 WAVE6000 下编程编译生成的“LED.HEX”文件,然后点击“自动” 。程序就跑到单片机里 去了,至于程序放在哪了,我们后面再详细讲解,然后你观察实验板上是不有个神灯在闪烁 啊。 (光盘:实验现象\1.avi)10 图 1-15 编程软件界面1.6 互动环节良子: “行者在上面编的程序也看不懂啊,那个 R0、R1、 DJNZ 都是什么东东啊?还有你说打开下载软件,找到那个 LED.HEX 的文件,一点击“自动”程序就进单片机的肚子里去 了,究竟把程序放在哪了?” 行者: “噢,在这里我们只是展示一下,有关单片机内部 的寄存器和指令系统我们会在后面与大家分享; 有关程序下载 到哪儿去了?程序下载的过程我们就不用管了, 这些都是设备 来完成的, 通过设备和软件把程序下载到单片机的内部程序存 储器 ROM 中,有关 ROM 和 RAM 的问题在下节讲。 ”11 第2天 认识一下著名的单片机先生请问吃掉一个大象怎么吃?显然要一口一口吃,学知识也一样,要一步一步来,千万别 着急;认识一个事物要有一个过程,先是外表,然后是内心,今天就和大家分享一下单片机 先生的外在形象和丰富的“内芯”世界。2.1单片机的外在形象51 单片机的封装形式有三种,图 2-1 是 TQFP 和 PLCC 封装,TQFP 封装的体积小,成本 低,为目前商品的主流;PLCC 封装可以直接应用在电路板上,而不必钻孔,在研发、试验 或教学时,还可以利用插座,以缩短开发与生产周期;第三种封装为双列直插封装(DIP) , 如图 2-2 所示,这种封装刚好可以插在面包板或 40 引脚的 DIP 插座上,特别适用于学校、 培训机构,但是由于该封装体积大、电路板制作成本高,在商品里应用较少。把引脚按照功 能分类介绍如下:图 2-1 TQFP 封装和 PLCC 封装12 2.1.1 要工作就得吃饭要让单片机工作就得让它“吃饭” ,所以要给它提供电源。 1 VDD(40 脚) :接+5V 电源 2 GND(20 脚) :接地也就是+5V 电源负极2.1.2 庞大的组织要有个总指挥18 脚和 19 脚:大家已经知道,单片机是在一定的时序控制下工作的,那么时序和时钟 又有什么关系呢?时钟是时序的基础, 单片机本身就如同一个复杂的同步时序电路, 为了保 证同步工作方式的实现, 电路必须在脉冲信号的统一指挥下才能工作 (如同军训时教官的口 令) ,按时序进行工作,那么单片机内的时钟是如何产生的呢?有两种方式:一种是内部振 荡方式,只要接上两个电容和一个晶振即可,电路 如图 2-3 所示,电容的大小影响着振荡器振荡的稳 定性和起振的快速性,通常选择 10-30pF 的相等的 两个瓷片电容,另外在设计电路时晶振和电容应尽 可能的靠近芯片,以减少 PCB 板的分布电容,保证 振荡器工作的稳定性,提高系统的抗干扰能力;另 一种是外部振荡方式,采用外部振荡方式时需在 XTL2 上加外部时钟信号,XTL1 接地。此种方式应用 于系统由多片单片机组成,为了保证各单片机之间 时钟信号的同步,就应当引入唯一的公用的外部脉 冲信号作为各单片机的振荡脉冲。2.1.3 控制信号引脚1 PSEN(29 脚):片外 ROM 选通信号。当单片机 要扩展存储器时,该引脚通常与外部存储器的片选 OE 引脚相连,当单片机要读取外部存储器数据时, 该引脚输出低电平信号。 2 ALE/PROG ( 30 脚) :地址锁存信号输出端 /EPROM 编程脉冲输入端。当访问外部存储器时,用于将 P0 口的地址锁存在外部锁存器中; 另一个功能是 EPROM 编程脉冲输入端。 图 2-2 DIP 封装引脚分布图 3 RST/VPD(9 脚) :复位信号输入端/备用电源输入端。何为复位,都知道电脑死机时 我们按了“reset”键吧,这就是复位,通常只要保证该引脚持续 2 个机器周期的高电平就 会使单片机复位。 4 EA/VPP(31 脚):内/外部 ROM 选择端。当单片机片内的程序存储器不够用时,就需要 外扩存储器,当我们需要把程序存储在外部存储器中时,需要将 31 脚接地,表示使用外部 存储器;当使用内部程序存储器时需要将 31 脚接在+5V 上,表示使用片内存储器。13 2.1.4 输入输出引脚 P0、P1、P2、P351 单片机有 4 个并行 I/O 口,分别是 P0、P1、P2 和 P3 口,每个并行口由 8 个引脚组 成,都可以用作普通 I/O 操作,除了 P1 口外,其他并行口都具有第二功能,下面分别介绍: P0 口(39-32 脚) :当向外部存储器读写数据时,P0 口 是复用口,P0 口和 P2 口配合完成低 8 位地址的传送后,P0 单片机想正常运行必 口再传送 8 位数据。 须具备的条件: P1 口(1-8 脚) :只具有普通 I/O 功能。 P2 口(21-28 脚) :当向外部存储器读写数据时, P2 1、必须加电; 口用于传送高 8 位地址。 2、必须接晶振电路; P3 口(10-17 脚) :P3 口除了能够完成 I/O 功能这一本 3、必须接复位电路; 职工作,还有许多非常重要的兼职任务,具体功能见表 2-1 4、如用内部程序存储器, 所示,具体功能的实现和应用方法后面再讲。 31 引脚必须接+5V;表2-1 P3口的第二功能表端口位 P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7第二功能 RXD TXD INTO INT1 T0 T1 WR RD注释 串行口输入 串行口输出 外部中断0 外部中断1 计数器0计数输入 计数器1计数输入 外部RAM写入选通信号 外部RAM读出选通信号14 锦囊: P1、P2、P3 口都能驱动 4 个 TTL 门,且不需要上拉电阻就能驱动 MOS 电路;P0口内部没有上拉电阻,驱动 TTL 电路时能带 8 个 TTL 门,但是驱动 CMOS 电路 时,若作为地址/数据总线,可以直接驱动,而作为 I/O 口时,需外接上拉电阻。2.2单片机丰富的内芯世界单片机究竟是个什么东东?为什么给人的感觉它如此的神通广大?它的内部都由哪些 部件组成呢?其实, 它就是一种能进行数学和逻辑运算并可以根据不同对象完成不同控制任 务的集成电路。它和电脑有些相似,也有 CPU 中央处理器、RAM(类似电脑内存条) 、ROM 程 序存储器(类似电脑硬盘)和输入输出设备(即 P0、P1、P2 和 P3 口)等。下面就和大家一 起分享单片机的内芯世界。2.2.1 好东西都放在哪了?单片机内部有两个地方可以存储东西, 一处是 ROM 程序存储器; 另一处是 RAM 数据存储 器。其实,这两处里面放的信息都是二进制数,但是还是有区别的,下面分别介绍。图 2-4 单片机程序存储器和数据存储器程序存储器(英文名称 ROM 全称为 Read Only Memory)叫只读存储器,所谓只读存储 器是指单片机在正常工作时只能读取不能写入修改, 但是当我们要把编译好的程序下载到单 片机里时,是可以修改的。 所以,程序存储器 ROM 里存放的就是编译好的二进制程序代码。15 AT89S51 单片机片内有 4K 的存储空间,AT89S52 单片机片内有 8K 的存储空间,如果片内空 间够用就不必外扩了,所以单片机的 31(EA)引脚要接+5V 上去,如果空间不够,需要外扩, 把程序代码存放在片外,则 31(EA)引脚要接在 GND 上,表示选择片外程序存储器,代码 执行时到片外去取指令执行, 最大可以扩展 64K 字节的程 序存储空间,可以参考图 2-4(a) 。 数据存储器(英文名称 RAM 全称为 Random Access 提示:编译通过的程 Memory)叫随机存取存储器,也叫内存,它是一种既可以 序 无 论 下 载 到 片 内 随时改写,也可以随时读出里面数据的存储器,类似于我 4KROM 中,还是外扩的 们上课时用的黑板,可以随时写东西上去,也可以用黑板 ROM 中, 程序执行都是从 擦随时擦掉重写。51 单片机内部的 256 个字节的 RAM 空 头开始的(即从 0000H 开 间分成两个区域,参考图 2-4(b) ,从 0―127(即 00H― 始) , 之后紧跟着就跳转到 7FH)这 128 个字节空间是用户可以随意操作的空间,而 0023H 之后继续执行,因 从 128―255(即 80H―FFH)这 128 个字节空间被 21 个特 为 0000H、 0003H、 000BH、 殊功能寄存器所占用,所以高 128 个字节并没有完全利 0013H、001BH 和 0023H 用, 但是我们用户也不能够使用剩余的 107 个字节, 所以, 是特殊房间,留给突然来 我们用户真正可以利用的只有低 128 个字节(对于 52 单 住的人,后面我们详细和 片机是可以用高 128 个字节的) ,要珍惜哦。下面就详细 大家分享。 和大家分享一下这 256 个字节的分配情况。 低 128 个字节的 RAM 空间分配情况如图 2-5 所示,它被分成三个部分。1、工作寄存器区在单片机内部有八个工作寄存器,分别是 R0、R1、R2、R3、R4、R5、R6 和 R7,这哥儿 八个也可以理解为用来存放临时物品(即临时数据)的房间,在单片机内部有 32 个房间用 这哥八个的名字命名,即从 00H―1FH(即从 0―31)这 32 个房间,被分成 4 组,每组 8 个 房间分别是 R0―R7,当有客人(其实是数据)来了,要住店,我们可以和他说,你住在 00H 房间,也可以和他说你住在 R0 房间,这是一个意思。当你说把数据放在 R0 中了,我就知道 你把这个数据放在了 00H 房间中。你可能会说,不对啊? 从 00H―1FH 共计 32 个房间,用 R0―R7 命名的分别都有 4 个房间,客人怎么才能知道你分给他的 R0 房间究竟是 提示:其实位寻址区相 00H、08H、10H 还是 18H 房间呢?很好,其实这个是由单 当 于 是 一 个 旅店 中 有 这么 片机内部的一个特殊功能寄存器 PSW 中的 RS0 和 RS1 这两 16 个房间, 每个房间有 8 张 位负责区分的,具体分配情况见房间分配示意图 2-5 所 床,每个床位可以单独提供 示,大家一看便知。为了弄清楚这个问题,大家看下面一 给任何一个客人住(该位置 段程序,当然仅这一段程序是不能完成什么任务,只是为 1) ,而其它区域,如上面讲 了说明问题用。 提到的工作寄存器区( 00H CLR RS0;把PSW中的RS0位置0 ―1FH) ,这 32 个房间就不 CLR RS1;把PSW中的RS1位置0 可以位操作, 即这 32 个房间 MOV R0,#22H;给 R0 里(即内存地址为 00H 空间)装 中的任何一个只能提供给一 一个十六进制数 22H 个团住(这个团可能 1 人, SETB RS0;把PSW中的RS0位置1 也可能 8 人把这个房间包下 SETB RS1;把PSW中的RS0位置1 来了) , 而不对单个人提供单 MOV R0,#22H;给 R0 里(即内存地址为 18H 空间)装 个床位服务。而位寻址区则 一个十六进制数 22H 可以对单个人服务,当然也 上面的程序先将 PSW 中的 RS0、RS1 两位置 0,选则 支持包房的,即可以当成普 了第 0 组工作寄存器组,表示 R0―R7 位于 00H―07H 处, 通区整体操作 8 位一个字节16 然后执行 MOV R0,#22H,就相当于是给内存地址为 00H 的房间赋十六进制数据 22H;然后又 将 RS0、RS1 两位置 1,选则第 3 组工作寄存器组,这时执行 MOV R0,#22H,就是在向内存地 址为 18H 的房间赋十六进制数据 11H。2、位寻址区从 20H-2FH 共 16 个字节定义为位寻址区,每个字节中包含 8 个位,位寻址区共计 128 个位,之所以称该区为位寻址区,是因为这个区域可以整体操作某个字节,也可以单独操作 某个字节中的某个位(其它区域不可以单独操作位) ,为了使用方便,把这 128 个位统一编 号,如图 2-5 所示,比如我想把位寻址区中的第 9 个位置 1(setb 9),相当于是把 21H 字 节单元中的最低位置 1,即 21H 单元中的数据变成了 01H(假设 21H 单元原来数据是 00H) 。 那我们来看看下面的指令是什么意思?图2-5 单片机片内数据存储器空间分布图SETB 11HMOV 11H,#55HSETB 11H 是将位寻址区的第 11H 位置 1,即将内存 22H 单元中的第 2 位置 1,使得 22H 单元中的数据变成 02H(假设 22H 单元原来的数据是 00H) ;而 MOV 11H,#55H 是将内存地址 11H 中赋一个十六进制数据 55H,相当于是给工作寄存器组 2 中的 R1 赋一个十六进制数据 55H。所以,位操作指令 SETB 不能用在工作寄存器区和一般工作区,而 MOV 指令可以用在 各个区。3、一般工作区从 30H―7FH 这 80 个字节单元是一般工作区, 具体那一个单元的用途完全是由用户决定 的,比如我要设计一个温度控制系统,我可以用 30H 单元存放采集的温度,用 31H 单元存放17 设定的理想温度等等。 当然位寻址区也可以由用户决定每个字节单元的作用,可以当成一般工作区来分配使 用,甚至工作寄存器区的 32 个字节单元也可以由用户决定每个单元的作用。但是一般在空 间分配够用的情况下尽量不要把工作寄存器区的单元改为其它用途。 关于这方面的实际练习 会在后面讲解,大家也可以打开 WAVE6000 软件,输入下面的代码,编译通过后,按“F8” 按键单步执行,观察窗口中“DATA”区中内存单元数据的变化情况来体会有关上述内容,这 里就不细说了,好好体会吧!这个很重要哦! ! ! ORG 0000H; SETB 20H; MOV R0,#55H; SETB 21H; MOV R7,#44H; CLR 20H; SETB RS0; CLR 21H; SETB RS1; SETB 00H; MOV R0,#0AAH; SETB 01H; MOV R7,#0BBH; MOV 20H,#0FFH 4、特殊功能寄存器区 从 128―255(即 80H―FFH)是特殊功能寄存器(SFR)空间, 21 个特殊功能寄存器离 散地分布在 80H―FFH 地址空间内,如表 2-2 所示。各个功能寄存器将在后面各部分出现时 再和大家分享。 (附录 A 中有特殊功能寄存器的详细介绍)表 2-2符号 B ACC PSW IP P3 IE P2 SBUF SCON P1 TH1 TH0 TL1 TL0 TMOD TCON DPH DPL SP P0 PCON 地址 F0H E0H D0H B8H B0H A8H A0H 99H 98H 90H 8DH 8CH 8BH 8AH 89A 88H 83H 82H 81H 80H 87H 初始值 00H 00H 00H 00H FFH 00H FFH 不定 00H FFH 00H 00H 00H 00H XH 00H 07H FFH 0XXX0000B特殊功能寄存器简介表功能介绍 B 寄存器 累加器 程序状态字 中断优先级控制寄存器 P3 口锁存器 中断允许控制寄存器 P2 口锁存器 串行口锁存器 串行口控制寄存器 P1 口锁存器 定时器/计数器 1(高 8 位) 定时器/计数器 1(低 8 位) 定时器/计数器 0(高 8 位) 定时器/计数器 0(低 8 位) 定时器/计数器方式控制寄存器 定时器/计数器控制寄存器 数据地址指针(高 8 位) 数据地址指针(低 8 位) 堆栈指针 P0 口锁存器 电源控制寄存器是否可以位操作 是 是 是 是 是 是 是 否 是 是 否 否 否 否 否 是 否 否 否 是 否18 2.2.2 芯里还有别人吗?在前面已经和大家分享了单片机的 I/O 口,即 P0、P1、P2 和 P3,还和大家一起探讨了 有关程序存储器 ROM 和数据存储器 RAM 的一些知识, 现在我们继续看看还有什么。 这里只是 简单介绍,后面详细讲解。1、串行口51 单片机内部有一个可编程的、全双工的串行接口。串行收发的数据存储在特殊功能 寄存器中的串行数据缓冲器 SBUF 中,串行发送和接收是通过单片机的 P3.1 和 P3.0 引脚完 成的。2、定时器/计数器51 单片机内部有两个 16 位的可编程定时器/计数器, 分别是 T0 和 T1, 可编程是指它们 的工作方式由指令设定,可以当计数器用,也可以当定时器用,即设置寄存器 TMOD 中的内 容即可。并且计数或定时范围由指令来设置。3、中断系统51 单片机的中断系统可以处理五个中断,分别是两个外部中断、两个定时器/计数器中 断和一个串口中断。 外部中断申请通过引脚 P3.2 和 P3.3 输入, 输入方式可以是低电平信号 或下降沿信号有效,可以通过设置选择;定时器/计数器中断请求是当定时器溢出时向 CPU 提出的, 即由最大值变成 0 时提出的请求; 串行口每次发送完一个数据或是接收完一个数据 就可以提出一次中断申请。 51 单片机可以设置两个中断优先级,通过中断优先控制寄存器 IP 来设置,改变各个中 断的中断优先级别。2.3互动环节甲子:在许多书上看见过介绍 ROM 的,你能详细介绍一下 ROM 都有哪些种好吗? 行者:哦,程序存储器有好几种,不管哪种其作用都是用 于存储我们设计的程序代码,下面就分类介绍给你:ROM 只读 内存是一种只能读取资料的内存。在制造过程中,将资料以一 特制光罩烧录于线路中,其资料内容在写入后就不能更改,所 以有时又称为“光罩式只读内存”;PROM 可编程程序只读内存 内部有行列式的F丝,视需要利用电流将其烧断,写入所需的 资料,但仅能写录一次;OTPROM 是一次编程只读内存,当产品 批量生产又要求价格比较低时,用这种程序存储器的单片机是 非常合适,编程写入之后就不再抹除;EPROM 是可擦除可编程只读内存,可利用高电压将资 料编程写入, 擦除时需要通过封装外壳上预留石英透明窗口进行紫外线曝光, 则资料可被清 空,并且可重复使用,但是每次操作时间较长,要 15 分钟;EEPROM 是电子式可擦除可编程 只读内存,原理类似于 EPROM,但是擦除的方式是使用高电场来完成,不需要透明窗进行紫 外线照射,大大节省时间;Flash ROM 是一种快速存储式只读存储器,简称闪存,这种程序 存储器的特点是既可以电擦写而且掉电后程序还能保存, 可以达到反复烧写一千次左右, 速 度快,目前,新型的单片机都采用这种程序存储器。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 大原:ROM 和 RAM 中都有数据,有什么不同啊?程序执行时是怎么用 RAM 和 ROM 的?19 行者:这个问题非常的棒。我还是先给你讲个生活故事吧。比如在一个旅馆,有老板、 卫生员,领班小经理,当然一定也有房间。这个老板每天晚上就把第二天要做的每件事都写 在了一张纸上,上面清楚的写着:第一、把 201 房间里 8 张床上面的东西搬到 203 房间 8 张床上去; 第二、 205 房间的客人走后把房间收拾出来, 把 207 房间 6 号床上的被罩扯下来, 第三、 去隔壁商店买 8 个不同花样的被罩给 209 房间换上?。 第二天领班小经理就拿着那张 纸,安排人干活儿,完成一件就下一件,如此循环的工作。在上面的故事里,白纸就是程序 存储器,上面写下的东西就相当于是我们编写的程序,老板就是设计程序的人,即编写程序 的人,领班小经理就相当于是程序指针 PC,负责读出并安排程序上的每件事,而被操作的 那些房间就相当于内存 RAM,而房间里面的每张床位就相当于内存中每个字节中的一个位, 到隔壁商店买 8 个不同花样的被罩给 209 房间换上就相当于到片外的某个器件里去读数据并 拷贝到内存 209 单元。现在再考虑 ROM 和 RAM 中存储的二进制数据 0 和 1 的关系,ROM 中的 这些 0 和 1 是由我们编写的程序经过编程软件编译后生成的单片机能够认识的 0 和 1 这些代 码,单片机就根据 ROM 中这些数字就可以知道一步一步都干什么,一旦将程序烧写进 ROM 中,在程序执行过程中就不能改了(老板的那张纸是不能改的,除非老板本人重新写) ,除非重新编程、编译、下载。而内存 RAM 就相当于是旅馆的房间,有的高级房间上面不但有房 间号,也有名称,如 R0 等,这些房间不会分租给个人,只能整体包下来,而有些房间可以 把单个床位提供给某个客人,也可以整体包给一个团,还有些特殊房间只能给指定的人住, 因为他把这个房间给永久包下来了, 这几类房间就相当于是内存 RAM 中的工作寄存器区、 位 寻址区、一般区和特殊功能寄存器区。好了,现在明白了吧。自己好好体会吧,这个问题很 重要的哦! ! ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 峰巍:ROM 和 RAM 都是可以存储数据的空间,当我想在片外分别扩展 64K 的空间时,单 片机到片外地址 101 去取数据,怎么区分是到 ROM 还是 RAM 中取数据呢?有点乱? 行者: 不乱, 捋捋就不乱了。 是这样的, 单片机到片外取数据虽然都是派相同的人去取, 即用 P0 和 P2 去取, 但是领 P0 和 P2 去的人不是一个, 领 P0 和 P2 去片外程序存储器取程序 代码的是由单片机的 29 脚(PSEN)负责,当然 30 脚和 31 脚也要配合;领 P0 和 P2 去片外 数据存储器取数据是由单片机的 P3.6(WR)和 P3.7(RD)负责,所以虽然是一个地址 101, 但是不同的人带路,带到的地方是不一样的。比如有两个楼都有 101 房间,而负责领路的人 分别负责这两个楼,所以? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~20 小涛:为什么提供位寻址区,有什么用? 行者: 在位寻址区可以单独操作某个字节中的某一个位。 当然这一位里只能存放 0 或 1, 这样我们就可以表示一个事件的两种状态。比如八路军的两个连队要攻打鬼子的一个山头, 他们事先商量好了, 如果谁把原先放到的彩旗升起来, 则表示另一个连队现在可以全速进军 攻打了。红旗放倒和升起来就是两种状态,可以分别用 0 和 1 表示。再举个例子,当我们用 单片机检测金属铁片时, 当检测的铁片数等于三块儿时, 就可以把位寻址区事先选定的某一 位置 1 了, 相当于做了一个标志, 当单片机查询到该位为 1 时就知道已经检测了三块铁片了, 如果是 0 就表示还没检测到三块。总之,通常位寻址区是用来做标志的。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 娜仁:今天的理论知识好像很多,许多知识都背不下来,怎么办?有什么好方法吗? 行者:是的,今天的理论知识确实很多,也很重要。但是都不用去背,只要能理解上面 所叙述的内容就可以。等到用的时候手里拿着单片机的引脚分布图和内存分布图就可以了。 没有必要背下来, 我们的脑子是用来创造性的分析和处理问题的, 不是用来存放知识的仓库, 知识是知识,会用知识才有力量,记住,能用电脑存储的就让它去存储,能让电脑干的就让 它去干。锦囊: 学单片机如同带兵远征,最后能否取得胜利,和许多因素有关,这其中就包括你是否坚持克服困难,你是否带足了粮食和弹药以及行军地图。所以先告诉你,你 一定要手握(或优盘里)有单片机引脚分布图、内存分布图、指令表、特殊功能 寄存器功能表、常用元器件手册等。21 第3天 用语言尝试着与单片机交流了解了单片机的外部引脚分布及功能,也知道了单片机丰富的内芯世界,这还不够。如 果真想把这位“圣人”请出来,我们还要学会和她交流,主要是语言的交流。单片机的母语 是汇编语言,她也懂世界上比较通用的语言―C 语言(其实它只懂机器语言,汇编语言和 C 语言是要经过编程软件翻译成机器语言它才懂) 。我们今天先和她用汇编语言交流。她的汇 编语言词汇并不多,只有 111 条指令,不过要能把这 111 条指令合理的组织起来,那可是会 产生奇迹的哦。只要把它的语言弄清楚了,你想让她帮你做什么都行。想不想让她帮你控制 智能小车、监控温度?那就加快脚步吧! 下面我们就来学学她的词汇, 不过可不能象学英语似的, 先背单词, 背会了再练习句子, 最后再写文章。学习英语对我来说体会那是相当深刻,用这样的方法六级到现在还没过。后 来学单片机才弄明白,其实有时可以直接看文章,发现不懂的词汇再去查词典,感觉这样效 果不错。现在我们就以任务为中心,提出设计要求,根据要求设计电路、编写程序,在分析 程序的过程中和大家分享指令。具体指令见附录 B―51 单片机的指令表。22 3.1一个 LED 灯闪烁下面我们通过神灯的实验给大家介绍几个常用的指令。 首先我们看一个 LED 小灯闪烁的 实验,即一个小灯一亮一灭的实验。电路如图 3-1 所示。1.硬件电路设计实现 LED 小灯闪烁实际上就是让小灯亮一下灭一下, 即让发光二极管导通一会儿再关断 一会儿即可。因此,只需要将 LED 发光二极管的一个极接到电源上,另一个极接到单片机 32 个 IO 口的任何一个即可。这里需要注意:如果把发光二极管接到 P0 口,需要给 P0 口接 上拉电阻, 电路如图 3-1 所示。 由于 89S51 单片机 IO 口输出低电平时的灌电流能力较强 (可 达 20mA) ,而输出高电平时的拉电流能力较弱,这里设计时将 LED 发光二极管的阴极接到了 单片机的 P0.7 引脚上,而阳极通过一个 R1(470 欧姆)这个限流电阻接到+5V 上。 .+5 4 .7 K40C3 1 0u FV CCR2 1 0kEA319RST5 6 7 818C1 3 0p FY1 1 2M Hz19 20XN 1D GP0. 0 P0. 1 8 9S5 1 P0. 2 P0. 3 P1. 4 P0. 4 P1. 5 P0. 5 P1. 6 P0. 6 P1. 7 P0. 739 38 37 36 35 34 33 329 8 7 6 5 4 3 2 1R1D1+5X2C2 3 0p F图 3-1 单片机控制一个 LED 小灯闪烁电路图2.软件设计思想让 P0.7 引脚输出低电平(发光二极管导通发光) ,延时一段时间后再输出高电平(发光 二极管截止不发光) ,再延时一段时间后输出低电平,?反复循环即可。3.程序代码清单ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;P0.0口置低电平,灯亮 ;调用延时程序 ;P0.0口置高电平,灯灭 ;调延时程序 ;跳到MAIN;--------------------主程序------------------MAIN:CLR P0.0 CALL DELAY SETB P0.0 CALL DELAY SJMP MAIN;----------------延时子程序-----------------23 DELAY:MOV R0, #250 D2:MOV R1, #250 D1:DJNZ R1, D1 DJNZ RET END R0, D2;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束4.程序代码分析(略) 5.互动环节大海:我是初学者,没有电路方面的任何基础,你能不能把电路图中的 C1、R2 和那 8 个并排的电阻方面的知识再详细说说吗? 行者:NO 问题!C1 和 R2 构成了复位电路。当刚开始上电时,即刚一接上电源 VCC 时, C1 瞬间相当于短路(电路里有关于暂态分析部分的知识) ,C1 两端保持 0 伏电压,VCC 的电 源电压就都加在了 R2 上,因此在单片机 9 脚 RST 上出现高电平,此后 C1 上逐渐充电,也就 在 C1 上出现电压,R2 上的电压开始下降,最后单片机 9 脚 RST 上变成了低电平,在此过程 中只要满足单片机 9 脚 RST 上的高电平持续 24 个振荡周期即可使单片机复位,即使程序从 头从新开始执行。 关于那 8 个并排的电阻是上拉电阻。 因为单片机 P0 口内部没有上拉电阻, 因此需要外接上拉电阻。在市场上可以买到这个排阻,它有 9 个引脚,一个是公共的引脚, 公共引脚接在 VCC 上,其余 8 个引脚分别接到 P0 口的 8 个引脚上,这样比接分立的 8 个普 通电阻方便,但是价格相对高些。31 引脚接 VCC 上表示选择内部程序存储器。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 华建: 通过上面程序中的汉语注释部分我们大致理解每条指令的意思, 但是我还是对完 成一个完整的程序的思路或者说程序是怎么执行的弄不太懂? 行者:先给大家讲个小故事轻松一下吧。记得有一部电视剧《雍正王朝》 ,里面有个掌 管皇宫安全的官,好像叫九门提督吧。他每天起床、洗漱、用餐完后就开始不停的在宫内循 环转悠以确保皇宫安全,在转悠的过程中,当遇到了什么问题他会处理,甚至会调一些人来 处理。单片机也一样,每当开始执行时,一定是从程序存储器的 0000 位置开始执行,跳到 一个合适的位置(后面再讲)进行初始化(相当于是九门提督起床、洗漱、用餐) ,初始化 相当于是做准备工作,接下来就进入主程序无限的循环(不停的在宫内循环转悠) 。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 德华:是所有单片机程序都是从头跳到一个位置,然后进行初始化准备,最后进入一个 无限循环的主程序中吗?为什么要跳过一段 ROM 的空间不用呢?ORG 又是什么意思,初始化 程序 START:MOV SP,#60H 在这里有什么作用呢? 行者:是的,所有程序都要从头执行并跳到一个合适的位置继续初始化的准备工作。原 因就是从 0000H 到 0030H 之间有几个地址是有特殊用途的, 我们在此预留了, 具体用法我们 后面再说。当然在本例中完全可以不跳也不会影响到 LED 小灯闪烁的效果。 ORG 是一条伪指令,仅起到宣布其下面的一条指令编译后生成的二进制代码存放的地点 而已。如本例中 SJMP START 这条指令就放在了程序存储空间的 0000H 处了,而 START:MOV SP,#60H 就存放在程序存储器的 0030H 处了。初学者常犯的错误如下面这段程序所示,程序 一开始从 30H 开始执行这是错误的, 要从 0H 地址开始执行; 在 ORG 0040H 后面又出现了 ORG 0025H,即后面宣布的地点比前面的还小,这也是错误的,这就相当于在二楼上面建地下室。ORG 0030H SJMP START ORG 0040H START:MOV SP, #60H24 MOV P0, #0FFH ORG MOV 0025H P0, #45H ?初始化就是做准备工作,例如设计一个时钟,开始要求钟上显示 12:00:00,那我们 就需要把时位赋值成 12,而把分位和秒位赋值成 0,即我们要用指令 MOV HOUR,#12,MOV MINUTE,#0,MOV SECOND,#0。当然初始化的内容要看设计需要,后面我们再逐步和大家分享。 在本例中出现了两条初始化的指令,即 START:MOV SP,#60H 和 MOV P0,#0FFH,其中 START 只是个标号,不是指令。当别处的程序想跳转到此处时需要加一个标号,当然在本例中不用 这两条初始化指令也不会影响到小灯闪烁效果,只是我们要养成习惯,因为有时如果不加 MOV SP,#60H 这条指令,程序会出现莫名其妙的不正常执行现象,那究竟是什么原因呢?这 我们就不得不提到两个非常重要的名词:堆栈、程序指针 PC。堆栈有些类似于火车站前临 时存放包裹的地方, 位于单片机内部的数据存储器 RAM 中。 如果在初始化时不设置堆栈的位 置,那单片机会自动给堆栈分配一个起始地址为 07H,而通过前面的学习我们知道内存 RAM 中的 07H 这个地方是第 0 组工作寄存器 R7 的空间,如果你既用了工作寄存器又向堆栈中存 储数据,这样在一个地方存放不同的数据,就会导致一些数据被覆盖,从而出现错误,结果 就导致了整个程序莫名其妙的不正常。 因此我们要养成习惯一定要在初始化中把堆栈设置在 一般区域中,通常都是设置在 50H 或 60H 以上,但是有时还是会出现错误,如有些初学者容 易将 MOV SP,#60H 写成 MOV SP,60H,仅仅是一个小小的“#”号就会使程序又一次出现莫名 其妙的不正常现象,原因是加“#”表示给堆栈指针 SP 赋一个 60H 的十六进制数据,即将堆 栈起始位置设置在了 60H 处,而不加“#”表示将内存 RAM60H 单元中的数据赋给堆栈指针 SP,而 60H 单元中的初始数据为 00H,所以不加“#”就相当于把堆栈的起始位置设置在了 00H 处,这和工作寄存器 R0 的地址又重叠了,所以此处一定要留意哦! ! ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 吕建:延时的时候单片机在做什么?还有延时的时间是怎么计算出来的? 行者:这个问题非常好,先给大家描述一下这样的场面,有一个智能机器人在玩一个彩 灯,他以非常快的速度拨动着彩灯的开关,我们看上去彩灯根本就没有闪烁,只是比一直亮 着的时候暗了些,机器人这时说了: “我想看到闪烁的效果” ,我温柔的对机器人说: “每当 你拨动一下开关后,你就绕着餐桌快速跑 5×5 圈(有一个时间间隔,否则太快,我们的视 力根本区分不开灯的亮灭) ,然后再拨动一次开关,你就会看到彩灯闪烁的效果了” 。其实我们这个场景和本例中单片机所处的状态很相似, 单片机将 P0.0 引脚置低 (灯亮)25 后,它亲自去执行延时程序,相当于在延时程序那大概执行 DJNZ 指令 250×250 次,起到延 时的作用,然后再将 P0.0 口置高,再延时,如此循环而已。大家想没想过机器人或单片机 累不累啊,我们如果能在单片机完成置低任务后,用一个小闹钟帮助它计时,这个时候单片 机不就可以休息或去做点其它的事情了吗?是的, 这种想法非常好, 我们在后面会和大家分 享定时器的用法和操作系统的用法, 到那时单片机就不会亲自去做这些没有什么智商的小事 了。对了,还有延时时间的计算方法,这个问题就相当于是从一个地方走到另一个地方所花 的时间一样,这取决于你走了多少步,每一步走的多快等。在本例中延时那段程序中有两类 指令:MOV R1,#250 和 DJNZ R1,D1,前一个指令耗时一个机器周期,后一个指令耗时 2 个机 器周期,一个机器周期代表多长时间?这个取决于我们用的晶振的频率,如果我们用的是 12M 的晶振,经过 51 单片机内部 12 分频后为 1M,那么一个机器周期的时间是 1 微秒,所以 可以计算出来延时时间,但是一般只需要估算一下即可,认为执行 D1:DJNZ R1,D1 这条指令 250×250 次,每次耗时 2 微秒,所以是 12500 微秒,约 0.125 秒。如果想改变延时时间, 只需要把赋给 R0、R1 的数值改变即可。总之,赋值给 R0 和 R1 的数值乘积再乘以 2 就是延 时的微秒数,需要注意两点:一是当外接晶振的频率改变时,一个机器周期就改变了,如接 一个 6M 晶振则一个机器周期为 2 微秒, 本例程序中的延时时间约为 0.25 秒; 二是当想延长 更长的时间,给 R0 和 R1 赋的值需要加大,但是不能超过 255(十六进制为 FFH) ,因为 51 单片机是 8 位单片机,R0 和 R1 都是 8 位的,能装的最大数据就是 8 个 1,即 255,还有就 是当把 R0 和 R1 都赋 0 的时候延时时间是最长的,因为第一次执行 DJNZ 指令后,R0、R1 变 成 255,不等于 0,所以程序继续执行,这个大家可以自己尝试一下就会很清楚了! ! ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 孝哲:如果我想在两处或多处调延时程序,而这些延时时间又不相同,那我就真的要编 写很多个延时程序吗?有没有简单的方法呢? 行者:当然有啊,其实思路很简单,我们只需要将原来赋给 R0 或 R1 的数据放在普通的 内存 RAM 的任意一个字节空间里, 在调延时程序时, 把想要的延时时间对应的数据放在这个 字节空间里,然后在执行延时程序时再把这个字节空间的数据传回给 R0 或 R1,这样我们在 每次调用延时程序前给这个字节空间存放的数据不同, 在执行延时程序时自然就会得到不同 的延时时间了,我们一起看一下下面的这段程序。ORG 0000H SJMP START ORG 0030H ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值START:MOV SP, #60HMOV P0, #0FFH ;让P0口输出高电平,即让灯灭 ;-----------------------------主程序----------------------------------MAIN:CLR P0.0 MOV CALL SETB MOV CALL SJMP 40H, #2 DELAY P0.0 40H, #200 DELAY MAIN ;P0.0口置低电平,灯亮 ;给内存RAM中的40H字节空间赋一个数据100 ;调用延时程序 ; P0.0口置高电平,灯灭 ;给内存RAM中的40H字节空间赋一个数据200 ;调延时程序 ;跳到MAIN ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处;--------------------------------延时子程序------------------------------DELAY:MOV R0, 40H D2:MOV R1, #250 D1:DJNZ R1, D126 DJNZ RET ENDR0, D2;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束从上面的程序执行结果中大家看到了什么现象呢?是不是小灯没有原来那么亮了, 原因 是在 CLR P0.0 指令后面调的延时较短,即小灯亮的时间短了,而在 SETB P0.0 指令后面 调的延时时间较长,即小灯不亮的时间相对长了,所以小灯消耗的平均功率小了,所以就暗 了(PWM 原理) 。3.2跑马灯一、设计任务要求 用单片机控制八个 LED 小灯,一个一个的点亮再熄灭,形成跑马灯,如此循环。 二、设计思想及硬件电路原理图分析 首先,硬件电路可以参照图 3-1,只是这次需要控制 8 个 LED 发光二极管,所以,我们 设计的电路如图 3-2 所示。软件的设计上只是需要点亮一个灯,调一个延时,然后在点亮临 近的一个灯的同时熄灭上一个灯后,再调延时程序,如此循环即会出现跑马灯现象。 .+540 314 .7 KC3 1 0u FV CCR1 1 0kEA99 8 7 6 5 4 3 2 1RST5 6 7 818C1 3 0p FY1 1 2M Hz19 20XN 1D GP0. 0 P0. 1 8 9S5 1 P0. 2 P0. 3 P1. 4 P0. 4 P1. 5 P0. 5 P1. 6 P0. 6 P1. 7 P0. 7X239 38 37 36 35 34 33 32R2 R3 R4 R5 R6 R7 R8 R94 70 D7+5 D8 D6 D5 D4 D3 D2 D1 .C2 3 0p F图 3-2 单片机控制 8 个 LED 小灯闪烁电路图三、源程序代码ORG 0000H SJMP START ORG ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;将P0.0置0,点亮一个LED小灯 ;延时 ;将P0.0置1,熄灭P0.0口的小灯 ;将P0.1置0,点亮一个LED小灯 ;延时0030HSTART:MOV SP, #60H MOV P0, #0FFH MAIN:CLR P0.0;------------------------主程序-------------------------CALL DELAY SETB P0.0 CLR P0.1 CALL DELAY27 SETB P0.1 CLR P0.2 CALL DELAY SETB P0.2 CLR P0.3 CALL DELAY SETB P0.3 CLR P0.4 CALL DELAY SETB P0.4 CLR P0.5 CALL DELAY SETB P0.5 CLR P0.6 CALL DELAY SETB P0.6 CLR P0.7 CALL DELAY SETB P0.7 SJMP MAIN DELAY:MOV R0, #250 D2:MOV D1:DJNZ RET END R1, #250 R1, D1;将P0.1置1,熄灭P0.1口的小灯 ;将P0.2置0,点亮一个LED小灯 ;延时 ;将P0.2置1,熄灭P0.2口的小灯 ;将P0.3置0,点亮一个LED小灯 ;延时 ;将P0.3置1,熄灭P0.3口的小灯 ;将P0.4置0,点亮一个LED小灯 ;延时 ;将P0.4置1,熄灭P0.4口的小灯 ;将P0.5置0,点亮一个LED小灯 ;延时 ;将P0.5置1,熄灭P0.5口的小灯 ;将P0.6置0,点亮一个LED小灯 ;延时 ;将P0.6置1,熄灭P0.6口的小灯 ;将P0.7置0,点亮一个LED小灯 ;延时 ;将P0.7置1,熄灭P0.7口的小灯 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束;--------------------延时子程序---------------------DJNZ R0, D2四、互动环节 玉琨: “我觉的这个设计很简单,可是程序代码写的很长,有没有其它简便方法了呢?” 行者: “当然有简单的方法了,我们是为了接着上一个例程的思路完成了本例,即用位 操作指令 SETB 和 CLR 对 P0.0-P0.7 引脚进行置高和置低操作,现在我们可以用一个数据传 输指令对整个 P0 口进行操作即上面的程序可以改写如下所示: ”ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MAIN:MOV P0, #0FEH ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;将P0.0置0,其余引脚置1 ;延时 ;将P0.1置0,其余引脚置1 ;延时 ;将P0.2置0,其余引脚置1 ;延时;--------------------------主程序-------------------------------CALL DELAY MOV P0, #0FDH CALL DELAY MOV P0, #0FBH CALL DELAY28 MOV P0, #0F7H CALL DELAY MOV P0, #0EFH CALL DELAY MOV P0, #0DFH CALL DELAY MOV P0, #0BFH CALL DELAY MOV P0, #7FH CALL DELAY SJMP MAIN DELAY:MOV R0, #250 D2:MOV D1:DJNZ RET END R1, #250 R1, D1;将P0.3置0,其余引脚置1 ;延时 ;将P0.4置0,其余引脚置1 ;延时 ;将P0.5置0,其余引脚置1 ;延时 ;将P0.6置0,其余引脚置1 ;延时 ;将P0.7置0,其余引脚置1 ;延时 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束;-----------------------------延时子程序--------------------------------DJNZ R0, D2侯杰: “我还有个问题, “MOV P0,#0FEH”这条语句中“FEH”前加“0”干什么?“FE” 后面的“H”又是什么意思,还有我觉得这个应该是个数据,还有其他表示方法吗?” 行者: “数据后面加“H”表示此数据是十六进制形式表示的数据;编译系统规定如果以 字母开头的十六进制数据前面需要加“0” ,如程序中所示,MOV P0,#7FH 这条语句中的数据 是以数字“7”开头的十六进制数据,因此不需要加“0” ;其实我们对于编写跑马灯程序而 言,还可以考虑用二进制的形式表示数据,这样会更清晰的看出来哪个灯亮,哪个不亮,当 然也可以采用十进制形式给 P0 口赋数据, 如我们可以通过下面三条语句给 P0 口赋数据: MOV P0,#0AAH,MOV P0,#B,MOV P0,#170,这三条指令会得到相同的结果,因为#0AAH、 #B 和#170 是同一个数据,只是分别用十六进制、二进制和十进制表示而已,因此 本例中的跑马灯程序还可以改写成下面的形式: ”ORG 0000H SJMP START ORG 0030H START:MOV SP,#60H MOV P0,#0FFH MAIN:MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;将P0.0置0,其余引脚置1 ;延时 ;将P0.1置0,其余引脚置1 ;延时 ;将P0.2置0,其余引脚置1 ;延时 ;将P0.3置0,其余引脚置1 ;延时 ;将P0.4置0,其余引脚置1 ;延时;------------------------------主程序-----------------------------29 MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY MOV P0,#B CALL DELAY SJMP MAIN DELAY:MOV R0,#250 D2:MOV R1,#250 D1:DJNZ R1,D1 DJNZ R0,D2 RET END;将P0.5置0,其余引脚置1 ;延时 ;将P0.6置0,其余引脚置1 ;延时 ;将P0.7置0,其余引脚置1 ;延时 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束;---------------------------延时子程序--------------------------苗娜: “记得在指令表的 111 条里面有个可以左移或右移数据的指令,我们不是可以用 在跑马灯上吗?” 行者: “你太有才了,是的,我们当然可以用这个指令,我们可以先给 P0 口赋一个数据 #B, 然后让此数据左移一位, 这样 “0” 就跑到第二位上了, 即数据变成#B, 以此类推我们就完成跑马灯程序了,左移指令是 RL A,右移指令是 RR A,下面练习一个 左移指令完成跑马灯的程序, 具体程序代码如下, 如何实现右移跑马灯请大家自行完成吧。 ”ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MOV A, #0FEH MOV R3, #07H MAIN:MOV RL A CALL DELAY DJNZ R3, MAIN MOV R3, #07H SJMP MAIN P0, A ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;赋初始值 ;移动次数 ;A中数据拷贝给P0 ;将A中数据左移1位 ;调延时程序 ;R3中数据减1不等于0跳到MAIN处 ;重新给R3赋数据7(移动次数);**************初始化程序**********;***************主程序*************;************延时子程序************* DELAY:MOV R0, #250 D2:MOV R1, #250 D1:DJNZ R1, D1 DJNZ RET END R0, D2 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束苗娜: “我还想编个其它花样的闪烁效果,比如让两侧的两个小灯同时亮,然后熄灭的 同时第二个和倒数第二个亮?,亮到中间后再倒着亮回来,你明白我的意思吗?”30 行者: “噢,我懂你的意思,就是两侧的马向中间跑,然后再跑回来,也是跑马灯,就 是多了一个马,两个马,哈哈,看看下面的程序吧! ”ORG 0000H ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MAIN:CLR CLR P0.0 P0.7 ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;将P0.0置0,点亮一个LED小灯 ;将P0.7置0,点亮一个LED小灯 ;延时 ;将P0.0置1,熄灭P0.0口的小灯 ;将P0.7置1,熄灭P0.7口的小灯 ;将P0.1置0,点亮一个LED小灯 ;将P0.6置0,点亮一个LED小灯 ;延时 ;将P0.1置1,熄灭P0.1口的小灯 ;将P0.6置1,熄灭P0.6口的小灯 ;将P0.2置0,点亮一个LED小灯 ;将P0.5置0,点亮一个LED小灯 ;延时 ;将P0.2置1,熄灭P0.2口的小灯 ;将P0.5置1,熄灭P0.5口的小灯 ;将P0.3置0,点亮一个LED小灯 ;将P0.4置0,点亮一个LED小灯 ;延时 ;将P0.3置1,熄灭P0.3口的小灯 ;将P0.4置1,熄灭P0.4口的小灯 ;将P0.2置0,点亮一个LED小灯 ;将P0.5置0,点亮一个LED小灯 ;延时 ;将P0.2置1,熄灭P0.2口的小灯 ;将P0.5置1,熄灭P0.5口的小灯 ;将P0.1置0,点亮一个LED小灯 ;将P0.6置0,点亮一个LED小灯 ;延时 ;将P0.1置1,熄灭P0.1口的小灯 ;将P0.6置1,熄灭P0.6口的小灯 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 SJMP START;------------------------主程序--------------------------CALL DELAY SETB P0.0 SETB P0.7 CLR P0.1 CLR P0.6 CALL DELAY SETB P0.1 SETB P0.6 CLR P0.2 CLR P0.5 CALL DELAY SETB P0.2 SETB P0.5 CLR P0.3 CLR P0.4 CALL DELAY SETB P0.3 SETB P0.4 CLR P0.2 CLR P0.5 CALL DELAY SETB P0.2 SETB P0.5 CLR P0.1 CLR P0.6 CALL DELAY SETB P0.1 SETB P0.6 SJMP MAIN DELAY:MOV R0, #250 D2:MOV D1:DJNZ R1, #250 R1, D1;--------------------延时子程序---------------------DJNZ R0, D231 RET END;子程序结束返回 ;程序结束苗娜: “这个看上去也太麻烦了,我们不是可以用 MOM P0,#B 这样的指令来实 现吗?” 行者: “你太聪明了,我有意用上面的位操作指令来完成,其实我是想告诉大家,当我 们想完成一个程序时,我们会有很多方法,只是大家觉得哪个方便就用哪个,用多了你自然 就会总结出来哪个编写的程序易懂, 哪个程序编译后占的字节空间少等等, 大家慢慢都能体 会出来,所以我们不要总是想啊想啊,把自己都想死了,应该先不管三七一十八动手写点程 序练练,其余的就留给时间大人帮我们总结改正吧,记住噢,不奔跑永远不会跌倒,所以要 多练习,错了就改,改了再错,然后再改?,改写的两个马一起跑的灯的程序如下: ”ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MAIN:MOV P0, #B ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,即让灯灭 ;将P0.0置0,将P0.7置0,其余引脚置1 ;将P0.1置0,将P0.6置0,其余引脚置1 ;延时 ;将P0.2置0,将P0.5置0,其余引脚置1 ;延时 ;将P0.3置0,将P0.4置0,其余引脚置1 ;延时 ;将P0.2置0,将P0.5置0,其余引脚置1 ;延时 ;将P0.1置0,将P0.6置0,其余引脚置1 ;延时 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束;------------------------------主程序-------------------------CALL DELAY MOV P0, #B CALL DELAY MOV P0, #B CALL DELAY MOV P0, #B CALL DELAY MOV P0, #B CALL DELAY MOV P0, #B CALL DELAY SJMP MAIN DELAY:MOV R0, #250 D2:MOV R1, #250 D1:DJNZ RET END R1, D1 DJNZ R0, D2 ;延时;---------------------------延时子程序--------------------------苗娜: “就这两个花样,也太单调了,如果要让这八个灯变幻出很多很多花样的闪烁方 式,那程序得编写多长啊,有没有什么方法用短一点的程序可以多些花样啊?” 行者: “当然有,不然的话还叫什么单片机啊。大家想一想我们之所以能得到流水灯这 样的花样,根本原因还是我们给 P0 口送了数据,从而导致有的灯亮了有的灯灭了,那么如 果我们想得到很多很多的闪烁花样, 只需要将事先编排好的数据存放在一个表里, 我们按照 顺序一个一个的取出来再送到 P0 口并加上合适的延时,这样就可以得到很多很多的闪烁花 样,当我们想要改变闪烁花样时,只需要改变这个表里的数据即可,其它程序我们根本不用 改,这个其实就是我以下部分要和大家分享的,我称这种闪烁位 LED 万能闪烁。 ”32 3.3LED 万能闪烁程序电路图还是如图 3-2 所示,硬件原理这里就不重复了,只是给大家一段程序,具体代码 如下所示:ORG 0000H SJMP START ORG 0030H START:MOV MOV MOV MAIN:MOV MOV MOVC MOV INC CALL CJNE MOV SJMP SP,#60H P0,#0FFH R2,#00H A,R2 DPTR,#TAB ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值60H ;给P0赋值FFH(十进制255) ;给R2赋0 ;R2里的数据拷贝给A ;给DPTR数据指针赋#TAB ;把此地址中的数据取出来再存到A中 P0,A R2 DELAY R2,#00H MAIN ;将数据送P0显示 ;R2中的数据加1 ;调延时子程序DELAY ;给R2重新赋0 ;跳转到MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回;*******************初始化程序**************************;------------------------------主程序-----------------------------A,@A+DPTR ;A和DPTR中的数加一起作为地址,R2,#72,MAIN ;R2和72比较不相等就跳转到MAIN处;---------------------------延时子程序-------------------------DELAY:MOV R0,#250 D2:MOV R1,#250 D1:DJNZ R1,D1 DJNZ R0,D2 RET TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH DB 0FFH,0FFH,00FH,0FFH,0FFH,000H,0FFH,0FFH DB 0FFH,07FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH DB 0FEH,0FFH,0FEH,0FDH,0FBH,0F7H,0EFH,0DFH DB 0BFH,07FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH DB 0FEH,0FFH,0FCH,0F3H,0CFH,03FH,0FFH,0FFH DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,03FH DB 0FCH,0F3H,0CFH,03FH,0FFH,03FH,0CFH,0F3H DB 0FCH,0FFH,0F0H,000H,0FFH,000H,000H,0FFH ;********************************************************* END;******************数据表*******************************在上面的程序里出现了几个新的指令,首先说一下 DB,DB 是定义字节伪指令,它的功 能是从程序存储器 ROM 中的某个单元开始, 存入一组规定好的 8 位二进制常数, 在本例中就33 是从 TAB 这个标号所在的地方开始存储了 72 个数据,这些数据是在向程序存储器 ROM 中下 载程序时“刻”在 ROM 中的,数据在掉电的情况下也不会丢失,其实,这些数据虽然我们称 之为数据, 实际上这些数据就是在编译后以程序代码的身份下载到 ROM 中了。 比如这样一条 指令 MOV 30H,#11H,这条指令的意思是把数据 11H 赋值给 30H 这个单元,这个 30H 单元是 内存 RAM 中的一个单元,当程序执行到这条时 30H 单元装的就变成了 11H,而当掉电了,这 个单元的数据可能就变成了随机数,短时间内也可能不变,还是 11H,时间长又变成了 0, 这会我们应该清楚了吧!接下来我们说一下 MOVC A,@A+DPTR,这个 MOVC 指令的意思是将程 序存储器 ROM 中的数据拷贝到累加器 A 中,那究竟是把 ROM 中哪个单元的数据拷贝给了 A 呢?其实就是把 A 和 DPTR 相加后的这个数作为地址,把这个地址里的数据拷贝给了 A,其 中符号“@”就表示 A 和 DPTR 相加后的这个数作为地址里面的数据的意思,那 A 里装的又是 什么呢?A 里的数据是通过 MOV A,R0 这条指令得来的,即是 R0 拷贝给 A 的,R0 里装的又 是什么呢?在初始化中最开始是通过 MOV R0,#00H 给 R0 中装了个数据 0, DPTR 里的数据是 通过 MOV DPTR,#TAB 这条指令得来的, 即 DPTR 中装的是 TAB 这个标号所在的地方的地址号, 那现在大家应该清楚了,A+DPTR 的结果就等于 DPTR 原来的数据,即是 TAB 这个标号所在的 地方的地址,把这个地址里的数据取出来给了 A,也就相当于是把第一个数据 0FEH 给了 A, 再把这个数据通过 MOV P0,A 这条指令传给了 P0,所以会有一个小灯亮,其余七个都不亮; 那表中的下一个数据 0FDH 又是怎么取出来的呢?是这样,在程序中有一条 INC R0 指令, 意思是将 R0 中的数加 1,这样 R0 中的数就变成了 1,后面还有一条 CJNE R0,#72,MAIN, 这条指令的意思是让 R0 和 72 比较,如果不相等就跳转到 MAIN 处执行,如过相等就执行它 下面一条指令,即执行 MOV R0,#00H 这条指令,当然此时 R0 等于 1,一定不等于 72,所以 程序跳转到 MAIN 处继续执行 MOV A,R0,这样就把 R0 中的 1 拷贝给了 A,此时 A 中的数据 就是 1 了,然后再执行 MOVC A,@A+DPTR 时,就取表中第二个数据 0FDH 了,如此循环 72 次,直到把最后一个数据取出来为止,然后 R0 重新赋值 0,再从第一个数据取,如此循环 自行。 在上面这段程序里我们一定要好好体会 MOVC A,@A+DPTR 这条指令是如何把数据取出 来的,这个就好像我们村里来了个陌生人,到了村头遇到你了,他说他要去的人家是从一棵 大树开始向东数第三家,你就可以先帮他找到那棵大树,然后再向东数第三家便是了。过两 天又来个陌生人说去从一棵大树数第八家, 你也是一样先帮他找到大树然后再数第八家又帮 助这个人找到了地点。这里是取数据,DPTR 中放的就相当于是这棵大树的地址,本例中是 TAB 标号所在处,A 中的数就相当于是那个人所说的第几家,所以我们只需要找到 TAB 数据 表头所在的地址, 再在这个地址基础上加上 A 中的数, 这样就可以确定出我们真正要找的数 据了。34 第4天 LED 数码管的应用4.1LED 数码管显示原理及显示方式在单片机系统中, 经常用 LED 数码管显示器来显示单片机系统的工作状态和运算结果等 各种相信。LED 数码管显示器是单片机于人对话的一种重要输出设备,那么数码管是如何工 作的呢?还记得我们小时候玩过的“火柴棒游戏”吗,几根火柴棒组合起来,可以拼成各种 各样的图形,LED 显示器实际上就是利用这个原理做成的,其结构示意图如图 4-1 所示。 八段 LED 显示器是由 8 个发光二极管组成。其中 7 个长条形的发光管排列成一个“日” 字形, 另一个圆点形的发光管在显示器的右下角作为 显示小数点用, 它能显示各种数字 及部份英文字母。LED 显示器有两种不同的连接形式:一种是 8 个发光二极管的正极连在一 起,负极则各自独立,称之为共阳极 LED 显示器,使用时公共阳极接+5V;这时阴极接低电 平的发光二极管就导通点亮, 接高电平的则不亮; 另一种是 8 个发光二极管的负极连在一起, 正极则各自独立,称之为共阴极 LED 显示器,使用时公共阴极接地,这时阳极接高电平的发 光二极管就导通点亮,接低电平的则不亮。它们的内部电路图如图 4-2 所示。图4-1 数码管示意图图4-2 数码管内部电路图4.2LED 数码管分类及驱动从尺寸上分,LED 数码管显示器的种类很多,常用的有 0.3、0.5、0.8、1.0、1.2、1.5、 1.8、2.3、3.0、4.0、5.0 寸等。一般小于 1.0 寸的为单管芯,1.2~1.5 寸为双管芯,1.8 寸以上的为 3 个以上管芯,因而它们的供电电压不同,一般每个管芯的压降为 2V 左右。通 常,0.8 寸以下采用 5V 供电,1.0~2.3 寸采用 12V 供电,3.0 以上的选择更高电压供电。 从颜色上分,LED 数码管显示器有红色、黄绿、黄色、橙色、蓝色、纯绿和白色等多种35 颜色,一般红色较为普通,价格便宜,蓝色价格较高。 驱动电路中的限流电阻 R 通常根据 LED 的工作电流计算得到。 R=(VCC―VLED)/ILED, 式 中 VCC 为电源电压 (+5V) , VLED 为 LED 压降 (约为 2V) , ILED 为工作电流 (一般可取 1~20mA) , R 通常为几百欧姆。 一般 LED 数码管工作时的电流在 10mA 左右亮度比较适中,而 89S51 单片机的 I/O 口 具有 20mA 的灌电流输出能力,因此可以直接驱动共阳极的 LED 数码管。由于 89S51 单片 机 I/O 口的拉电流能力较弱,因此一般不要直接驱动共阴极的 LED 数码管,如果一定要用 共阴极 LED 数码管可以另加驱动电路。4.3点亮一个 LED 数码管图 4-3 是 89S51 单片机与一个共阳 LED 数码管的连接电路图, 如果想让 LED 数码管先是 “0” ,则需要 a、b、c、d、e 和 f 段亮,而 g 段和 h 段不能亮,因此需要单片机 P0.0~P0.5 输出低电平,而 P0.6 和 P0.7 输出高电平。. +5 4 .7 K40C3 1 0u F 9 R1 1 0k .V CCEA319 8 7 6 5 4 3 2 1DS1 R2 R3 R4 R5 R6 R7 R8 R9 4 70 1 2 3 4 5 6 7 8a b c d e f g dp DPY a f e g d b c dpRSTXN 1D GP0. 0 P0. 1 U1 P0. 2 P0. 3 8 9S5 1 P0. 4 P0. 5 P0. 6 P0. 7X2CO M 9+539 38 37 36 35 34 33 3218C1 3 0p FY1 1 2M Hz19 20C2 3 0p F图 4-3 单片机点亮单个共阳数码管具体程序代码如下:ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MAIN:MOV CLR SJMP P0,#B P2.7; $ ;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,数码管不显示信息 ;将P0.0~P0.5置0,将P0.6和P0.7置1;------------------------------初始化-----------------------------;------------------------------主程序----------------------------;此条在本例中没用(编书时选的板子和下图电路不同) ;停在当前位置END;程序结束36 4.4LED 数码管显示段码如果还想显示其它数字,则可以用同样的方法看哪段应该亮,哪段不应该亮,然后就知 道需要从 P0 口送出什么数据了。 象数字 0~9 及部分字母都很常用, 如果每次显示都需要重 新算未免有些繁琐,所以我把这些数字按照图 4-3 这样的接法所对应的段码总结如表 4-1 所示。 需要注意的是当我们在编程软件中输入这些数据时, 以字母开头的数据前要补加一个 “0” ,否则系统在编译时认为有错误! ! !表4-1 数码管显示段码字符 字形 dp g f e d c b a 共阳笔段码 共阴笔段码011000000C0H3FH111111001F9H06H210100100A4H5BH310110000B0H4FH41001100199H66H51001001092H6DH61000001082H7DH711111000F8H07H81000000080H7FH91001000090H6FH不显示11111111FFH00H37 4.5静态显示从上面的内容中, 我们已经懂得数码管的原理和如何点亮一个数码管了, 现在大家想不 想用数码管显示出自己的生日?可能你会认为一个数码管怎么显示生日啊?对, 一个数码管 是不可以,那我们就多接几个。大家看看 89S51 单片机有 P0、P1、P2 和 P3 四个口,如果每 个数码管都这样去连接, 那我们最多只能接上四个数码管, 而我们显示生日一般要八个数码 管,还有,单片机也不能就接几个数码管啊,还得留几个“腿儿”用来接个蜂鸣器或者按键 之类的设备啊。那该怎么办呢?这就需要借助外围器件来接数码管,具体的器件有很多,我 们这里就不一个一个介绍了。 按照显示方式的不同, 可以分为静态显示和动态显示两种。 所谓静态显示就是只要单片 机一次把需要显示的数据送到了数码管上以后, 数码管上的数据就会一直存在不消失, 除非 要改变显示的数据, 单片机将不需要再去理会数码管。 静态显示的优点就是显示程序十分简 单并且显示亮度大(显示亮度大这是为什么?因为静态显示数码管是一直处于亮的状态) ; 缺点就是每一个数码管的每一个段(如 a 段)都要独占具有锁存功能器件的一个输出口,因 此占有的 I/O 口线较多, 硬件成本也较高, 所以静态显示法常用在显示器数目较少的应用系 统中。 图 4-4 是一个静态显示的图。因为每个数码管的每一段(如 a 段)都要占一个独立的引 脚。这样太浪费单片机的 I/O 引脚了,所以单片机找来两个驱动芯片 74HC573,用来锁存需 要显示的数据。单片机通过 P0 口的八个“腿儿”分两次把待显示的数据送到两个 74HC573 芯片上进行所存。你可能觉得奇怪,单片机的 P0 口和两片 74HC573 都连着,数据不会送乱 了吗?不会的, 因为 P1.0 和 P1.1 两个引脚会告诉两片 74HC573 本次显示数据是给他们谁的, 谁接到使能信号谁就接收本次的显示数据。 单片机一旦把显示数据锁存到 74HC573 中就不需 要再管了,数据将一直保留在 74HC573 上供数码管显示,这就是静态显示。DS1 a 1 b 2 c 3 d 4 e 5 f 6 g 7 dp8 9a b c d e f g dp DPY a f e g d b c dpDS2 a 1 b 2 c 3 d 4 e 5 f 6 g 7 dp8 9a b c d e f g dp DPY a f e g d b c dpcom DPY_7 -SEG_DPcom DPY_7 -SEG_DP U2 1 11 OC C 1D 2D 3D 4D 5D 6D 7D 8D 7 4HC5 7 3 VCC GND 1Q 2Q 3Q 4Q 5Q 6Q 7Q 8Q VCC 20 10 19 18 17 16 15 14 13 12U1 P1. 0 D0 D1 D2 D3 D4 D5 D6 D7 P1. 1 P0. 0 ~P0 .7 1 11 2 3 4 5 6 7 8 9 OC C 1D 2D 3D 4D 5D 6D 7D 8D 7 4HC5 7 3 VCC GND 1Q 2Q 3Q 4Q 5Q 6Q 7Q 8QVCC 20 10 19 18 17 16 15 14 13 12 a b c d e f g dp D0 D1 D2 D3 D4 D5 D6 D72 3 4 5 6 7 8 9图 4-4 数码管静态显示驱动电路38 4.6动态显示生日动态显示实际是利用人眼的“视觉暂留”效应。方法是将所有数码管的 8 个笔画段 a~h 的各同名端分别并接在一起,并把他们接在单片机的字段输出口上。为了防止各个数 码管同时显示相同的数字, 各个数码管的公共端 COM 还要受到另一组信号的控制, 即它们接 到位输出口上。这样,对于一组数码管显示器需要由两组信号来控制:一组是字段输出口输 出的字形代码,又来控制显示的字形,成为段码;另一组是位输出口输出的控制信号,用来 选择第几个显示器工作,称为位码。因此,所谓动态,就是利用循环扫描的方式,分时轮流 选通各个数码管的公共端,使各个数码管轮流导通,在导通的同时送上不同的段码。当扫描 速度达到一定程度时,人眼就分辨不出来了,认为各个数码管在同时显示。 如图 4-5 所示, P0 口作为段控制, P2 口通过八个 PNP 型三极管 8550 控制数码管的八个 COM 公共端。如果要第一个数码管显示数据,P2.7 需要输出低电平 0,则此时第一个 PNP 三 极管导通, 通过第一位数码管的 COM 公共端向第一个数码管供电; 如果要第二个数码管显示 数据,P2.6 需要输出低电平 0,则此时第二个 PNP 三极管导通,通过第二位数码管的 COM 公共端向第二个数码管供电。以此类推可以分时点亮 8 个 LED 数码管数。但是,需要注意不 能让 P2.0~P2.7 中的两个或两个以上同时输出低电平 0,否则就会造成显示混乱,除非两 个数码管上要显示的内容相同。本例中数码管选择的是 SM410364 共阳极四位一体的 LED 显 示器。由于在前面我们提过要显示生日,需要 8 个数码管,所以该型号的 LED 数码管选了两 个,每个上面有四个(这四个数码管的各个同名段在内部是连接好的,只是四个 COM 公共端 是分开的,如图 4-5 所示) ,因此能显示 8 位数据,三极管采用 PNP 型 8550,P0 口接的限流 电阻是 8 个 470 欧姆的;P2 口上接的是 8 个 4.7K 的电阻;P0 口接的 8 个上拉电阻都是 10K 的;其它部分如复位电路、晶振电路、电源及单片机 31 脚的处理方法同 4-3。图 4-5 数码管动态显示驱动电路现在我们终于把电路搭建起来了,我想把
这个重要的日子显示在数码管上, 该如何写程序代码呢?请大家参考下面的代码:39 ORG 0000H SJMP START ORG 0030H START:MOV SP, #60H MOV P0, #0FFH MOV P2,#0FFH MAIN:MOV CLR CALL SETB CLR CALL SETB MOV CLR P0,#0F9H P2.7 DELAY P2.7 P2.6 DELAY P2.6 P0,#0F8H P2.5;复位时程序从此开始 ;跳到START进行初始化 ;初始化程序从30H开始 ;给堆栈指针赋值 ;让P0口输出高电平,数码管不显示信息 ;P2口输出高电平,所有三级管均不导通,数码管熄灭 ;将“1”对应的段码“F9H”送到P0口 ;将P2.7置0,让第一个三极管导通使得第一个数码管显示 ;调用延时程序 ;将P2.7置1,让第一个三极管截止使得第一个数码管不显示 ;将“9”对应的段码“90H”送到P0口 ;将P2.6置0,让第二个三极管导通使得第二个数码管显示 ; 调用延时程序 ;将P2.6置1,让第二个三极管截止使得第二个数码管不显示 ;将“7”对应的段码“F8H”送到P0口 ;将P2.5置0,让第三个三极管导通使得第三个数码管显示 ; 调用延时程序 ;将P2.5置1,让第三个三极管截止使得第三个数码管不显示 ;将“8”对应的段码“80H”送到P0口 ;将P2.4置0,让第四个三极管导通使得第四个数码管显示 ; 调用延时程序 ;将P2.4置1,让第四个三极管截止使得第四个数码管不显示 ;将“1”对应的段码“F9H”送到P0口 ;将P2.3置0,让第五个三极管导通使得第五个数码管显示 ; 调用延时程序;------------------------------初始化-----------------------------;------------------------------主程序-----------------------------MOV P0,#90HCALL DELAY SETB P2.5 MOV CLR P0,#80H P2.4CALL DELAY SETB P2.4 MOV CLR P0,#0F9H P2.3CALL DELAY40 SETB P2.3 MOV CLR P0,#0A4H P2.2;将P2.3置1,让第五个三极管截止使得第五个数码管不显示 ;将“2”对应的段码“A4H”送到P0口 ;将P2.2置0,让第六个三极管导通使得第六个数码管显示 ; 调用延时程序 ;将P2.2置1,让第六个三极管截止使得第六个数码管不显示 ;将“1”对应的段码“F9H”送到P0口 ;将P2.1置0,让第七个三极管导通使得第七个数码管显示 ; 调用延时程序 ;将P2.1置1,让第七个三极管截止使得第七个数码管不显示 ;将“9”对应的段码“90H”送到P0口 ;将P2.0置0,让第八个三极管导通使得第八个数码管显示 ; 调用延时程序 ;将P2.0置1,让第八个三极管截止使得第八个数码管不显示 ;程序跳转至MAIN处 ;给R0赋值 ;给R1赋值 ;R1减1不等于0跳到D1处 ;R0减1不等于0跳到D2处 ;子程序结束返回 ;程序结束CALL DELAY SETB P2.2 MOV CLR P0,#0F9H P2.1CALL DELAY SETB P2.1 MOV P0,#90H CLR P2.0 CALL DELAY SETB P2.0 SJMP MAIN DELAY:MOV R0,#10 D2:MOV R1,#20 D1:DJNZ R1,D1 DJNZ R0,D2 RET END;---------------------------延时子程序--------------------------4.70-99 循环自加计数器一、设计任务要求 用单片机控制两个 LED 数码管,实现 0~99 循环自加计数器。 二、设计思想及硬件电路原理图分析 首先,硬件电路可以参照图 4-5,只是这次需要控制 2 个 LED 数码管,所以,在软件程 序里面只要控制两个数码管即可,和上例比较还容易些,但是,难点在于我们这次编的是 0~99 循环自加计数器,即数据是在不断变化(0、1、2?99) ,而上一例显示生日的程序中 数据不需要变化, 那该怎么实现呢?思路是这样: 我们定义一个变量, 在主程序中程序每 “跑” 一圈儿后就让这个变量加 1,然后把最新的数据送到数码管上去显示,这个方法肯定是可以 的,但问题是,我们怎么知道某时某刻这个数据变成几了,该怎么给数码管送这个数据呢? 其实,我们可以把 0~9 这十个数据对应的数}

我要回帖

更多关于 脚手架钢管规格型号 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信