为什么P10端口接地atmel单片机烧录软件才能烧录进去程序

单片机引脚介绍
单片机的40个引脚大致可分为4类:电源、时钟、控制和I/O引脚。
⑴ VCC - 芯片电源,接+5V;
⑵ VSS - 接地端;
⒉ 时钟:XTAL1、XTAL2 - 晶体振荡电路反相输入端和输出端。
⒊ 控制线:控制线共有4根,
⑴ ALE/PROG:地址锁存允许/片内EPROM编程脉冲
① ALE功能:用来锁存P0口送出的低8位地址
② PROG功能:片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。
⑵ PSEN:外ROM读选通信号。
⑶ RST/VPD:复位/备用电源。
① RST(Reset)功能:复位信号输入端。
② VPD功能:在Vcc掉电情况下,接备用电源。
⑷ EA/Vpp:内外ROM选择/片内EPROM编程电源。
① EA功能:内外ROM选择端。
② Vpp功能:片内有EPROM的芯片,在EPROM编程期间,施加编程电源Vpp。
80C51共有4个8位并行I/O端口:P0、P1、P2、P3口,共32个引脚。P3口还具有第二功能,用于特殊信号输入输出和控制信号(属控制总线)。
拿到一块芯片,想要使用它,首先必须要知道怎样连线,我们用的一块称之为89C51的芯片,下面我们就看一下如何给它连线。
1、 电源:这当然是必不可少的了。单片机使用的是5V电源,其中正极接40管脚,负极(地)接20管脚。
振蒎电路:单片机是一种时序电路,必须供给脉冲信号才能正常工作,在单片机内部已集成了振荡器,使用晶体振荡器,接18、19脚。只要买来晶体震荡器,电容,连上就能了,按图1接上即可。
3、 复位管脚:按图1中画法连好,至于复位是何含义及为何需要复要复位,在单片机功能中介绍。
4、 EA管脚:EA管脚接到正电源端。 至此,一个单片机就接好,通上电,单片机就开始工作了。
我们的第一个任务是要用单片机点亮一只发光二极管LED,显然,这个LED必须要和单片机的某个管脚相连,不然单片机就没法控制它了,那么和哪个管脚相连呢?单片机上除了刚才用掉的5个管脚,还有35个,我们将这个LED和1脚相连。(见图1,其中R1是限流电阻)
按照这个图的接法,当1脚是高电平时,LED不亮,只有1脚是低电平时,LED才发亮。因此要1脚我们要能够控制,也就是说,我们要能够让1管脚按要求变为高或低电平。即然我们要控制1脚,就得给它起个名字,总不能就叫它一脚吧?叫它什么名字呢?设计51芯片的INTEL公司已经起好了,就叫它P1.0,这是规定,不能由我们来更改。
名字有了,我们又怎样让它变'高'或变'低'呢?叫人做事,说一声就能,这叫发布命令,要计算机做事,也得要向计算机发命令,计算机能听得懂的命令称之为计算机的指令。让一个管脚输出高电平的指令是SETB,让一个管脚输出低电平的指令是CLR。因此,我们要P1.0输出高电平,只要写SETB
P1.0,要P1.0输出低电平,只要写 CLR P1.0就能了。
现在我们已经有办法让计算机去将P10输出高或低电平了,但是我们怎样才能计算机执行这条指令呢?总不能也对计算机也说一声了事吧。要解决这个问题,还得有几步要走。第一,计算机看不懂SETB
CLR之类的指令,我们得把指令翻译成计算机能懂的方式,再让计算机去读。计算机能懂什么呢?它只懂一样东西&&数字。因此我们得把SETB
P1.0变为(D2H,90H ),把CLR P1.0变为 (C2H,90H
),至于为什么是这两个数字,这也是由51芯片的设计者--INTEL规定的,我们不去研究。第二步,在得到这两个数字后,怎样让这两个数字进入单片机的内部呢?这要借助于一个硬件工具&编程器&。如果你还不知道是什么是编程器,我来介绍一下,就是把你在电脑上写出来来的代码用汇编器等编译器生成的一个目标烧写到单片机的eprom里面去的工具,80c51这种类型的单片机编程是一件很麻烦的事情,必要要先装到编程器上编程后才能在设备上使用,而目前最新的AT89s51或者STC89C51单片机能支持在线编程(isp)功能,不用拔出来利用简单的电路就可以实现把代码写入单片机内部,本站有详细的编程器制作教程下载。
下面我们来实战一下:下图(图2)所示的软件名字叫keil
&&点此下载,是用来编写程序代码并生成一个可以写入到单片机芯片的Hex文件(我们人要控制单片机只能用汇编语言或者C语言而单片机不认识怎么办呢?所以keil这个软件就把程序语言转换成了一种特定格式的Hex文件,只要把这个文件下载到单片机芯片单片机就会按我们程序的思路来运行)
图2 (keil编程软件) && 本例keil工程文件点此下载
图3(下载软件) && 点击此处下载
好了&& ,我们把 SETB P1.0
这条汇编语句用keil软件编译生成Hex文件,然后用图3所示的软件和图1所示的硬件(用串口连接电脑)下载到我们已经做好的电路板上的单片机芯片里去(图省事的话建议直接买个开发板),然后接通电源&&什么?灯不亮?这就对了,因为我们写进去的指令就是让P10输出高电平,灯当然不亮,要是亮就错了。所以要将keil编缉区的内容改为CLR
P1.0,重新编译生成Hex文件,重新下载,接电,好,灯亮了。因为我们写入的Hex就是让P10输出低电平的指令。这样我们看到,硬件电路的连线没有做任何改变,只要改变写入单片机中的内容,就能改变电路的输出效果。1.bit和sbit都是C51扩展的变量类型。
&&&&&&& bit和int char之类的差不多,只不过char=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。除非你指定,否则这个地址是随机的。这个地址是整个可寻址空间,RAM+FLASH+扩展空间。bit只有0和1两种值,意义有点像Windows下VC中的BOOL。
&&&&&&& sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。一旦用了sbi xxx = REGE^6这样的定义,这个sbit量就确定地址了。sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。
2.bit位标量&&&&&&& bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。
3.sfr特殊功能寄存器&&&&&& sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。
sfr P1 = 0x90; //定义P1 I/O 口,其地址90H&&&&&&& sfr 关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定的含义如P1 口可以用P1 为名,这样程序会变的好读好多.等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH),具体可查看附录中的相关表.
&&&&&&&&& sfr 是定义8 位的特殊功能寄存器而sfr16 则是用来定义16 位特殊功能寄存器,
如8052 的T2 定时器,可以定义为:sfr16 T2 = 0xCC; //这里定义8052 定时器2,地址为T2L=CCH,T2H=CDH用sfr16 定义16 位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上.注意的是不能用于定时器0 和1 的定义.sbit 可定义可位寻址对象.如访问特殊功能寄存器中的某位.其实这样应用是经常要用的如要访问P1 口中的第2 个引脚P1.1.我们可以照以下的方法去定义:(1) sbit 位变量名=位地址sbit P1_1 = Ox91;这样是把位的绝对地址赋给位变量.同sfr 一样sbit 的位地址必须位于80H-FFH 之间.(2) sbit 位变量名=特殊功能寄存器名^位位置sft P1 = 0x90;sbit P1_1 = P1 ^ 1; //先定义一个特殊功能寄存器名再指定位变量名所在的位置,当可寻址位位于特殊功能寄存器中时可采用这种方法(3) sbit 位变量名=字节地址^位位置sbit P1_1 = 0x90 ^ 1;这种方法其实和2 是一样的,只是把特殊功能寄存器的位址直接用常数表示. 在C51存储器类型中提供有一个bdata 的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中,可以将要求可位录址的数据定义为bdata,如:un //在可位录址区定义ucsigned char 类型的变量ibint bdata ab[2]; //在可位寻址区定义数组ab[2],这些也称为可寻址位对象sbit ib7=ib^7 //用关键字sbit 定义位变量来独立访问可寻址位对象的其中一位sbit ab12=ab[1]^12;操作符"^"后面的位位置的最大值取决于指定的基址类型,char0-7,int0-15,long0-31.
sfr 并标准C 语言的关键字,而是Keil 为能直接访问80C51 中的SFR 而提供了一个新的关键词,其用法是:sfrt 变量名=地址值。2)符号P1_0 来表示P1.0 引脚。在C 语言里,如果直接写P1.0,C 编译器并不能识别,而且P1.0 也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0 是不是就是P1.0呢?你这么认为,C 编译器可不这么认为,所以必须给它们建立联系,这里使用了Keil C的关键字sbit 来定义,sbit 的用法有三种:第一种方法:sbit 位变量名=地址值第二种方法:sbit 位变量名=SFR 名称^变量位地址值第三种方法:sbit 位变量名=SFR 地址值^变量位地址值如定义PSW 中的OV 可以用以下三种方法:sbit OV=0xd2 (1)说明:0xd2 是OV 的位地址值sbit OV=PSW^2 (2)说明:其中PSW 必须先用sfr 定义好sbit OV=0xD0^2 (3)说明:0xD0 就是PSW 的地址值因此这里用sfr P1_0=P1^0;就是定义用符号P1_0 来表示P1.0 引脚,如果你愿意也可以起P10 一类的名字,只要下面程序中也随之更改就行了。
*AT89C51的特殊功能寄存器表请看附录二
4.sfr16 16位特殊功能寄存器&&&&&&&&& sfr16占用两个内存单元,值域为0~65535。sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,好定时器T0和T1。
5.sbit可录址位&&&&&&&& sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。如先前我们定义了sfr P1 = 0x90; //因P1端口的寄存器是可位寻址的,所以我们可以定义sbit P1_1 = P1^1; //P1_1为P1中的P1.1引脚//同样我们可以用P1.1的地址去写,如sbit P1_1 = 0x91;这样我们在以后的程序语句中就可以用P1_1来对P1.1引脚进行读写操作了。通常这些可以直接使用系统提供的预处理文件,里面已定义好各特殊功能寄存器的简单名字,直接引用可以省去一点时间,我自己是一直用的。当然您也可以自己写自己的定义文件,用您认为好记的名字。
阅读(...) 评论()您是不是在找:
买家还在看:
当前位置:
关注行业资讯
仙童 FQD18P10
MOS管,单片机,电子
&0.58 - &1
detail3e达人选购¥74000.00¥22313.00¥700.00¥320.00¥
detail3e周边优质供应商广东省深圳市广东省深圳市广东省深圳市广东省深圳市
同参数产品
同参数产品
同参数产品
沟道类型:
同参数产品
导电方式:
同参数产品
同参数产品
封装外形:
同参数产品
同参数产品
慧聪网厂家深圳市浩吉发电子有限公司为您提供仙童 FQD18P10
MOS管,单片机,电子的详细产品价格、产品图片等产品介绍信息,您可以直接联系厂家获取仙童 FQD18P10
MOS管,单片机,电子的具体资料,联系时请说明是在慧聪网看到的。
detail3e相关商品推荐¥74000.00¥22313.00¥700.00¥320.00¥¥0.90¥0.45¥1.30热门商品推荐 ¥74000.00 ¥22313.00 ¥700.00 ¥320.00 ¥ ¥0.90 ¥0.45 ¥1.30
detail3e店内热门商品¥30.00¥1.07¥0.46¥30.00
detail3e单片机系列相关资源单片机系列热门产品搜索更多&热门商机最新商机
提示:您在慧聪网上采购商品属于商业贸易行为。以上所展示的信息由卖家自行提供,内容的真实性、准确性和合法性由发布卖家负责,请意识到互联网交易中的风险是客观存在的。推荐使用,保障您的交易安全!
所在地:广东省&&
联系人:朱钦元 & 先生
075 ******
请供应商联系我
手机号不能为空
姓名不能为空
请供应商联系我
您对该公司的咨询信息已成功提交请注意接听供应商电话。
detail3e关于单片机
detail3e同类其他品牌
detail3e您是不是在找
您采购的产品:
请输入采购产品
您的手机号码:
请输入手机号码
*采购产品:
请输入采购产品
*采购数量/单位:
请输入采购数量
请选择单位
*采购截止日期:
请输入正确的手机号码
请输入验证码
*短信验证码:
<input id="valid_Code1" maxlength="6" placeholder="请输入验证码" name="VALIDCODE" class="codeInput" onkeyup="this.value=this.value.replace(/\D/g,'')" onkeypress="if(event.keyCode
57) event.returnValue =" type="text">
免费获取验证码
为了安全,请输入验证码,我们将优先处理您的需求!
请输入验证码
发送成功!
慧聪已收到您的需求,我们会尽快通知卖家联系您,同时会派出采购专员1对1为您提供服务,请您耐心等待!
075 ******
联系人:朱钦元&经理
公司名称:深圳市浩吉发电子有限公司
备注:点击关注按钮后才可自动收到卖家电话
请输入正确的手机号码
请输入验证码
*短信验证码:
免费获取验证码
为了安全,请输入验证码,我们将优先处理您的需求!
请输入验证码
按字母分类 :还没有帐号? 赶紧
用户版块帖子
求单片机STC12C5A60S2和P10LED单元板(12接口)接线方式及驱动代码
在线时间198小时
我做好了一个STC单片机想用它直接连接 P10的LED屏&&实现汉字 或图案显示那位有资料分享下电路部分或者代码都可以 [ 此帖被yangbin在 21:46重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请
后查看;或者
成为会员获得更多权限
在线时间198小时
郁闷,没有一个大师来指导下吗!我的硬件都就绪了
在线时间198小时
谁帮我送STC12A5C60S2一片
UID:829109
在线时间1402小时
M币589专家2
我只有08接口程序,没有12接口的
在线时间198小时
是和我一样的单片机吗你点亮的屏是动态还是静态要是12转成08接口是否可以纠结有大师指点迷津吗求普度
UID:812763
在线时间278小时
M币277专家3
P10单元板驱动程序&&=740) window.open('http://bbs.mydigit.cn/skins/Default/topicface/face1.gif');" style="max-width:100%;" onload="if(is_ie6&&this.offsetWidth>740)this.width=740;" title="" alt=""> Post By: 13:22:52 包含画点、画直线、画矩形、画圆函数等,非常实用。#include &w78e052.h&#include &intrins.h&#include &ASCII.h&#include&math.h&#define uchar unsigned char&&#define uint unsigned int #define NOP&&&& _nop_() typedef unsigned char u8;typedef unsigned int&&u16;typedef unsigned char u32;sbit OE&&&& = P0^2; sbit A1&&&& = P0^3; sbit B1&&&& = P0^4; sbit SHCP=P0^5;&&&&//11脚SHCP&&&&移位时钟 sbit STCP=P0^6;&&&&//12脚STCP&&&&锁存时钟 sbit DATA=P0^7;&&&&//数据输入 sbit BEEP=P1^1;unsigned char ip,tp,min,u16unsigned char PLAYBUF[64];u8 code yi_dong[31] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,12,11,10,9,8,7,6,5,4,3,2,1,0};u8 code tab[10] = {&&};const uchar code table[160]={0x10,0x00,0x08,0x0E,0x7F,0x70,0x22,0x40,0x14,0x40,0xFF,0x7E,0x08,0x48,0x08,0x48,0xFF,0x48,0x08,0x48,0x2C,0x48,0x2A,0x88,0x4A,0x88,0x89,0x08,0x2A,0x08,0x10,0x08,0x00,0x00,0x00,0x40,0x78,0x40,0x0B,0xF8,0x10,0x48,0x17,0xFE,0x20,0x48,0x7B,0xF8,0x08,0x40,0x4B,0xFC,0x48,0x40,0x28,0x40,0x17,0xFC,0x28,0x40,0x46,0x40,0x81,0xFE, /*------------------------------------------------------------------------------ ;&&源文件 / 文字 : 工 ;&&宽×高(像素): 15× ------------------------------------------------------------------------------*/ 0x00,0x00,0x00,0x00,0x3F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00, 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00, /*------------------------------------------------------------------------------ ;&&源文件 / 文字 : 作 ;&&宽×高(像素): 15×16 ------------------------------------------------------------------------------*/ 0x08,0x80,0x0C,0x80,0x09,0x00,0x13,0xFE,0x12,0x80,0x34,0x88,0x50,0xFC,0x90,0x80, 0x10,0x80,0x10,0x84,0x10,0xFE,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, /*------------------------------------------------------------------------------ ;&&源文件 / 文字 : 室 ;&&宽×高(像素): 15×16 ------------------------------------------------------------------------------*/ 0x00,0x00,0x02,0x00,0x01,0x00,0x3F,0xFE,0x20,0x04,0x40,0x08,0x3F,0xFC,0x04,0x00, 0x08,0x20,0x1F,0xF0,0x01,0x10,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0xFF,0xFE}; /*******************************************************************************************/&&&&&&&& /*******************************************************************************************/ /*******************************************************************************************/ //数据串行输入&&void serial_input(uchar dat)&&&& {
for(m=0;m&8;m++)
{&&if(dat & 0x80)&& DATA=0;&&else&& DATA=1;&&SHCP=0;&&SHCP=1;&&&&&&&&NOP;&&NOP;&&SHCP=0;&&NOP;&&NOP;&&dat=dat&&1; }} void delay(){ unsigned int i = 50000; while(i--);}/*******************************************************************************************/ //并出 void serial_output() { STCP=0; STCP=1;}/*******************************************************************************************/ /*******************************************************************************************/ //行显控制 void HC138_scan(uchar temp) {&& OE=1;&& A1=0x01 &&& B1=0x01 &(temp&&1);} /*******************************************************************************************/ /*******************************************************************************************/ //整屏显示 void display() { uint i,j,k; serial_output(); for(k=0;k&4;k++)&&&&&&&&&&&&&&//显示的四行
{ &&for(j=0;j&2;j++)&&&&&&&& //显示3、4列 &&{&& for(i=0;i&2;i++)&&&&&&// 显示1、2列 && {&&&&buf = PLAYBUF[24+(k&&1)+i+(j&&5)];&&&&serial_input(buf);&&&&buf = PLAYBUF[16+(k&&1)+i+(j&&5)];&&&&serial_input(buf);&&&&buf = PLAYBUF[8+(k&&1)+i+(j&&5)];&&&&serial_input(buf);&&&&buf = PLAYBUF[(k&&1)+i+(j&&5)];&&&&serial_input(buf);&& }&&}&&serial_output();&&HC138_scan(k); }}void point(unsigned char x,unsigned char y,bit c){ if(x&=32) if(y&=16) i=0x80; i&&=x-((x&&3)&&3); if(c)&&PLAYBUF[(y&&1)+((x&&4)&&5)+((x&&3)&0x01)] |= else &&PLAYBUF[(y&&1)+((x&&4)&&5)+((x&&3)&0x01)] &= ~i;}//画线void line(u8&&x1, u8&&y1, u8&&x2, u8&&y2, bit color){ u8&&x, y, if((x1 == x2) && (y1 == y2))&&point(x1, y1, color); else if(fabs(y2 - y1) & fabs(x2 - x1)) {&&if(y1 & y2)&&{&& t = y1;&& y1 = y2;&& y2 =&& t = x1;&& x1 = x2;&& x2 =&&}&&for(y = y1; y &= y2; y ++)&&{&& x = (y - y1) * (x2 - x1) / (y2 - y1) + x1;&& point(x, y, color);&&} } else {&&if(x1 & x2)&&{&& t = y1;&& y1 = y2;&& y2 =&& t = x1;&& x1 = x2;&& x2 =&&}&&for(x = x1; x &= x2; x ++)&&{&& y = (x - x1) * (y2 - y1) / (x2 - x1) + y1;&& point(x, y, color);&&} }}void rectangle(u8 x1,u8 y1,u8 x2,u8 y2, bit color){ line(x1,y1,x2,y1, color); line(x1,y1,x1,y2, color); line(x1,y2,x2,y2, color); line(x2,y1,x2,y2, color);}void filled_rectangle(u8 x1,u8 y1,u8 x2,u8 y2, bit color){ u8 for(i=y1;i&=y2;i++) {&&line(x1,i,x2,i, color); }}//在指定位置画一个指定大小的圆//(x,y):中心点//r&&&&:半径void circle(u8 x0,u8 y0,u8 r, bit color){ int a,b; a=0; b=r; di=3-2*r;&&&&&&&&&&&& //判断下个点位置的标志 while(a&=b) {&&point(x0-b,y0-a, color);&&&&&&&&&&&& //3&&&&&&&&&& &&point(x0+b,y0-a, color);&&&&&&&&&&&& //0&&&&&&&&&& &&point(x0-a,y0+b, color);&&&&&&&&&&&& //1&&&&&& &&point(x0-b,y0-a, color);&&&&&&&&&&&& //7&&&&&&&&&& &&point(x0-a,y0-b, color);&&&&&&&&&&&& //2&&&&&&&&&&&& &&point(x0+b,y0+a, color);&&&&&&&&&&&& //4&&&&&&&&&&&&&& &&point(x0+a,y0-b, color);&&&&&&&&&&&& //5&&point(x0+a,y0+b, color);&&&&&&&&&&&& //6 &&point(x0-b,y0+a, color);&&&&&&&&&&&& &&a++;&&/***使用Bresenham算法画圆**/&&&& &&if(di&0)di +=4*a+6;&& &&else&&{&& di+=10+4*(a-b);&& && b--;&&} &&point(x0+a,y0+b, color); }}void load_playbuff(unsigned char *p){ for(i=0;i&64;i++) {&&PLAYBUF = *p++; }}void clear_playbuff(unsigned char n){ for(i=0;i&64;i++) {&&PLAYBUF = }}/*******************************************************************************************/ /*******************************************************************************************/ void put_char(u8 x,u8 y,u8 c,bit color){&&unsigned char tmp_char=0,i,j;&&for (i=0;i&16;i++)&&{&&&&tmp_char=AsciiLib[((c-0x20)*16)+i];&&&&for (j=0;j&8;j++)&&&&{&&&&&&if ( (tmp_char && 7-j) & 0x01 == 0x01)&&&&&&{&&&&&&&&point(x+j,y+i,color); // 字符颜色&&&&&&}&&&&&&else&&&&&&{&&&&&&&&point(x+j,y+i,!color); // 背景颜色&&&&&&}&&&&}&&}}void put_chinese(u8 x,u8 y,u8 *c,bit color){ u8 i=0; u8 j=0; u8 tmp_char=0; u8 tmp_char2=0;&&for (i=0;i&16;i++)&&{&&&&tmp_char=c[i*2]; tmp_char2=c[i*2+1];&&&&for (j=0;j&8;j++)&&&&{&&&&&&if ( (tmp_char && 7-j) & 0x01 == 0x01)&&&&&&{&&&&&&&&point(x+j,y+i,color); // 字符颜色&&&&&&}&&&&&&else&&&&&&{&&&&&&&&point(x+j,y+i,!color); // 背景颜色&&&&&&}&& && if ( (tmp_char2 && 7-j) & 0x01 == 0x01)&&&&&&{&&&&&&&&point(x+j+8,y+i,color); // 字符颜色&&&&&&}&&&&&&else&&&&&&{&&&&&&&&point(x+j+8,y+i,!color); // 背景颜色&&&&&&}&&&&}&&}}void display_move(unsigned int c){
for(i=0;i&16;i++) {&&PLAYBUF[i*2] = (PLAYBUF[i*2]&&1)+(PLAYBUF[i*2+1]&&7);&&PLAYBUF[i*2+1] = (PLAYBUF[i*2+1]&&1)+(PLAYBUF[i*2+32]&&7);&&PLAYBUF[i*2+32] = (PLAYBUF[i*2+32]&&1)+(PLAYBUF[i*2+1+32]&&7);&&PLAYBUF[i*2+32+1] = (PLAYBUF[i*2+32+1]&&1)+((c&&i)&0x01);
}}/*******************************************************************************************/ /*******************************************************************************************/ void main() {
unsigned int i=1000; BEEP=0; P0=0x00; TMOD = 0x1;
TH0=0&&TL0=0x18;//12Mhz ET0 = 1;
EA = 1; min=0; sec=0; time=0; rectangle(0,0,31,15,1); circle(15,8,4,1); while(i--) {&&display(); } //load_playbuff(&table[2*32]); put_char(0,0,tab[min/10%10],1); put_char(8,0,tab[min%10],1); point(15,6,1); point(15,9,1); point(16,6,1); point(16,9,1); put_char(16,0,tab[sec/10%10],1); put_char(24,0,tab[sec%10],1); while(1)
{&&display();&&if(time&=1000) {&&time=0;&&sec++;&&if(sec&=60)&&{&& sec=0;&& min++;&& if(min&=60)&& {&&&&min=0;&& }&& put_char(0,0,tab[min/10%10],1);&& put_char(8,0,tab[min%10],1);&&}&&put_char(16,0,tab[sec/10%10],1);&&put_char(24,0,tab[sec%10],1);&&point(15,5,1);&&point(15,10,1);&&point(16,5,1);&&point(16,10,1);&&point(15,6,1);&&point(15,9,1);&&point(16,6,1);&&point(16,9,1); } }}/*******************************定时器中断**************************/ void OSInterrupt(void) interrupt 1 { &&&&TMOD=0x1; TH0=0&&TL0=0x18;//12Mhz,1ms_delay time++;} /*******************************结束***************
在线时间198小时
太感谢!!!我的承诺还算!要是软硬都有就更美了
访问内容超出本站范围,不能确定是否安全
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
您目前还是游客,请
&回复后跳转到最后一页
Code by , Time now is:06-14 22:16, Total 0.271468(s) query 12,
Gzip enabled&当前位置: >
> 第2章 单片机的内部、外部结构
第3节 单片机程序的完善
一、 程序的完善
  上一次我们的程序实在是没什么用,要灯亮还要重写一下片子,下面我们要让灯不断地闪烁,这就有一定的实用价值了,比如可以把它当成汽车上的一个信号灯用了。怎样才能让灯不断地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10不断地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行:
这是不行的,有两个问题,第一,计算机执行指令的时间很快,执行完SETB P10后,灯是灭了,但在极短时间(微秒级)后,计算机又执行了CLR P10指令,灯又亮了,所以根本分辨不出灯曾灭过。第
二,在执行完CLR P10后,不会再去执行SETB P10指令,所以以后再也没有机会让灭了。
  为了解决这两个问题,我们可以做如下设想,第一,在执行完SETB P10后,延时一段时间(几秒或零点几秒)再执行第二条指令,就可以分辨出灯曾灭过了。第二在执行完第二条指令后,让计算机再去执行第一条指令,不断地在原地兜圈,我们称之为&循环&,这样就可以完成任务了。
以下先给出程序(后面括号中的数字是为了便于讲解而写的,实际不用输入):
;主程序:
LOOP: SETB P10     ;(1)
    LCALL DELAY   ;(2)
    CLR P10     ;(3)
    LCALL DELAY   ;(4)
    AJMP LOOP    ;(5)
;以下子程序
DELAY: MOV R7,#250  ;(6)
D1: MOV R6,#250    ;(7)
D2: DJNZ R6,D2    ;(8)
  DJNZ R7,D1     ;(9)
  RET         ;(10)
  END         ;(11)
按上面的设想分析一下前面的五条指令。
  第一条是让灯灭,第二条应当是延时,第三条是让灯亮,第四条和第二条一模一样,也是延时,第五条应当是转去执行第一条指令。第二和第四条实现的原理稍后谈,先看第五条,LJMP是一条指令,意思是转移,往什么地方转移呢?后面跟的是LOOP,看一下,什么地方还有LOOP,对了,在第一条指令的前面有一个LOOP,所以很直观地,我们可以认识到,它要转到第一条指令处。这个第一条指令前面的LOOP被称之为标号,它的用途就是给这一行起一个名字,便于使用。是否一定要给它起名叫LOOP呢?当然不是,起什么名字,完全由编程序的人决定,可以称它为A,X等等,当然,这时,第五条指令LJMP后面的名字也得跟着改了。
  第二条和第四条指令的用途是延时,它是怎样实现的呢?指令的形式是LCALL,这条指令称为调用子程序指令,看一下指令后面跟的是什么,DELAY,找一下DELAY,在第六条指令的前面,显然,这也是一个标号。这条指令的作用是这样的:当执行LCALL指令时,程序就转到LCALL后面的标号所标定的程序处执行,如果在执行指令的过程中遇到RET指令,则程序就返回到LCALL指令的下面的一条指令继续执行,从第六行开始的指令中,可以看到确实有RET指令。在执行第二条指令后,将转去执行第6条指令,而在执行完6,7,8,9条指令后将遇到第10条令:RET,执行该条指令后,程序将回来执行第三条指令,即将P10清零,使灯亮,然后又是第四条指令,执行第四条指令就是转去执行第6,7,8,9,10条指令,然后回来执行第5条指令,第5条指令就是让程序回到第1条开始执行,如此周而复始,灯就在不断地亮、灭了。
  在标号DELAY标志的这一行到RET这一行中的所有程序,这是一段延时程序,大概延时零点几秒,至于具体的时间,以后我们再学习如何计算。 程序的最后一行是END,这不是一条指令,它只是告诉我们程序到此结束,它被称为&伪指令&。
二、单片机内部结构分析:
  为了知道延时程序是如何工作的,我们必需首先了解延时程序中出现的一些符号, 就从R1开始,R1被称之为工作寄存器。什么是工作寄存器呢?让我们从现实生活中来找找答案。如果出一道数学题:123+567,让你回答结果是多少,你会马上答出是690,再看下面一道题:123+567+562,要让你要上回答,就不这么容易了吧?我们会怎样做呢?如果有张纸,就容易了,我们先算出123+567=690,把690写在纸上,然后再算690+562得到结果是1552。这其中1552是我们想要的结果,而690并非我们所要的结果,但是为了得到最终结果,我们又不得不先算出690,并记下来,这其实是一个中间结果,计算机中做运算和这个类似,为了要得到最终结果,往往要做很多步的中间结果,这些中间结果要有个地方放才行,把它们放哪呢?放在前面提到过的ROM中可以吗?显然不行,因为计算机要将结果写进去,而ROM是不可以写的,所以在单片机中另有一个区域称为RAM区(RAM是随机存取存储器的英文缩写),它可以将数据写进去。
  特别地,在MCS-51单片机中,将RAM中分出一块区域,称为工作寄存器区。
Copyright &
elecfans.com.All Rights Reserved

我要回帖

更多关于 单片机烧录器 的文章

 

随机推荐