谁能帮忙看看这个单片机工作寄存器程序里的几个寄存器?把每一位的值告诉我可好?

单片机寄存器赋的值是怎么来的?-电子发烧友网触屏版
这篇文章适合刚刚入门的单片机小白看。
单片机在电学里面,属于很简单的一种器件,外表看,就是一个芯片,长着很多的脚。内部,就是一堆寄存器。不同的单片机,外部表现就是形状和引脚数量和引脚名称可能不一样,内部,就是寄存器名称不一样。
我们要做的,就是写程序控制单片机里面的寄存器,然后通过引脚表现出来完成各种电子产品。
所以,你在看别人写的程序的时候,会经常看到给单片机寄存器赋值的语句。下面就以最简单的控制51单片机引脚高低电平来说明一下。(不要总是存在51单片机已经淘汰的想法,51单片机至今任然是出货量最大的单片机,并且各大公司每年都有新款的51单片机推出,功能越来越强劲,做产品,要选最合适的单片机,而不要总想用牛逼的单片机。)
例如,单片机P1口有8个引脚,分别为P1.0~P1.7,如果想让P1口的8个引脚都输出高电平,是这么写:P1=0XFF;如果想让P1口的8个引脚都输出低电平,是这么写:P1=0X00;如果只让P1.0输出高电平,其他引脚输出低电平,是这么写:P1=0X01......
这些值是怎么来的呢?
计算方法:
一个数,前面以0X开头,标示后面的数是十六进制数。所以首先,我们先要知道十进制和十六进制的转换。
十六进制:0 1 2 3 4 5 6 7 8 9 A &B &C &D &E &F
十进制: &0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
以上十六进制和十进制是对应关系,例如B对应11。
单片机和计算机一样,是以&位&为最小单片机,例如,P1是一个8位的寄存器。P1寄存器的8个位名称分别是:P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
上面的0X开头的数,是以4个&位&为一个单位进行计算,以8421码进行相加计算,听这里很迷糊吧。举个例子就明白了。
你可以做一个这样的表格:
从上表看出,把寄存器的&位&,从高到低排列,然后以4个为一组,对应的8421码如上图所示。
给寄存器写值,实际上就是给它的每个位写0或者1,例如要使得哪个引脚为高电平,就给对应的位写1;要使得哪一个引脚为低电平,就给对应的位写0。然后把对应为1的8421加起来,以4个位为一组。
例如,我们要让每一个引脚都输出高电平,就是每个位的值都为1,那对应寄存器的高四位,8+4+2+1=15,15对应的是十六进制的F,再看寄存器的低四位,8+4+2+1=15,还是对应F,所以最后的值就是0xFF。
再看,如果让每一个引脚都输出低电平,就是每个位的值都是1,前面说过,只有对应位是1,才把它们的8421加起来,现在都是0,所以都不用加,结果就是0x00。
再看,如果只让P1.0引脚是高电平,其他引脚输出低电平,那么,只有P1.0对应的位是1,其它的位是0,所以,只需要取P1.0上面的1码,所以结果就是0x01。
再看,如果让P1.0、P1.1、P1.7、P1.5输出高电平,其它引脚输出低电平,那么对应的值如下图所示:
我们看寄存器的高四位,取对应1上面的码8+2=10,10对应十六进制的A,再看寄存器的低四位,取对应1上面的码2+1=3,3对应的十六进制还是3,所以结果就是0XA3,这是,你写P1=0XA3,就可以使得引脚该高的高,该低的低了。
不管是51的8位寄存器,还是ARM的32位寄存器,寄存器中的每一个位都有一定的用意,这些用意可以查看单片机的用户手册得知,你只需要按照你的要求,给对应的位写1或者0,然后利用上面的方法得出结果,就可以操作单片机的寄存器了。
文章来源专栏
加载更多评论
后参与评论没有玩过单片机的可能对单片机还有一定的神秘感,对程序更是如此,为什么一个文件写进去它就工作了,不写就不工作。我写这个帖子的主要作用就是想以浅显的方式让大家了解一下单片机到底是怎么个东西。
首先,单片机是一个芯片(废话)。它和程序是什么样的关系呢。你可以认为单片机是一个可以接受你命令的芯片,你给它命令,它就执行,否则就傻傻地在那里,什么也不会做。但是它能接受的命令只有两个,第一,将某一个管脚连到电源或地。第二个,判断某个管脚上有没有电。只有这么点功能。你能想出什么花样,那么它就能帮你完成。
这里要介绍一下几个名词,这里给出的解释并不严谨。
1高电平和低电平
高电平就是电压是接近于单片机供电电压的状态,低电平是接近于0V的状态。一般情况下,电压高于2V都认为是高电平,小于0.7都认为是低电平。那么0.7到2V之间的呢?对不起,正常工作时不可能出现中间的电压。
刚才说到了,单片机只能接受两种命令,一是将管脚连到电源或地(输出电平),二是判断管脚电压(输入状态)。IO口就是指这些可以被控制的管脚,I(input 输入)O(output 输出)。它们可以通过命令让它输出一个电压状态,也可以读取外边的状态。记住了,这里是状态,要么为高,要么为低,没有其他结果。
单片机就是这么一个傻傻的东西,余下的是就是程序的范围,注意了,程序运行的速度非常快,基本都是M为单位的,也就是每秒100万次。
那么了,我们从最简单的跑马灯来了解一下,程序是怎么来控制这个傻傻的单片机,让它变成一个有趣的东西的。
前面说了,单片机只能接受两种命令。一是输出,二是输入。所以你必须搭一个电路,让电平变成可见光。这个很简单,把管脚通过一个LED+电阻。这时就有两种接法,一是接到电源,那么管脚上为低电平时就会亮。另一种是接到地,管脚上为高电平就会亮。
既然要做跑马灯,那么至少得准备4个灯吧。否则效果不明显。
那么我们就给这四个灯分别编上号 叫1 2 3 4吧。所以跑马灯占用了4个管脚(4个IO口)
前面是硬件部分,软件部分干什么呢
换句话说,如果让你直接去指挥单片机,你该对它下哪个命令?
我想这个答案应该很容易想到
1.1号脚输出高电平(让1号灯点亮),其他几个都输出低电平(不亮)
2.1号脚输出低电平,2号输出高电平
3.2号输出低电平,3号输出高电平
4.3号输出低电平,4号输出高电平。
5.重复1-4.
这时你自己去想一下,这些灯是不是应该按次序亮的。很显然应该是正确的。那就说明你这个程序已经完成了。
到时候只要把这几句话变成相应的指令(这个过程由电脑上的软件完成,这个过程称为编译),就会生成一个文件,这个文件加到单片机里,单片机就按你的要求运行了。
实际上,如果你把这段程序加到单片机里,你会发现四个灯都是亮的,而不是依次点亮。原因是前面说,程序运行的速度非常快。每秒都是百万次的,所以如果真的这么写,这个灯会按每秒几十万次的速度依次点亮,因为太快了,你看到的就是它们都亮在那里。
这时你要做的是就是改一下程序。变成下面的
1.1号输出高电平,其他输出低
3,1号输出低电平,2号输出高
5.2号输出低,3号输出高
7. 3号输出低,4号输出高
8. 等0.5秒
9.重复1-8
这样改过之后,灯就会按每0.5秒跳一次的速度依次点亮。你可以改变等待的时间,就可以得到不同的跑马速度。你也可以增加灯的数量,让更多的灯参加跑马。还可以加入控制,比如某个额外的管脚为高时才开始跑,为低时就一直在等。这就得到了可以控制的跑马灯。
怎么样?可以发挥的空间很大吧?变成什么,完全就看你的想象力了。
今天 就先讲这些。有什么想问的,欢迎大家提问。谢谢
彩电CPU算是单片机吗
彩电那个 有些电视里边只有一个芯片,俗称“单片机”,类似的还有双片机,三片机。
那种不是我这里讲的单片机。我这里讲的单片机叫“可编程微控制器”,因为它的电路简单,只有一个芯片,所以叫单片机。
而彩电那种“单片机”是将大量的功能集成到同一个芯片里边去。这种称为专用芯片,也叫ASIC芯片。这种做法常用于需求量巨大的情况下,为了降低成本则专门设计的芯片。设计一个比较大的芯片,费用相当吓人,光投片一次就需要几十万甚至几百万。人工设计费用更是个巨大的开销,更要命的是只要一点点设计错误。投片的钱就打了水漂。
现在USB2.0的控制器就是一个小芯片,几块钱就行了。上次在哪个论坛看到的,在没有这个芯片的时候,用了一堆高档的FPGA拼出来的。那堆芯片价值少说上万美元。体积不比一台DVD小。而给开发这些代码的工作量更是无法想像。具体多少我不知道,但我可以保证的是,那堆代码如果让你一行一行地输入到电脑,估计这辈子都别想完成。
如此巨大的工程,最后搞成了专用芯片,就变成几块钱了。所以降成本非常明显。当然,只有数量足够大的时候才会设计专用芯片,否则也是亏本。
今天周末,天气不怎么好,继续讲单片机。
前面大概地说了一下单片机是个什么样的东西。单片机的功能的确非常简单。所以能做出什么东西来,就看你的脑洞了,更要的是有足够的耐心去指挥它。因为有时一个非常简单的功能,程序写起来都是一大片。
接着上次的。
上次说到,单片机只能接受两种命令。一是控制管脚输出高电平还是低电平,二是告诉你某个管脚是高电平还是低电平。但就是这么简单的一句话,实际上还要分成两步才能完成。首先第一步就是告诉单片机,这个管脚是用来输出还是用来读取(输入)。完成这一步才能进行下一步操作。具体地说,如果你让它是输出,那么你可以再下一个命令,告诉它输出是高电平还是低电平。同样,如果你让它是输入,还需要再下一个读取命令才能知道这个某脚上的电平状态是高还是低。
下面就要说一说,怎么给单片机下命令,也就是指令长什么模样?指令其实就是一排数字,不同的数值代表不同的指令。具体什么数值代表什么指令,每种单片机都不一样。因此就会有什么51单片机,AVR单片机,PIC单片机等等。所以你想玩哪种单片机,就得找对应的书去看它的指令。然后你把这一堆指令一条一条地写出来,找个编程器把它写入单片机,单片机就可以运行了。
那我们先来对指令有个感性的认识。
这里我们用指令最为简单的PIC举例。
600)this.width=600;">
先不看具体内容,看见有一个写着12位操作码的那一列了吗?那就是指令。就是一串长度为12位的数,不过这里的每位只允许取0或者1.(这实际就是二进制,具体是怎么个东西后面讲)
你这时可能会有意见了,你不是说单片机只有两种命令的吗?这里怎么冒出来了这么多?
因为前面说了,如果让你去指挥,只需要两条就行了,问题我可能把你塞进单片机啊。比如单片机读到了管脚的电平状态,总得汇报给谁吧?不可能等你人来处理啊。这就是单片机必须能代替你,你只需要把事情事先交待好了,比如,当发生什么什么时,就做什么,否则就做什么什么。所以你见到的这么多指令,就要就是用来描述这些内容的。
这下好了,这种指令已经有二三十条了,理论上,你完全可以用这些12位的数据完成对单片机的编程。如果这样玩的话,估计不会有几个人会对单片机感兴趣了。因此你可以使用图上的“助记符”,然后由电脑将助记符一一对应地转成12位的指令。这里的助记符就实际就是汇编指令。
当然,我们今天讨论的重点不是在于让你会用它,而是让你感觉到,程序是如何来让单片机发挥作用的。到这里就基本就可以知道了,单片机已经规定好了一串串的数值作为指令,你按它的规定就可以写出一串串的数值来控制它。当然,我们写的时候可以使用“助记符”来写,也就是汇编指令来写。写着这些助记符之后,电脑会将它一一对应地转化为数值,这就是可以写到单片机里的程序了。
下面,我简单地说明一下,我该怎么写前面说的跑马灯。
这个过程只是用PIC来举例,让你感受到在这个过程中,人和电脑分别做了什么事。
未完,待续
刚开始就说了,如果让你去控制单片机,让它实现跑马灯,你应该不停地按下面的顺序给单片机下命令。
1.1号输出高电平,其他输出低
3,1号输出低电平,2号输出高
5.2号输出低,3号输出高
7. 3号输出低,4号输出高
8. 等0.5秒
9.重复1-8
那我们按这个思路,将它转化为单片机的指令。但是指令总共有那么30多条。你得在里边找出合适的指令,来完成你的命令.
下面这段内容,由于涉及到单片机的具体操作,所以新手可能点无从下手,我写了“看手册可以知道“的,你就当作是已知内容。因为你目前对单片机不了解,所以这些“已知内容”还是有点陌生。学习某种单片机,实际上就是了解这些内容的过程。由于你以后不一定就用这个型号的单片机,所以这些具体的内容就没必要深究它在文档的哪一页。这个内容等后面再讲
先看第一条
将1号管脚设为高电平,其他设为低电平
那我们该怎么给它下命令呢? 第一,我必须将1 2 3 4号管脚全设为输出,你就在里边找将管脚设为输出的命令是什么,看手册我们可以知道,这条命令叫TRIS ,将哪个管脚设为输出呢?我们看看单片机有哪些管脚?看了手册你就知道,12F508有GP0-5 共6个管脚可以被我们控制,但是手册里又说了。GP3是不能用于输出的。那我们就选 GP0 GP1 GP2 GP4管脚,分别对应于前面的1 2 3 4
那好,我们要将0 1 2 4管脚设为输出,手册上说 0表示输出,1表示输入,所以我们要将4,2,1,0管脚设为输出的命令就是 TRIS 101000
为什么是这样 因为它有6个可控制的管脚,分别为GP5 4 3 2 1 0,我们需要将 4 2 1 0设为输出,3只能作为输入,GP5呢?GP5没有用到,随便你。我给它安排的是1(输入)。所以它们就是入出入出出出 (高的在前),也就是101000,当然如果你想把GP5也设为输出,那就是001000
所以,第一条命令就是 TRIS 101000
然后还要将1号脚(也就是GP0)设为高。 在数字电路里边,1就表示高,0表示低。那么GP5,4 3 2 1 0就应该 表示为000001.注意,GP5 和3是输入,但是位置你还得给它留着,否则就对歪了,当然,它作为输入时,对应的位置上是1还是0是无所谓的。我习惯用0.
怎么改变管脚的状态呢?在命令里找了一圈,没有发现这条命令。那怎么办?读手册可以知道,想改变管脚的电平状态,只要将这组数据保存到一定特定的位置就行了。这怎么理解呢?就像我们上论坛,要输入用户名和密码。这实际就是给电脑发指令。但电脑不需要给输用户名配一个键盘,给密码再配一个键盘。而是由位置决定。你把光标停在用户名这一栏,那么你输入的内容就是用户名,停在密码,输入的内容就表示密码,停在验证码的框里,就表示输入的内容是验证码。
所以单片机里有很多这种地方可以让你输入内容,因为这些内容直接就会引起某个功能,所以我们不叫它为输入,而是称为设置。这些给你设置内容的地方称为特殊寄存器 一个单片机里有很多这种寄存器。只要修改它们的值,就可以实现一定的功能。为了方便描述,它们都有一个编号,每个的编号都不一样。
好了,我们看看怎么设置管脚的电平状态吧。
根据手册,这个单片机的第6号寄存器就是用来控制管脚电平状态的。当管脚为输出时,1就表示高,0就表示低。你改变它里边的值,管脚上的电压状态就会改变。
所以只需要向第6号寄存器里输入000001就达到目的了。
查了一下指令表,里边没有这指令可以将一个数保存到某个寄存器里。但是可以用两个命令来实现这一功能。第一个指令为MOVLW 这个指令的功能是将一个数据放到一个叫名子叫W的空间里。另一个指令是将W里的数据转移到你指定的编号里去。嗯,就用这两条命令就可以达到目的。
因此 第2,3条指令就是
MOVLW&&000001
回过头来读一下,第一步,将000001存到W这个空间里去。第二步将W空间的数据转移到第6号寄存器里去。很明显,通过这两步,我们就将000001放到了第6号寄存器里了。一旦数据放进去,单片机管脚的电平状态立即跟着就改变了。现在GP5 4 3 2 1都是0,也就是低。而GP0是1,也就是高。
到这里,我们完成了1号管脚输出高电平的过程。
接着要等0.5秒,也就是什么事也不做。什么事不做也有一条指令,叫NOP。执行一条这个指令需要一个周期,一个周期是多少?根据手册,这个单片机的振荡器的频率为4M,每4个周期为1个指令周期。也就是说1秒可以执行1M个指令。那么我需要0.5秒,得连写50万个NOP。这简直没法活了。这时我们就得想想其他办法了。方法一定是有的。它的方法是让单片机在那里做一个很简单的计算,做什么事呢?让单片机将一个寄存器里放50万,然后让它减1,减到0了,那就是执行了50万次了。向寄存器里放一个数我们刚讲过,减1也有专门的指令叫DECF 让它减到0就结束该怎么做呢?我们找到了一条新指令叫DEFSZ 它是什么意思,当减到0时就跳过下一条指令,直接执行下下条指令。
那么好了,方法出来了
&&MOVLW 500000
&&MOVWF 20
&&DEFSZ 20
&&GOTO 上一句
&&...接下来的事.....
回过头来看看,先将50万放到W里边,然后将数据转移到20号空间,20号空间没有什么功能,就是给你临时放放数据的。
然后对20号空间(20号寄存器)里的数据减1,如果是0就跳过下一条,执行接下来的事。否则就回到上一句,继续减1,很显然,它要被执行50万次再能执行接下来的事。
&&这段程序实际上还有错误,那只是单片机自身的原因引起的,为了不影响我们的主要目标,我们就先不管具体错在哪里了,我们只管思维逻辑上是对的。
接下来又是改变输出的值,前面已经指定了GP 4 2 1 0为输出了,因为我们没修改过,这就不需要再次指定了。直接修改管脚的电平状态就行了
MOVLW&&000010
接下来又是等0.5秒,不要我说了吧,把上面的再抄一遍。
MOVLW&&000100
MOVLW&&010000
等0.5秒之后,
GOTO (第一句)
这里不能写中文写第一句,同样,前面有个GOTO 上一句也是不行的。这个问题很简单,你在对应的位置设一个标志。就改成这样
&&MOVLW 500000
&&MOVWF 20
&&DEFSZ 20
&&GOTO AAC
这样就可以了。同样goto 第一句 我们在在 TRIS 101000之前也弄一个标志,标志就写个START00
TRIS 101000
GOTO START00
这样就行了。标志别重复就行。
好了,这样一个程序就写完了。这种指令叫汇编指令,所以这种程序叫汇编程序。
下面的事交给电脑了,你用记事本写完这些内容。然后用厂家提供的软件,它就会将指令翻译成12位的数据。然后保存为一个文件,后缀名叫.bin
这就是编译好的程序了,你用烧片器把它写到PIC12F508的单片机里,然后在GP4 2 1 0上接上LED,通电后你就可以看到灯在那里跑了。
到这里,你也应该大概地知道,编程是怎么回事,以及为什么要写程序了。
但是你写什么样的程序,就得得发挥你的想像力了。
由于到现在才讲到了非常简单的一个功能,所以大家的想像空间还很有限。这时可能你还是觉得这东西没什么大用。
但是等我讲完它的其他部分,你会发现,可以发挥的余地其实很大。
数字万用表中的黑圆圆的覆膜一电路和语音存储电路的控制电路是单片机吗?还有电动车控制器的核心集成电路是 ...
万用表里的是专用芯片。它里边的主要功能是AD。模数转换,就是将一个电压值用数字来表示。
语音存储也是专用芯片,声音实际上可以用一个交变的电压驱动喇叭来产生。反之,用话筒也能将声音转成电信号。芯片里边的AD将电信号变成数值,然后存起来,每秒要存几千次。播放时就是将数据转成电压(DA),然后驱动喇叭。这个过程也可以用单片机,但是这就要求单片机上有AD和DA,同时有很大的存储空间用来存声音。这种单片机会非常贵甚至根本买不到。
电动车控制器用单片机的还是比较多。
它的主要功能是产生PWM,很多单片机都有PWM功能。你拧油门把手,实际上是改变了一个电阻。电阻的改变引起电压的改变。单片机里有AD,就可以知道当前的电压,然后根据一定的要求产生PWM来驱动电机,从而改变电机输出的力最。无刷的会更复杂。
在论坛上看见有人说数字万用表里有ic是软封装,我想是不是他本身也是一种单片机,另外像计时器这种东西实际不 ...
单片机有点像万金油,什么都会一点,但又不精。
那常用的软封装的万用表IC,那不属于单片机。因为你无法对它进行编程。它的功能已经固化。算是专用芯片。
高档的万用表,一般都是单片机加AD,虽然很多单片机自带AD,但是性能不行。这种高精度的应用场景还是专门配一个AD芯片。
计时器实际也不会用单片机,一般用时钟IC就行了。
今天讲一下输入功能。
前面就说了,单片机的管脚可以设置为输出,也可以设置为输入。前面讲了输出,但大部分小电子产品都应该可输入的,否则应用场景不大。就像前面的跑马灯,通电之后,它就依次亮下去,刚开始看看还觉得有点好玩,看一会儿就腻了。
那加一个按键做什么呢?我也没想好。那就做个简单的。你按一下开关,灯就亮,再按一下,灯就灭。呵呵,这么弱智的电路,一个双稳就搞定了,但我们现在杀鸡用牛刀,用单片机来做。目的只是为了让大家了解一下,单片机是怎么来实现这一功能的。其实单片机用得好与不好,主要就是看你软件思路(算法)好不好,基于会汇编语言还是会C语言,这是基本功。就像写作文,会拿钢笔还是会拿毛笔,但你好歹得会一种,你会写字了,不代表你能写出一篇好的文章来。所以,文采就相当于软件的算法,而会某种编程语言则是像用哪种笔。可以知道了吧,算法才是最终的目标。这和作文一样,再伟大的作家,也一定能将别人教成大作家。所谓师傅领进门,修行看个人。
好了,不说大道理,看一下怎么实现这一功能。首先还是要有硬件的,硬件怎么连?1号管脚连一个灯,2号脚连一个按键,按键就是按下去就接通,松开就断开的。按键怎么接?通常是拿一下电阻,一头接在2号脚上,另一头接电源,开关一头接2号脚,另一头接地。这样不按开关时,管脚电压为高,按下去之后变为低。
好了,看软件算法
1.将1号设为输出
2.将2号设为输入
3.读2号的电压,为高则回到3.
4.从0开始计数
5.读2号脚的电压,为高则回3
7.如果没有数到10000,则回5
8.如果1号脚是高电平,则改为低电平(熄灯)
&&否则,则将1号脚改为高电平(亮灯)
9.如果按键为低,则回到9
嗯,写完了,看看它是怎么工作的,1和2是初始化,就是将对应的管脚设置一下,这个没好说的。
从3开始,如果为高则回到3,为低呢?前面说过,程序是无法停得住的,它会以每秒百万次的速度去不停地执行,如果为高,它又回到3,再次判断。平时按键是没有按下的,所以它在拼命地执行第3句。这样程序就被“卡”在了这一句上。
当有按键按下,管脚变为低,不满足第3句的条件了,它就会执行下一句,也就是第4句。从0开始计数。这是要什么?没有说,程序会继续执行下一句。
读2的电压,为高则回3.---这是怎么回事,如果按键没有按下,它应该卡在第3句,既然已经跑到了第5句,那说明按键已经按下,为什么还要再判断一次?
这是我们今天要讲的一个重要内容,这就是按键的抖动,平时我们认为,按下开关,它就通了,松开,它就断了。实际上,在按键按下的瞬间,按键里边的动触点就会跳动,当它撞上定静触点,它会回弹(断开),然后在弹力的作下再次接触,有可能再次弹开...反复几次之后它才老老实实地和静触点接触。就像你把一个弹珠丢到水泥地上的感觉,它会跳几次才肯停在地面上。这个过程很短,一般只有千分之几秒(即几毫秒),这对人来说是感觉不到的,前面说了程序速度很快,它就能感觉检测得到,当开关按下去之后,电路是通-断-通-断-通-断-通---- 这样一个过程。
会在5-7之间跑至少1万次,所以这需要10毫秒的时间,这样就把这个跳动的时间给躲过去了。这称为去抖,是按键处理里边最常用的一种手段。
继续看大体的流程。按键被按下去之后10ms,软件这时可以保证是按键被按下去了。程序继续下向,如果原来灯是亮的,则改成灭。否则改成亮。
执行完之后,还有第9步,它会在这里等键键松开。一旦松开就回到第3步,松开的时候就没有加去抖,虽然松开时也可能会抖动,但是它最多会执行5-7,最终再次卡在第3步,等待下一次按键的动作。
好了,这就是一个完整的流程。如果有问题欢迎提问。
另外,我们在这个过程中提到了计数。可能有人喜欢搞明白,它怎么能计数?在单片机里边,除了有前面提到的特殊寄存器,这种寄存器里边的值不同,就会直接改变单片机的某一项功能。还有很多通用寄存器。通用寄存器,也就是“内存”和电脑的内存是同一个概念。我们现在的电脑内存基本都是2G打底了。1G=6KB。单片机有多少内存?一般只有一两KB,简直小得可怜。还有更可怜的,标准的51单片机里边只有百来个字节。前面举例用的PIC12F508只有25个字节。所以在选单片机时,需要根据你需要数据的大小选择合适的单片机,如果选的单片机的内存不足,那你的程序就无法运行。
一个字节有8个位,所以它的值可以是0-255(2^8-1),想存更大的数据怎么办?用两个,一个表示高位,一个表示低位。这样两个就能表示0--1)了。两个字节就能存得下10000了。所以计数就这样,在内存里边找两个字节,将它的值改为0.这就是第4步的内容。将其中的一个作为低位,另一个就是高位了。计数就是拿低位的加1(加1是所有单片机都有的一条指令,你不要担心它不会加1怎么办),当加到255,你继续加1 ,它会自变成0,同时还会告诉你发生进位了,当检测到进位之后,你对高位再加1,这们就完成了计数。
好了,这个按一下亮再按一下灭的开关好像有点简单,我们能不能给它扩展一下用途?
我就先抛几块砖吧,引玉的活你们自己去想
1.多加一个按键,功能还是一样,只是无论按哪个都等同,那么就可以用于楼梯上了。
2.加10个按键,按指定的顺序按下按键,则控制一个电磁铁吸合。这就变成了密码锁。
3.多加几个灯,再多加几个开关,第一个按开关的灯被点亮。这就变成了抢答器。
4.两个灯,当高电平时,1号灯亮,低电平时2号灯亮,这就是逻辑笔。
呵呵,想要更多功能,发挥你的想象吧。
前面讲了单片机的基本功能。它的管脚是既可以作为输入,还可以作为输出的。至于输入还是输出完全由软件控制的。讲到这里,你用单片机做一点简单的事情应该已经可以了。根据你的设计意图,将对应的管脚设为输入或输出,然后通过程序来控制它,当输入管脚为什么情况时输出什么内容,然后配合上电路完成你想实现的功能。
下面就要讲讲单片机的其他功能了,其他功能只是让你的程序可以变得更加灵活。总体来说,它们的加入可以简化你的硬件电路或者降低软件的难度。这里说的难度对初学者可能是“增加”难度,有了它们,单片机可以用较少的代码完成更多的事情。对初学者来说,感觉又增加了复杂度。
先讲第一个附加功能,也是最最重要的,那就是中断。
中断可以打断程序的正常运行而“插播”一段程序。就像一些紧急新闻可能打断原来的播放内容一样。比如你正在收看电视剧,这时忽然插播了一条紧急新闻,一只老虎从动物园跑出来了,大家赶紧关好门窗以防不测。对于你观众而言,这条新闻的出现是出乎你的意料的,但是它的出现并没有对电视剧的内容造成影响。只是额外让你知道了一个事情的发生,你可以立即关好门窗然后继续看你的电视。现在我们用一个简单的单片机例程来和这件事对应,让大家了解一下单片机的中断是个怎么回事。这个单片机例程就是电动自行车的控制器。电动自行车估计大家都骑过,打开电源,一拧油门(应该叫电门),车就开始跑,你扭得越多,控制器给电机的电能就越多,车就跑得越快。但是当捏下刹车时,不管油门拧多大,必须立即停止对电机的供电,否则影响刹车效果。当刹车松开之后,控制器又需要给电机供电让车子继续跑。
那我们来看看两者的相似之处,对于电视,今天放什么节目什么广告,都是预先定好的,这也可以认为是一种程序。对于电动车控制器来说,你加多大的油门我给电机供多少电这也是预先定好的,这也是一个程序。本来大家都按着事先定好的程序进行着,一切都很自然。这时关老虎从笼子门自己开了,老虎从里跑出来了,这是一个紧急事件发生了。对于电动车来说,本来在路上跑得好好的,突然有个小孩冲到了路中间并挡住了去路,开车的必须立即刹车,这也是一个紧急事件发生了。这种不知道什么时候会出现的事情打断了原来的平静,这就被称为中断事件。所以中断发生的时间你是不确定的,但可能发生这事件你却是事件能预见到的,否则车就不需要安装刹车了。发生了中断事件之后,你必须立即进行应急处理,对于老虎事件,应急处理就是立即中断当前的广播电视节目,插播这一紧急新闻。而对于电动车来说,则是立即刹车,同时切断电机的供电。这个过程称为中断响应。很显然,捏下刹车后切断对电机的供电这段程序是也是事先写好的,平时它不会被执行,只有发生了事情之后才被执行。所以写程序必须有“经验”否则你就可能写不出这样的程序。同样,应急处理也必须事件演练,各种消防演习就是让你学会处理紧急事件,给你增加“经验”。当要处理的事情完后之后,电视又继续播放正常的内容,而自行车则继续给电机供电继续向前跑。
好了,单片机的中断实际上你可以认为是一代应急代码。你必须事件想发这件事情发生后该做什么,并把它写成代码。主程序里边只需要写正常情况要执行的事。当发生了对应的事件之后,单片机自动地跳过去执行那段代码,执行完了之后它就会继续执行原来的程序部分。
如果不用中断,那事情就不一样了,对于电动车而言,你可以不停地检查有没有刹车动作,有的话就切断电机的供电。这个看上去也说得过去,这是因为这个事情相对来说比较简单,你可以不停地检查有没有发生某个事(这称为轮询)。但是如果需要关注的事件非常多,那么你都一项一项地检查,那就会浪费大量的CPU时间,前面说过,单片机的CPU每秒执行的命令数量虽然看上去很多,但毕竟是有限的,如果需要查询的内容非常多,那么CPU用于处理正常程序的时间就会变少,这就影响了CPU性能的发挥。如果换作电视台,那么就很可笑了。你的记者每天都往动物园跑几百次,如果发现老虎跑出来了就赶紧写稿子叫电视台播放,那问题来了,如果你不一天跑几百次,万一你刚走老虎跑出来了怎么办?另外,除了动物园,还有工厂也可能发生火灾或有毒气体泄漏,你也得一天跑几百次,一年365天还得不分昼夜,记者不累死才怪。有中断,则事情就简单多了,记者可以关心它关心的内容,一旦发生了事情,人家一个电话给记者,记者听到电话后立即放下手头的活赶往现场。这样工作才会更有效率。
一个单片机可以允许多个中断,每个中断都对应一种情况,你只需要将可能发生的情况出现后要怎么处理写好,一旦发生了这个问题,程序就能自动跑过去执行这段内容,执行完之后它又能自动地接着刚才的正常程序继续工作。
嗯,中断好像就是这么回事。你有没有能理解?有问题欢迎提问。
今天又要给大家增加一个新的内容。那就是定时器(或者叫计数器)。
这个本来不属于单片机的内容,但它在常见的单片机里都集成了这个功能,所以也讲一下。
这里的定时器,在单片机里边只是一个会自动加1的寄存器,但是有了它,又可以玩更多的花样了。
已经说了,这是一个会自动加1的寄存器,那么你可能会问了,它什么时候会加1?嗯,这就是我们要讲的内容。它什么时候加1是可以设置的,方法也是设置另一个寄存器。通过设置不同的值,单片机就可以知道你希望它什么时候自动加1。可以选择当某个管脚上出现一个脉冲的上升沿(或下降沿时)加1,也可以选择系统时钟的整数倍时加1。假设它是在管脚脉冲的上升沿时加1的,我读取这个计数结果,就可以知道这个管脚上收到了多少个脉冲。这相当于在计数。所以这时习惯称之为计数器。如果它是在系统时钟的整数倍时加1,系统的时钟是我们自己选的,它的频率我们是已知的,收到了多少个计数,就知道过去了多长时间,所以这时我们习惯称之为定时器。这里也可以让你看出,同样是一个简单的加1功能,它计数的东西不同,就实现了不同的功能。所以单片机能做什么,全看你怎么用它。
计数功能很简单,没什么要多说的了。我们主要说说计时功能。既然叫它定时器,那么就应该有到了时间提醒你的功能。的确,它是具有这个功能的。
比如我们的系统时钟为1M,那么计数加1就需要1微秒(当然,也可以设为N个时钟计数加1).比如我需要它在1000us(等于1ms)后提醒我,那么我可以设置计数的值为1000,然后让它开始计数.当1000us过去之后,它会产生一个中断.前面说了,当中断之后,程序会打断当前执行的内容去执行这段处理程序.所以单片机可以去做其他的事,当时间到了,它会自动跳过去执行中断处理程序.
我们现在用的电脑,它里边只有一个CPU,它的运行速度很快,都是以G为单位.虽然只有一个CPU,你会发现你的电脑可以一边聊QQ一边看网页,还能一边听听歌,看上去好像是多个程序都在同时执行,而实际上,它们并不是同时执行的,因为CPU同一时间只能执行一个程序.所以电脑的CPU会每过10ms产生一次中断,中断之后就执行另一个程序,由于每秒切换100次,所以你感觉到的就是所有的程序都在同时运行.这就是定时器一个强大的应用:实现任务的切换,让一个CPU完成多个事情的处理.
这部分由于需要对单片机深入接触之后才能感觉得到,所以这里只是提一下,等你们在使用过程中去感受它.
今天我们说一下串口
为什么要说它,因为它对我们玩单片机很有帮助。
老一点的台式机上,一般都会有一个9针的插口。那就是串口。在电脑附件里有一个超级终端的小软件,它可以和这个口通信。
我们常见的单片机里,一般都带串口这个功能,这个意味着通过这个接口就可以实现电脑与单片机的通信。这是与电脑通信最简单快捷的一条路!
为什么要与电脑通信?我们要玩单片机,必须要把程序给加到芯片里去才行。把程序烧到单片机通常的做法是用烧录器。买一个编程器,然后把芯片夹在编程器的烧录座上,打开电脑上的烧录软件,把单片机的程序加载进来,点写入,这就完成了。你可以发现,要想这样做,首先你得拥有一个编程器。第二如果你想改变程序,你还得把芯片拆下来,这是很麻烦的事。所以现在出的单片机就改进了这一点,你可以采用一个“下载线”对单片机编程,下载线实际上也是一种编程器。基本都可以自制,如果不想动手的话,买一个也很便宜,一二十块钱就搞定了。除了便宜,它最大的好处是可以在线更改单片要的程序而不要把芯片拆下来。这比使用编程器进了一步,但毕竟还得准备一个工具才能对单片机编程,再后来就可单片机可以直接从串口加载程序,连下载线都不要了。这样就让单片机使用更加简便了。
串口除了可以作为部分单片机的加载程序的接口,更重要的是我们在程序里可以写一些内容让它上报给电脑。因为程序写出来,能100%没问题的可能性基本为0,肯定会遇到这里或那里的错误,如果程序有错,它可能就不按你的思路走了。这时你必须找出我的程序哪里写得不对。如果没有任何提示,你只能抓瞎,所以在编程时我们会在一些位置上多加几句代码,让它通过串口上报一些信息,当它出现异常时,我们就可以根据这个信息来推断是哪里的问题。这样就可以方便地找出程序哪里写错了。
那好,我们看看串口是怎么工作的?
先看一个实例,你打开电脑上的记事本,然后你按A,则记事本上就出现一个字母A,你按B它就出B。你感觉这是理所当然的事,实际上这个过程并不是这么直接的。如果你的键盘出了点问题,完全可能你按A,而电脑上显示的内容却是B。我们先了解一下电脑和键盘是怎么配合工作的。实际上,你按一个键,它就会送出一组数据,每个键对应的数据都不一样。当然,哪个数字代码哪个键,它们都约定好的。比如0的编码是48 1的编码是是49 a的编码是97 b的编码是98 A的编码是65等等。每个都有一个对应的码。当你在键盘上按下大写字母A,键盘会发送65给电脑,电脑就知道键盘上A被按下了,于是就在显示屏上画一个A这样的符号。键盘上每个字符的编码都可以在网上查到,这张表叫ASCII码表,包括回车,退格键,都有各自的编码。
困了,先休息一下再写
不光键盘是通过数字编码的方式将你的动作告诉电脑主机。鼠标也是通过数字编码来报告它的行为的。在电脑里,所有的内容都是用数字来表示的。不同的地方,数字代表的含义不一样。摄像头也是通过一堆数据来告诉电脑它拍到的内容,你正在打开的网页也是一堆数据。还有电脑硬盘上存的内容,全都是一堆数字的编码。除了电脑,我们常见的手机,U盘,数码相机,MP3,它们全部都是使用数字编码来代表各种各样的内容的,所以它们都被称为数码产品。
扯得有点远了。回主题,串口是怎么来表示一个数据的?1用1V的电压?2用2V的电压?用不同的电压的确可以传递信息,我们的老式电视,收音机都是利用不同频率不同电压的信号来还原声音和图像的。这种做法看上去很直观易懂,但是它有一个缺点,那就是容易受干扰。比如我用0-5V表示0-50。0.1V表示1 0.2V表示2,这个看上去没有任何问题。但是,信号在传输的过程中总会遇到干扰,如果干扰的电压超过0.1V,原来0.1V的电压现在变成0.2V,那么所表示的内容就出错了,但是如果你用这种简单的方式来传数据,那么出错的概率就会很高。电脑里的数据并不是这样表示的,0-5V只表示两个数据,比如低于2V表示0.高于3V表示1。中间的不认。发送这一端想告诉对方是0,那么送出0V,如果想告诉对方这里是1,则送出5V。要想把它干扰得不能识别,干扰在信号线上产生的电压要超过2V才行,这是比较困难的。
比如发送端送出来的信号想传送的数据为1,因此它会送出5V的电压,在传输的过程中,它被干扰变成了4V,对端收到4V的电压,它就知道发送那端送给我的数据是1,当它再次将这个数据送给下家的时候,它仍然会发送5V的电压而不是4V的电压,因此这个干扰就被消除了。对来传统的方式,我想发送1,那么送出的信号是0.1V,干扰之后变成1.1V,接收端认为发过来的数据是11,那么它传给下家时,仍然是1.1V。如果下次再受个干扰,数据又变了。所以传统的方式传信号,遇到干扰就会很头大。
你可能会说,我用0V和5V来表示0和1,我想表示22,你不就傻眼了吗?而我用传统方式,发送个2.2V就行了。那这个只能表示0和1的货,怎么表能表示22呢?这个问题嘛,我们得换个思路。其实,这个不难。你看我们常用的数。中文一千,写成数字1000,中文五千三百二十一,写成数字,5321,看出点什么了吗?阿拉后数字里边只有0-9,如果不限制它的位数,它可以表达任意大小的数值。那么仅有0和1,如果你不限定它的位数,它是否也能表达任意大小的数值呢?当然可以! 先看阿拉伯数字,1位,可以0-9,10种值。两位0-99,100种值,可以写成10的2次方种。3位就是10的3次方种。对于只有0和1的数据,1位可以表示0和1,只有两种,很可怜。两位可以表示4种,即2的2次方种。3位就可以表示8种。4位就能到16种。你不限定它的位数,用阿拉伯数能表示的值,它也能,只不过位数多了很多而已。阿拉拍数,每数到10就进一位,我们称为10进制。而它,每数到2就得进行位,所以它称为2进制。你看那些科幻片,只要提到黑客在破解什么,满屏都是0和1在那里乱跑。为什么用0和1作画面就是这个原因。
所以 那么我们看一下,它怎么表示不同的数。
10进制& & 2进制& && && & 10进制& && & 2进制
0& && && &&&0& && && && & 8& && && &&&1000
1& && && &&&1& && && && & 9& && && &&&1001
2& && && & 10& && && && &10& && && &&&1010
3& && && & 11& && && && &11& && && &&&1011
4& && && &100& && && && &12& && && &&&1100
5& && && &101& && && && &13& && && &&&1101
6& && && &110& && && && &14& && && &&&1110
7& && && &111& && && && &15& && && &&&1111
看见了吧,如果继续向上数,你也应该能继续写,16就得用5位来表示了,变成10000。再看规律,我们平时计数,计到9就进一位,它呢0上面是1,1再上面没有了,就行进位,变成10。规则和十进制的没什么区别,就是位数太多,看得眼花。才到16就已经5位数了。比如一个电阻1亿欧,写成阿拉伯数欧,二进制表示一下000欧,估计你看到这么长的数字都快疯,眼睛是直接罢工。那怎么办?刚才读起来也费眼,所以我们会给它加上空格 1 ,四个一组,一组是万,两组是亿,这读起来就舒服多了。老外喜欢三个一组,写成100 000 000,一组是k两组是M 三组是G,所以这个电阻你不会叫它1亿欧,而是习惯叫它100M欧。所以作为一个搞家维中国人,你既要习惯于四个一组的中式分法,还要习惯于3个一组的老外分法,比较辛苦啊。
对于刚才二进制表示的一个亿000,我们也可以给它加上空格,但这次是老外投降了,也是用四个一组 变成101 10 00。分开之后看上去舒服一点了,虽然不会读它。这次老外按4个一组不是因为吸取了中国人的经验,而是在电脑发明的时候,大家规定了,8位二进制记为1个字节,分成4个一组最方便。
现在虽然分了组,但是记忆这么长一的串数字还真不容易。它的长度达27位。比起只有9位的阿拉伯数来说,难了太多了。为了方便记忆,我们四个一组四个一组地记,前面我列举了四位长度能表示的各种值,共有16种。比如22这个值,二进制1 0110 你根据那个表就可知道,第一组是1,第二组是6,因因此你可以记为16,但为了防止和阿拉伯数里的16混淆,我们习惯写成16H或者0x16。22可以表示为16H,那么30怎么办?30用二进制就是1 对应于14,你记作114H?那么怎么区分于二进制1 呢(相当于阿拉伯数276)?这个按这种写法也是114H啊。办法总是有的,0-9是几个符号,我再多加几个符号进来凑足16种就行啦。于是有人用A-F表示上表的10-15 这样就好办了。一位表示4位,所以30写成二进制变成1 1110,现在就可以记为1EH或者0x1E了。
那好,我们现在开始数数,0-35 ,用这种计法写出来就是0 1 2 3 ...9 A B C D E F 10 11 12.....19 1A 1B 1C 1D 1E 1F 20 21 22 23
看见了吗,和我们原来10进制时数起来也差不多,只不过原来我们数到9后面就得进一位,现在是数到F后才进位,所以每16才进1,所以这种计数又称为16进制,简写HEX,为什么要在原有数字后面加H,就是这里来的。
16进制& & 2进制& && && & 16进制& && & 2进制
0& && && &&&0& && && && & 8& && && &&&1000
1& && && &&&1& && && && & 9& && && &&&1001
2& && && & 10& && && && & A& && && &&&1010
3& && && & 11& && && && & B& && && &&&1011
4& && && &100& && && && & C& && && &&&1100
5& && && &101& && && && & D& && && &&&1101
6& && && &110& && && && & E& && && &&&1110
7& && && &111& && && && & F& && && &&&1111
呵呵,不知不觉我。 们把二进制 16进制与10进制的关系给讲完了。你可能会问,为什么搞这么复杂的过程,弄得我晕晕的。100 200 这种数字看上去多省力啊。非要搞什么1E 3DF之类的数字,我看到它们还得换算成10进制才能知道它是多少,太不给力了。我要10进制~~~。很遗憾的是,这种你看上去很费劲的数据,对于电脑来说,就像你看100 200 这种10进制数一样舒服。毕竟你是需要用它,你得将就着一点。就像你想和老外交流,你得学外语一样。让老外讲中文也不是不可能。比如你问老外,十加十是多少?他要先将这句话翻译成what is ten plus ten ,然后思考:ten plus ten euqals twenty,然后twenty翻译成中文是二十,然后再用不流利的中文和你说:二时~~(20)。同样,如果你需要让电脑来计算100+100是多少,它要先将100翻译成二进制 110 0100 + 110 0100 ,你可以尝试着用我们10进制的思路来加它,0+0=0 1+0=1 1+1=0 并进位。你可以计算出结果是,再换算出我们的10进制变成200。你可以发现这这个规则还能再简化一下,不看进位部分,有两种:相同的变成0,不同变成1。反过来看我们10进制计算,1+1 1+2 ..1+9,2+1,2+2...2+9.....8+9 9+9,有几十种。所以二进制的加法规则要比10进制的简单不知道多少倍,实现这个功能的电路就会很简单,所以它的计算速度非常快。所以你想电脑帮你计算,它要先将10进制转成2进制,算好之后再换成10进制让你容易看懂。
今天好像思路老是发飘,不旦讲了二进制,还讲了为什么要用二进制。继续聚焦串口上来
前面说了,电脑发明时规定了8个二进制为1个字节。串口每次都是传一个字节,所以多于8位的,拆成多组,每次传8位,不足8位的,前面用0补足,这也不影响结果。8个进制,最多能表示 换算出来就是255,0-255共有256种值。
比如单片机串口发送数据35H(10进制就是53)给电脑,表示为二进制 11 0101凑足8位 。那么串口会怎么弄?单片机串口平时的电压是5V,这表示1,然后它会变成0,告诉电脑,我开始发数据了。电脑那边发现数据线上的电压由5V变成0V,就知道串口要发数据了,然后就进入警觉状态,密切关注线路上电压的变化,在一定的时间之后,单片机送出第一位1(从最低位开始),所以这时线上面的电压就从0V变成了5V,持续一段时间之后,送下一位0,因于线路上电压又变成了0,这样连续8次之后,就把8个数据送出去了。送完数据之后,它还要再送一个5V,让线路上恢复初始的5V,以便下一次传输。对于电脑那边,它发现平时处于高电平(5V)的线上突然变成了低电平(0V),那么就知道马上有数据来了,然后就开始按预定的时间去一位一位地读,读完8个数据之后就知道对方发过来的数据是什么了,也就知道这是什么意思了。比如这次我们举例的数据是35H,电脑收到之后,它会去查表,这个35H表示的是什么,一查ASCII表就知道,这个值表示数字5,它就会在显示屏上显示一个5.
你可能会问,它怎么知道要等多久呢?我发送的时候是1ms/位 它却按2ms/位的速度去收,那不就错了吗?的确,这样就错了,所以我们要规定好速度。这个速度有个专有名词叫波特率,你打开超级终端,你会发现,它个值不是想设多少就设多少的,只有 00
等有限的几种可选。波特率就是每秒的位数。换算一下就知道每个位持续的时间了。比如9600的波特率 每个位持续时间为1/9600秒。一个字节有8个位,还要额外开销一个位用于通知对端开始传送(这叫起始位),还要开销一个位用于通知对端传送结束(这叫停止位)所以发送一个字节需要10个位,每秒9600个位,只能发送960个字节。如果想发送更多数据,只能提高波特率。使用19200或其他更快的,但必须选用那几种可选的。否则无法正确通信
老师你好,我想请教几个有关单片机烧录方法的问题,不知老师能不能帮我解决困扰,先谢谢老师。
&&一、 单片机在烧录时会有单片机的引脚要与编程器相连接,而这些引脚在不同的单片机、不同的编程器上会有不同的引脚功能标识,我想求教老师,拿到一个单片机如何判断出他的那个引脚是:TXD、RXD、MIOS、MOIS、CLK、RST、MCLR/Vpp、PGD、PGC、OSC1等与编程有关的引脚。
&&二、老师能不能传我几个有关单片机烧录的具体软件,比如通过TXD和RXD端口烧录的、通过MIOS、MOIS端口烧录的和通过MCLR、PGD、PGC等端口烧录的软件以及其它实用软件。谢谢。
三、老师我想求教一下,有的单片机烧录软件在我的电脑上有时候能正常打开应用界面,有时就不能打开应用界面,这是为什么。
四、老师能不能给我几个简单容易业余制作的单片机烧录编程器图纸,比如PIC系列单片机的,谢谢。
老师你好,我想请教几个有关单片机烧录方法的问题,不知老师能不能帮我解决困扰,先谢谢老师。
&&一、 单 ...
看来你没有怎么接触过编程器。
每种编程器都有自己配套的软件,打开软件就有可以支持的芯片型号。芯片夹上编程器,选好型号,它就知道哪个脚是什么功能了。你只要选择好要写进去的文件就可以了。
既然编程器都是配了软件,那就不存在软件问题了
自制编程器,很费时,还不如买一个,才小几十块钱
今天再增加一个新的东西,那就是ADC,也就是模数转换器。对于很多单片机,这个是单片机上的一个功能,所以用起来很方便。
前面说过,单片机的管脚可以作为输入,但是它的输入很简单,非0即1,什么意思,就是说你给它加一个电压,它只会将它认为两种状态,要么为低电平(我们记为0),要么为高电平(我们记为1)。多少才是高电平,多少是低电平,这是有标准的,一般来说,0.7倍的VCC(供电电压)以上,就认为是高电平,0.3倍VCC以下,认为低电平。对于5V供电的单片机,那就是3.5V以上,它就认为是高电平,1.5V以下就认为是低电平。那就有人会问了,如果我给它一个2.5V的电压,它是认为高电平还是低电平呢还是其他呢?单片机只可能识别出高或低,这种不高不低的电压,被认为是高还是低,就是各单片机的,比如你用这块单片机,它可能认为是高电平,但你换一块,可能就认为是低电平了,所以这种不高不低的电压是不应该出现在数字电路里的。万一真的出现了,认为是高还是低就不好说了。前面说的0.7VCC和0.3VCC只是说,如果你的电平达到了0.7VCC时,我必须认为是高,否则我这个单片机就不合格了。但是你说,如果电压为0.69倍的VCC,你认为是高还是低?可以说绝大部分单片机还会认为是高电平,但是如果认错了,那我单片机厂家是不负责的。
因为有规定,0.7倍的VCC就一定要认为高电平,那么我发送的时候,要求就更严了,一般芯片输出高电平要求达到0.9倍VCC,低电平小于0.1倍VCC,这样输出高电平至少要达到4.5V,比接收端要求的高于3.5V要多出1V的余量。因此就算是遇到一点点干扰也不至于出错。同样,低电平时也有1V的余量。
介绍完了单片机的管脚只有高或低两种状态,那么对于我们电路中很多信号都是一个变化的电压,那怎么玩?比如锂电池,充满了4.2V,随着电量的减少,电压也慢慢下降,降到3.5V以下,基本就没什么电了。而按刚才那个标准,单片机会一直认为它是高电平,根本无法知道电量还有多少啊。为了解决这个问题,很多单片机上会集成一个ADC功能,也就是模拟-数字转换器。
这一功能一般只能在指定的某个管脚上才具有,具体哪个管脚,不同的单片机都不一样,所以你需要去看这个单片机的资料。通过设置单片机的一些寄存器,ADC这个功能就可以使用了,当你将一个电压接在这个管脚上,单片机里有一个寄存器里的值可以随着电压的变化而变化。
就和你的万用表一样,分别测1V和1.002V两个电压,如果你用指针表,很可能看不出任何区别,这时因为你的万用表分辨率不够,如果你用三位半的数字表,那就能看出区别来了。同样,单片机里的AD也就一个分辨率的概率。比如一个8位的AD,也就是说它的结果只可能是0-255之间的一个值,它用0-255表示0V到VCC的电压,VCC一般是5V,算一下5/256差不多0.02V,这是什么意思,0-0.02V的,寄存器里的值就是0, 0.02-0.04 寄存器里就是1,以此类推,比如4.2V的电压,读到的就是4.2/0.02=210,如果电压为3.5V,读到的值就是175。所以你可以根据读到的值来知道这个管脚上的电压是多少,这样程序里可以根据这个管脚上的电压进行相应的功能。就像锂电供电的设备,例如手机,当电池没电的时候,它会自动关机。这个关机是软件实现的,手机在运行时,里边的CPU(你可以当它是一个很强大的单片机),也能像这样读取电压,并根据电压在手机上方画一个电池的图标告诉你还有多少电量,当电压低到3.5V时,它会显示电池空了,然后执行关机。
对于一个8位的AD,电压变化在0.02V以内,它是无法显示得出来的,要想显示这种更小的变化,你必须使用更多位数的AD,比如10位的,它能显示0-1023 这样0-5V被分成1024份,每格差不多就是0.005了。
有了AD,单片机上的某些管脚就可能测量电压了。很多传感器都是以电压来反馈信号的变化,因此只要将一些信号转为电信号,那单片机就能感受到它们了。比如热敏电阻,它的电阻会受温度影响,我用一个普通电阻有一个热敏电阻串起来,然后来测量热敏电阻上的电压,经过换算就能知道当前的温度了。如果换成光敏,我就知道外界的光线强度。如果换成压力传感器,就可以知道压力,如果这个压力传感器连在氧气瓶上,那就知道瓶里大概还有多少气,如果它是绑在胳膊上,再配上气泵和袖带,那可能测的是血压。所以有了AD之后,单片机的应用一下子活跃了很多。它再也不是一个只认识0和1的芯片,而是有了自己的感官了。通过软件的配合,那就没有边际了。就是只有想不到,没有做不到。
我想知道怎么编程
不知道你是对编程是什么个理解
或许你认为编程只是一个步骤,而实际上,编程是一个可大小可的事情。简单的程序,几十分钟就够了。复杂的程序,按年为单位也不为过。
编程,说得简单一点,就是将你的想法用C语言或汇编语言描述出来。但是C语言能接受的语句就那么几种,你得想办法用这么一点点东西,来描述你的想法。
接下去,我会找一款适合学习的单片机,然后从搭硬件电路开始一步一步地讲到简单的编程。
从第一讲到现在已经过去不少天了。
前面的内容,不涉及任何具体的单片机,并且是以我自己的想法,尽可能地让大家易懂的描述。
从这一讲开始,我们要动手了。
动手之前,我要先说明一下,不管你是用哪种单片机,它们的用法和步骤都是差不多的。芯片资料你得得看一下的,不一定要每章都看,只要关心你需要关心的部分。具体是哪些,我们会在后面的讲座里提到。学习不光是简单的模仿,而是让你有一个思路。另外,这些单片机的资料基本都是英文的,如果你英语不好,只能选择那些有中文资料的单片机。虽说削减了你的选择范围,但是它们的原理都是差不多的。只要你会玩一种,其他的都是触类旁通的,就看你有没有办法弄懂它的资料。
现在我们要认真地做一件东西出来。但我也不知道大家想要一个什么,所以想看看大家需要一个什么,我目前想到的是做一个充电器。如果大家有更好玩的东西,也请说出来,我会根据难度选择一个合适的。
期待大家的回复。。。。
这里的人气比较淡啊。
只有楼上这个响应了。
我也不知道空压机的控制器是干什么的。那我们就做个类似的吧。
做一个什么呢?温度控制器。通过一个实例来看看它是怎么工作的。
楼上要的控制器,估计原理也差不多,等你把它弄明白,问题也就不大了。
既然要实际操作,那么就得有实际的东西。所以我们得选择一个单片机。
首先,这个单片机需要是插件的,为什么选它?脚间距很大,如果是那种贴片密脚的,一是必须定制电路板,二是密脚的不一定都能焊好。所以我们选用普通插件的单片机,它的脚间距2.54mm。
第二,这个单片机上面要集成AD转换功能,因为我们很多传感器它都是通过电压或电流的变化来反映的,为了简化电路,我们用集成了AD的。虽然它的精度不够,但作为学习也能凑合了。
第三,这个单片机的烧写工具必须简单,那些通用编程器虽然功能强大,但价格都要几千大洋,划不来,所以我们要找一个工具便宜的。
第四,单片机不要太贵,一般来说,贵的性能会好,但是对于初学者来说,功能越多的东西越复杂,反而容易头晕而失去兴趣。
第五,资料要有中文的。大部分的芯片资料都是英文的,这对这里的很多人来说,是个头大的事。
下面简单地介绍一下常见的单片机
1&&51单片机,这是一个很庞大的家族,很多公司都有51型的单片机,这是我们国内教材最多的一种,本来我想拿它来学习的,但是找不到合适的单片机,AT89S51不带AD STC的带AD但是资料看上去特别山寨,讲得给不够细。还有si lab的C8051F,它简直是我见到最强悍的51单片机了,速度快功能多,但是价格高。也不太适合初学。
2.PIC的,PIC是micro chip公司的一种单片机,它的指令特别简单,据说抗干扰能力不错。拿它练手也是不错的选择。可惜的是英文资料为主。
3.AVR AVR是Atmel公司的一种单片机,这个也是我接触得比较多的一种,因为能找到它的中文资料,并且符合我们说到的几个条件,所以决定用它
4. ST公司的STM8 它的性价比不错,最大的一个优点是直接可以连电脑调试,缺点是没有插件的封装,只好放弃。
那么好,单片机就选择AVR公司的ATMega16这款单片机
万能的淘宝上可以搞定我们需要的所有器件。
单片机,直接搜atmega16 要那是双排直插的,40脚的那种。mega16有一种是mega16L,这种可以用3.3V供电,也可以5V供电,但它只能跑到8M,不带L的只能5V供电,但它可以跑到16M。我推荐使用带L的,因为这样你接一个锂电池在上面就行了。否则还要整个5V出来,麻烦。当然,你不嫌麻烦也没事。买2-4片,以免被不小心弄坏。
下载线:去搜AVR 下载线。也是几块到十多,无所谓的。
其他东西有洞洞板 排针 小电线 电阻 发光二极管,其他你需要什么功能,根据自己的想法购买。这些东西尽可能集中在一家以节省邮费。一般卖下载线的那里都会有这些各种小的电子元件,你们网购时顺件买了就成。
资料你可以百度ATmega16中文资料,或者百度文库里 ATmega16 官方中文PDF 官方翻译
既然我们选择了这个单片机,那我们就得看看资料里说了些啥吧。先看第一页。那里有芯片的特性介绍。我就捡重点说了。
131条指令,大多数是单周期。多少条指令我们就不需要关心了,因为我们不打算用汇编,大部分为单周期,这就是说,大部分指令执行只需要花一个周期的时间,如果我们用8M的频率,那么,一个周期只要0.125us。而51单片机,至少12个周期才能完成一条指令。所以这个单片机速度比较快。
16k什么什么flash,你写好的程序就存在里边,16k感觉非常小,一个25系列的小芯片还几兆呢。但是你用了就知道了,16K够你写很多很多了。
寿命1万次,也就是说,如果你发现写错了,改一次代码就要用掉它一次寿命。不过1万次足够你玩了。
512字节的EEPROM,这个芯片还有512字节的空间可以让你放一放设置的内容,可以实现掉电后你原来的设置还在里边。怎么用先不管
1K的SRAM,这相当于内存,比起电脑以G为单位,这个小可怜,但是比起51单片机可怜的128字节还是大了不少。
余下的内容,等用到的时候再说。
比起很多单片机,这才能算是真正的单片机:你只要给它接上电源,它就可以工作了,所以它还是很简单的。
可能你看到这里还是晕晕的。不要紧,在下面的时间里,我要让大家一点一点地了解。不要认为它会有多复杂的,所以的东西都是和堆积木一样。是一种水到渠成的事。
下面开始一个要做一个东西:温度控制器,实现的的功能是当温度高于设定值时,接通一个继电器。继电器后面接什么,看你的了。比如我后面接压缩机,这就是一个简单的空调控制器了。那行,我们就想办法实现一个简单空调的温度控制器。一步一步地来,最后我们要连遥控功能都加上。
做一个东西之前,你肯定已经想好了我要做什么。现在我要做一个控制压缩机工作的控制器。当温度高了就要让压缩机工作,达到温度之后关掉压缩机。
你想控制压缩机,你得用个继电器。继电器的线圈通过单片机来驱动。这个电路很简单,估计大家已经想出来了。另外,怎么才能让单片机知道当前温度呢?这个也简单,修空调的都知道空调里有个温度探头,它实际上就是一个热敏电阻。我只要能知道电阻值就能知道温度。怎么才能知道电阻值呢?你不要告诉我用万用表。的确,用万用表最简单,问题是单片机不会用万用表啊,但是单片机的AD功能可以测量某一管脚上的电压,你得想办法将阻值变成电压,最省事的办法是用一个固定电阻和热阻电阻串联接在电源上,测量其中一个的电压,然后就能计算出它的阻值来了。那么得了,这个电路思路已经完工。
600)this.width=600;">
图应该很好懂吧?
单片机用到了2个管脚,电源和地那是必不可少的,除此之外,还用到了两个,一个是用于输出,控制继电器。另一个是用来输入,用来测量温敏电阻上的电压。单片机要做的事就是测量电压,然后计算出电阻值,再查表得到温度。如果温度高于设定值,则将控制继电器的管脚输出高电平(压机运转),否则输出低电平(压机停止)。
本帖最后由 jimsboy 于
21:40 编辑
最近有点忙
前面思路已经讲了,现在就得把它具体成电路图了。具体到电路图,那就得确定哪个线连在哪里。所以我们必须对芯片的管脚功能进行了解。所以,你用到的芯片,基本都得知道每个管脚是干什么的。如果实在搞不懂的,看看厂家的参考设计。
那我们先看看MEGA16的各个管脚吧。
600)this.width=600;">
单片机的管脚功能很多是复用的,有些功能是必须在哪个管脚上,如果你想用该功能,则这个脚就不能作为其他用途了。具体的功能要看管脚的功能描述。当你看多了之后,你一看名子就大概地知道它是干什么的了。
从第1脚看过去
1-8 基本功能是PB,一组数字IO口。可以作为输出也可以作为输入。我们设计里用到一个ADC输入还有一个数字输出(用于控制继电器开或关的),由于它们都是数字IO口,不是ADC的输入口,所以在我们的设计里,输入端口不能选择它们,但作为输出倒是可以选择其中的一个,也就是把继电器接在这些脚上倒是可以的。具体用哪个看你的心情。
1-8脚除了作为数字IO口外,它还有第二功能,
PB0和PB1可以作为计数器的输入,但是我们在这个设计里用不上,不要关心
PB2和PB3是一个模拟比较器,注意这是模拟比较器,不是AD,所以我们的设计也用不上。
PB4-PB7,这是一个SPI接口。我们前面没有提到。但是我要告诉你的是,这个单片机是使用这几个管脚加载程序的,所以我们得把它们预留下来,烧程序时需要用到,如果你在上面接其他东西,你得考虑在加程序时是否会造成意外,因为你目前还不怎么了解它,所以最好的办法是尽量把它们空出来,专用作为加载程序的接口。
9是复位,必须的.reset上面一条横线告诉你,当为低电平时,单片机就处于复位状态。一般来说,复位脚要能让单片机上电时能处于复位状态,过一小段时间又要解除复位。所以大部分电路对复位管脚外接一个RC电路。这个芯片是低电平复位的,所以该脚通过一个电容接地,通过一个电阻接电源。上电的瞬间,电容里没有电,所以reset管脚被电容拉在比较低的电位(低电平),这时电容通过电阻充电,电压慢慢上升,当充到一定的电压时,RESET就认为是高电平了,这时复位解除,单片机就开始运行。用不同的电阻和电容,就可以实现不同的延时值。
但这个单片机把这个功能也做到芯片里去了,所以你可以让RESET管脚悬空都不会影响单片机的运行。如果换作普通单片机,这是万万不可的。
10和11 电源和地,这两个你也不接那就说不过去了。必须接,怎么接不要我教了吧。但是注意,单片机虽然耗电不大,但是实际上它的瞬间耗电非常大,所以你必须在靠近电源和地的地方安装一个小电容(一般0.1uF)。否则会引起瞬间的电压跌落,这个持续时间非常短,你用万用表根本测不出来,但是这个电压跌落可能会使单片机状态混乱,就会出现意想不到的状况,为了保险起见,都会给它接上这么一个电容,一般还会在旁边还会再放一个10uF到几百uF级的电解电容。
12 13是接晶振的。普通的单片机,这个也是必须的。而它默认状态下它也可以省略。但如果你买的是旧单片机,并且人家已经设定了使用外部晶振,那你就得给它接上晶振了,否则单片机无法工作。所以如果你用二手的单片机,你最好是备个晶振。2-8M的都行。
14 15,这是串口,虽然我们这个设计里用不着,但是这个可以方便我们调试程序,所以也留着。
16-21 PD,可以作为数字IO口,你也可以选择这几个来接继电器,同样不能作为AD输入。
22-27 也是数字IO,随你用。
22 23 这是IIC,我们这次用不上
24-27 TCK TMS TDI TDO,这是JTAG口,可以接仿真器。如果你买了仿真器,可以把它们接出来,我没有这东西。空着吧。反正用不上
30 31 这是模拟部分的供电,如果你需要考虑AD的转换精度,就可以给它额外供电,这里说的额外供电并不是让你再去搞一个电源出来,而只要对原来的电源加一个电感(或10欧左右的电阻),然后对地接个电容,做一级滤波就可以了。如果对AD精度不高时,连在一起也无所谓。
32 AREF ,这个电压会被分成1024份,你输入的电压是多少份,那么AD转出来的值就是多少。为了好计算,比如我给这个脚供电4.096V,分成1024份,一份就是4mV。那么如果AD管脚上的电压是4mV,那么转出来的值就是1,如果是2400mV,那么转出来的结果就是600。就这么个意思
一般来说,如果为了省事,我们会把它和AVCC接一起,比如电源电压5V,分成1024份,每份4.883mV。用也能用,就是计算比较麻烦。所以这个管脚你给它接4.096V还是直接接电源,看你的习惯。接5V省事,但计算麻烦一点,接4.096V计算简单,但你得用硬件搞出一个4.096V的电压来,硬件麻烦。我们这里直接接电源吧。
33-40,看见了吗?除了作为数字IO口,还能作为ADC,所以我们的输入只能从这里边选一个,选哪个看你的心情。输出也可以从这里边选。
所以我们这个输入的只能在PA0-7里选一个,输出则是有很多选择的余地。我们就选择PA0作为输入,PB0作为输出吧。因此这两个脚要引出来。
编程需要用6-9脚,我们也得引出来
10 11 30 31 32是电源和地,也引出来。
OK,已经胸有成竹,我们得把竹子画出来
600)this.width=600;">
好了,原理图也画好了。很简单,这个单片机上很多管脚都没有用得上。MISO MOSI等4个脚引出来是用来加程序的。
晶振可接可不接。我们先不接。
刚发现错误了,C23应该是接在电源和地上的,结果我接错了位置。原图没有保存,所以没办法改了。
这个对我来说,没什么难度,常用物料公司都有,不常用的离华强也不远。所以我可以想到什么买什么。在内地的朋友们就得想着一点了。要么你先不管三七二十一,常用物料都买一点。这样一搞,没有个几百块钱下不来。如果缺什么再去买,邮费可能伤不起。所以你们就先看着,缺什么了先记着,到时候一起买。电阻电容什么的我就不提了,如果你搞维修或制作的,连常见电阻电容都没有,那就是你的不对了。
600)this.width=600;">
我们要准备的: 最上面蓝板,是ISP下载线,不一定要是这个样子的,但一定要能支持AVR或mega16(mega16 是AVR的一种)。它实际上就是一个编程器。只是它可以直接加载程序而不要把芯片拆下来。
右边是一个USB转TTL串口的板子,中九的升级板就是这东西。那个是我自己做的,很丑。再右边的线是下载线的插头,买下载线都会带一根的。
最大的是万能板,也叫洞洞板。这东西可以多备几块。我这种是很便宜的,有一股臭味,铜皮容易掉,最好是买环氧板。这是我从家里找出来的,凑合着用吧。我这个大小是9*15cm。一般买这么大的或者一半左右的。再小的还没怎么弄就没地方了。不爽。
单片机是必须的 ATmega16,最好带L,带L的可以用3.3V供电。也可以5V供电,而不带L的只能5V供电。
单片机座,也就是IC座,40脚的。我没有,我用那个圆孔排针代替。用它的好处是做完试验还能把芯片拆下来。如果你去华强买一个这种座子,人家会鄙视你的。所以我只好用很贵的圆孔排针座代替。
排针 2.54间距的。最好双排的,因为加载线的插头就是双排的。你买单排焊两排也一样用。排针是实验时常用物品,买个十根都不要紧。
旁边一个数码管,有时要显示点信息,没有显示屏还是不方便的。
最下面继电器,5V的。继电器上边有一根黑线,那是温感。一种热敏电阻。我那个是10K的。
其他,还需要细的电线(外边有绝缘胶皮的),按钮开关你也得备上几个,因为很多操作都是按键来实现的,红外遥控接收头也是常用的。
差不多就这些了。可以开搞了。
有空我把它们焊起来。
{}期,一个周期是多少?根据手册,这个单片机的振荡器的频率为4M,每4个周期为1个指令周期。也就是说1秒可 ...
PIC的单片机是四个振荡周期为一个机器周期
也就是说晶振振4次,才能完成一个指令。
晶振一般用的是4M的,一个周期就是0.25us。4个晶振周期才是一个指令周期,所以一个指令周期是1us。所以指令执行的速度是1M
我们现在用的是AVR,它一个晶振周期就是一个指令周期。一般我们习惯用8M的晶振,它的指令执行速度就是8M。因此AVR的运行速度是很快的。
好久没有更新帖子了。
这几天比较忙。也没有时间搭电路,我们先做软件部分。单片机必须写给它写入程序才能使用,对于很多维修员来说,写程序只是用烧片器加载一个bin文件,然后一点写入就完事了。其实这只是将已经编译好的程序加载到单片机里的过程,要想生成这个bin文件,里边或许有想像不到的工作量。
为了得到一个按我们想法工作的bin文件,我们必须学会编程语言。而最常用的就是C语言了。所以我们在讲解的过程中,必不可少地会讲一点C的内容,虽然我讲的内容不够全,但是凑合着够用,如果你有兴趣,自己再去补习一下C语言的全部,也不是很难的事。
既然要编程,你必须有单片机的开发工具(含软件),硬件是ISP下载线,前面已经要求购买了,还有一个硬件JTAG,JTAG在调试程序时很方便,但价格原因没必要购买。开发使用的软件一般是单片机厂家提供的。比如我们这次要用的AVR开发软件(习惯叫开发环境),是AVR的公司提供的,这个软件叫avr studio,你可以在网上免费下载的。这个软件用起来很方便,只是有一个缺点那就是只支持汇编语言。这是非常要命的事,因为用汇编写点东西非常痛苦。所以我们必须找到AVR的C语言开发工具,这种工具一般会有多种,最常用的就是免费的winavr。另外这里有一个好消息,那就是你安装winavr之后,就可以直接在avr studio里使用C语言进行编程了。所以这两个软件就是绝配,因此你必须同时安装这两个软件
我好久没有使用AVR单片机了,为了给大家演示,临时在网上下载了软件,这是我下载的地址
我也不知道允不允许贴网址。
先安装winavr,两个软件安装好之后,启动avr studio
600)this.width=600;">
呵呵。英文的。没办法,谁让这公司是美国的呢。不知道网上有没有汉化版的。我没时间找,大家就凑合着看吧,记住点哪里就行。其他功能看不懂也不去用,省心。
我们可以看到下面那个框里是空的,如果我们已经做过了一些软件了,那么这些软件会列在下面。现在我们没有软件。我们必须先新建一个。
左上角那个图标,像写字的样子的,那是创建一个新的工程。我们就点它。右边那个是打开工程,如果你已经有做好的了,那么可以用它打开。这个是电脑的基本操作,不多说。
点下新建后进入这第二个图的界面,在这个界面里,我们要选择AVR GCC那一项,就是使用C语言进行编程,如果选第一项,那就是用汇编语言编程。我们这里选GCC。
600)this.width=600;">
给工程起一个名子,我给它叫wenkong,呵呵,就是温控的拼音,尽量不要使用中文字,有些软件不认中文字,那就会出莫名其妙的错误。我这里存放的位置使用了中文,也不知道有没有影响。
下面开始进入软件的时间。主要就是C语言相关的内容和开发环境的使用了。
前面说过,电脑会将我们写的代码变成bin文件,这个过程中叫编译。代码里边详细地“描述”了每个步骤,单片机只要按照步骤一步一步地做就能达到目的。你写的这些步骤就是代码的内容。但你的那么多步骤里,哪个是第一步呢?根据我们的习惯,我们会认为最上面的一句是第一步。这很符合我们的思维习惯。而我们前面的伪代码也是这样写的。
但是C语言不是这样规定的。C语言规定,你的程序的第一句在main()里边的第一句话。
具体的就是这样写
&&第一句代码;
&&第二句代码;&&//注释,这是什么什么什么意思
规定了,你必须写一个mian(),然后是一对大括写,指明哪里到哪里是main的范围。然后里边就是一条条的指令了。
前面也说过,程序必须是一个死循环,否则单片机执行完最后一条指令之后就去休息了,然后就不知道它干什么去了。
另外,每一句代码的结束处,必须要有一个英文的分号在后面。这也是规定。
两个靠在一起的斜杠//后面是写注释的,你需要养成写注释的习惯。这个方便你维护它们,同时还有利于减少错误。
在C语言里,有很多个类似于
这种结构的东西。它有一个名子,叫函数。可能有些人听到函数这个名子头就疼。因为在上学时被这个东西折腾得快发疯了。这里你不要害怕它们,因为它们没那么复杂。
为什么需要有很多这种结构,因为我们的一个程序往往都是比较复杂的,如果你写在一个里边,这原则上也是可以的,但是实际上会很麻烦。主要的麻烦还是调试时很头大。因为你不是神仙,写出来的程序一定会有错误,你必须找出它们哪里出错了。我刚开始写程序的时候也就是一个mian函数,所有的功能都写在里边。但这个习惯慢慢就变了。
一个程序有很多个函数组成,每个函数又由很多句代码组成。我们用实物来打比方吧。
如果你购买了一台电视机,它能给你带来什么好处不需要我多说吧。你可以认为这是一个程序。但是你不可以拿电视机代替洗衣机的功能。所以程序也是这样的,我写好之后,它是什么功能就已经定死了。
如果你拆开电视,你会发现,它里边有一堆器件,电容电阻二极管,再加各种集成块。这些小器件就类似于代码。一个电阻,装在电视机上能修复一台电视,如果装在洗衣机上,则能修复一台洗衣机(前提是你必须装对了)。所以当工作制造出这颗电阻来的时候,它是没有考虑过它会被用在哪里。代码也是这样,它们也是基本通用的。只是说你必须用对了。
而函数是什么 ?我们好像没提到,实际上,函数就相当于电视里的电源 伴音电路 这类名词一样,它们在电路板上并没有明显的界线。它们只是为了利于维修而人为地划分出来的一个个功能模块。但这种划分也是有好处的,那就是说你只需要检查相应的部分,而不是整板地找问题。所以我们的函数就像相于这个的功能模块。
如果你看得晕晕乎乎的,也不要紧,先看实例,等熟悉之后,我们再回过头来看它们,你就容易理解了。
下面开始程序的设计。
我们要实现的功能是测量温度,如果温度高于一个值,我们就控制继电器吸合。否则就断开。功能也是很简单明确。
那么我们画出这个程序的流程。
600)this.width=600;">
这个图就是说明了整个流程,因为它的功能简单,所以画起来很容易。如果功能复杂的时候,画这个图往往需要花费大量的工作量。但是如果你把这个工作做好了,那么你会减少很多的麻烦。画完之后,你需要尝试走一下,看看它到达的每个地方是否是你想要的,会不会出现你不想要的路径。同时你还得看一看,这个程序会不会出现一去不复返的问题。
我们看这个图,程序开始后,第一件事是测量温度,测完温度之后需要判断温度是否超过26度,如果超过,则打开继电器。如果没有超过,则断开继电器。不管是打开还是关闭继电器,当做完这件事之后,程序又需要回到测量温度这个地方,进行下一次循环。所以程序一旦上电之后,它就永远在执行这个循环直到断电。所以你写完这些内容之后,你就可以得到一个温控器了。
下面就该写代码了。
不管三七二十一,先写上
然后再把光标挪到大括号内写内容。注意,括写必须成对出现,为了忘写括号的另一半,我们写的时候就是成对的写,然后往中间塞内容。
下面的事,就是往大括写里写内容了。
今天我们开始写程序吧。
打开avr studio这个这软件,在source file里边有wenkong.c。双击wenkong.c你就可以在光标处写内容了。
source file中文叫源文件。我们的代码有一个洋气的名子,叫源文件。所以你记住了,源文件就是我们的代码内容。
写什么内容呢?看我上次帖子里框图。我们要把这框图的内容用代码描述出来。
C语言规定了,程序是从main()这个函数开始的。你必须有这么一个函数,名子叫main()。所以我们得写上
然后我们在大括写里写内容。可能大家看到这里边空荡荡的,心里有点发述,我该写什么啊,好困难啊。呵呵。万事开头难,所以最简单的办法是抄人家的。
我先写几句,大家先抄进来。抄进来之后就不会再觉得空空荡荡的了。
& & //关闭所有中断
& & cli();
& & //OSCCAL =0
& & ResetGlobeVariable(); //初始化全局变量
& & cpu_init();&&//初始化硬件
& & /*再次打开中断
& & 到这里,硬件已经初始化完毕
& & sei();
& & //&&UART_Send((UCHAR *)(&Hello\r\n&),7);
& & while(1)//主循环
这一段我也是抄来的。这样好歹看上去像个程序了。你心里或许就会舒服一点了。
大概地说一下,连续两个斜杠//在C语言里表示本行从这里开始后面都是注释。注释的作用是为了让你N久之后看到这里能回想起当时为什么要这样写。对调试有很大的作用。所以为了你的程序容易读懂,尽量地把你的想法写在程序里。如果你的内容太长了,一行写不下怎么办?你可以在注释内容的每一行前面都写上//。但这样写很麻烦。你可以写/*,软件为认为后面的内容全都是注释,所以你必须在注释的结尾处写上*/告诉软件我的注释到这里为止。
这上面的内容几乎是通用的。就像古装片里开打之前总得先比划上那么一段然后再开始出招一样。
下面说一下每一行的内容
cli(); 这行前面已经有注释了,说关闭所有中断。这种带括号的都是函数。如果它出现别的函数里边,那就是调用的意思。如果不在别的函数里,那么就是定义的作用。如果你读不懂这句,先记住有这么个事情,后面再来理解。我们后面要讲述它的。
为什么要关闭中断呢?前面说过,中断可以让程序临时跳到其他地方,在那里把事情做完了再回来。因为这时单片机刚上电,它里边很多状态都不确定,所以先关闭中断,以免程序跳到我们不知道的地方去。
//OSCCAL =0
看到前面的//吗?它现在是注释。但它说的什么你也看不懂。其实它该是一句代码,我们可以在芯片资料时找到OSCAL,这是一个微调振荡频率的,通过设定不同的值可以微调内部RC振荡器的频率。因为芯片出厂时,虽然它标称8M,但实际上可能会高一点或低一点,而且还会随温度的变化而变化。如果你对频率精度有要求,则需要对它进行微调(校准)。因为我们这个对时间精度基本没有要求,所以我们不需要这一句代码。你完全可以删掉。但是我说过,这是通用的,为了让你在需要精度时知道在哪里校正,所以我们这里把它变成注释,如果你需要用到的时候,只要去掉前面的//就可以了。同样,我们对于一些不需要用的代码,也可以用同样的办法让它们变成注释。
再下面两个函数,后面都有注释,是用来初始化全局变量和硬件的。可能有人不知道什么是初始化。因为单片机刚上电时,里边很多状态都是不确定的,初始化就是把我们要用到的内容先设定一个值,这样我们就知道它的值是什么了。
再后面有sei();这是打开中断,如果你的程序用到了中断,那么有必须使用这句话来允许中断执行相应的程序。如果你不需要使用中断,那么可以注释掉。我们等后面看看,如果需要使用中断,则留着这一句,否则用//注释掉。
再下面是while(1)
while翻译成中文是“当...时”,这个句在C语言中是有含义的,它的意思是当()里的内容不为0,就会执行一遍括号里的内容。执行完一遍之后再看看()里是否为0,如果不为0则再执行一遍,如果为0则执行{}下面的内容。我们这里给它写了一个1,这就意味着()里永远不会为0,所以它就会一遍又一遍地执行{}里的内容,也就是在里边死循环。这个死循环是单片机程序必须的。否则CPU执行完这里的内容之后就会继续向下,当它执行完main里的最后一句的时候,它就去放羊了。它在干什么你永远也无法知道了。所以我们必须把它困死在main()里边。
因为我们的程序永远也不会离开while(1)后面的大括号了,所以写在这个大括号下面的代码永远也没有机会被执行,所以在}之后也不会有任何代码。
到现在,我们已经搭好了框架了。现在我们得向里边填内容了。不需要的东西要删掉
里边有一句 ResetGlobeVariable(); //初始化全局变量
全局变量?什么叫变量?还有全局之说?先解释一下吧。比如我们要对某个管脚上的脉冲个数进行计数。很显然,计数的结果你总不能抓在手上啊。必须放在单片机里的内存中。C语言要求你必须给它起个名子。名子的内容任意,但必须是字母或者数字或_,不允许用中文(明显的地域歧视啊~~),另外名子不能以数字开头。起好名子之后,它里边的值是多少我们是不知道的。所以我们必须给综一个设定一个,像这里计数,我们显然是从0开始,所以我们必须先令它等于0.这就叫初始化。
这个名子就叫变量。至于全局变量,就是哪个函数都可以用的。所以它必须写在所有函数的外边,一般我们习惯写在所有函数的上面。那不全局的,就是写在函数里边的,写在哪个函数里边,就只有哪个函数可以用它。
现在我们也不知道用不用得上,先把它注释掉,等要用到的时候再把它恢复回来。如果你不用//直接删掉效果一样,但是想恢复回来就得手工输入了,没有打两个/来得方便 。
初始化硬件,那是必须的,因为我们要指定哪个管脚是输入,哪个管脚是输出啊。初始化的内容写在哪里呢?写在mian的外边,前面说了,写在外边是定义。所以我们必须在main(){}的外边重起一行写cpu_init(){}。这里{}里就是具体怎么初始化的代码了。
程序从main开始,执行到cli();它就去找cli()这个函数,这个函数是编译器提供的,所以你不需要写它的具体内容。
然后ResetGlobeVariable();但它被我们刚才注释掉了,当作不存在。
再下来cpu_init();&&//初始化硬件
这时编译器就会去找cpu_init(){}这一块内容,如果找到了,则会把这里边的内容执行完毕再执行下一条代码,如果没找到,编译就会出错,你就无法生成bin文件,连文件都没有,就更谈不上执行了。
执行完cpu_init()后面{}里的内容,程序会回到main里继续下一句 sei(); 这个也是编译器提供的,也不需要你写。执行完这一句之后就会执行while,
while后面是1,不为0,所以它就把括号里的内容执行一遍(目前我们括号里为空的。但实际上我们要写内容在里边的),执行完一遍之后,它又会回到while这里,括号后面还是1,它又把大括号里的内容执行一遍。这里边永远为1,所以它就一遍又一遍地执行大括号里的内容。
所以我们只要在这个大括号里写上以下的内容(当然,要把这些文字写成代码)
读取PA0脚上的电压(温敏电阻上的电压)
根据电压换算出温度
如果温度高于预定值,则PB0(控制继电器的)输出高电平。否则就输出低电平。
这几些话写在了大括号里,它会被一遍一遍地不停执行。所以温度一旦超过设定值就会引起继电器吸合。直到温度低于预定值。
如果没有这个死循环。程序也会读一次电压,换算出温度,如果高于就吸合,低于就断开,然后程序一去不复返,你后面温度再怎么变它也不会理睬你了。所以必须制造一个死循环给它。
期待老师继续开讲,我想做一个自动加水机,用到2个4位数码管,一个显示调好的水量(预设值,单位为g),按 ...
不错,你这个可以作为一个完整的示例了。
我们就像这个来做一个思路培训,因为这东西,学的是一种思路,和修家电一样,首先,你要明白原理,第二,你要知道检查的方法。那就够了,余下的,可以随时上网搜,网上什么样的学习内容都有,关键是你要会提出问题。
就拿你这东西开讲吧。
首先,你要了解你用的材料。
除了单片机,这里用到了4位的数码管。
两个按键。
水流传感器。
所以你必须对它们了解一下
先说第一个器件,四位的数码管。四位的数码管(带小数点的)一般会有12条腿。4个是公共脚,一个位一个脚,另外8个,分别对应数码管的8个笔划。根据公共脚是作为正极还是负极,分为共阴和共阳两种。
现在有两个问题,一是怎么才能让数码管显示0-9中的某一个字?
这个,你只要用万用表测一下或者用3V的小电池去接一下数码管,你就能想到了:0-9是由7个笔划组成的,我只要控制这7个笔划的亮和灭,就能形成这10种数字。 这是第一个重点:你必须了解你要用的器件,有条件的话,买回来先试试。如果你连怎么使用数码管都不会,余下的事就别谈了。
第二个问题:怎么才能让数码管显示1234.你用电池或万用表试了,你就会发现,它们要显示就显示一样的内容,而根本做不到显示不同的内容,你让我显示还比较容易,但是要显示1234这种不同的,好像做不到。
要不接个4位的数码电压表,v表示kg,精确到小数点后2位数,用单片机的DA口,将脉冲计数转换为电压量,问题 ...
哈,你想得太多了。当然是可以实现的。我只是留了一个疑问给大家思考的,因为这是重点,所以我故意写了一半就不写了。
所以,学习单片机并不是学习这么一个器件,它的神奇之处在于,你怎么用那么}

我要回帖

更多关于 单片机特殊功能寄存器 的文章

更多推荐

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

点击添加站长微信