最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

PIC单片机入门

来源:动视网 责编:小OO 时间:2025-09-25 13:43:41
文档

PIC单片机入门

单片机入门不难------谈PIC系列话说人间事物的学习,不外两类:一类入门易,精通难比如矿石机,再比如练书法谁都会写两下,可写好却不是一朝一夕的事儿。另一类则入门难精通易,比如超外差收音机,学会需要各种放大、振荡、反馈、混频、中频、统调等等,但是一旦你学会,做出一个高质量的收音机,确也不是难事。单片机属于后者,所以无论如何,你得用些时间,学习一些新名词并理解,甚至还得花一些小钱。但是,一旦你掌握,其乐趣也像收音机一样,很有吸引力的。本故事说给一点也不懂计算机,甚至数字电路的引引道。一般入门应
推荐度:
导读单片机入门不难------谈PIC系列话说人间事物的学习,不外两类:一类入门易,精通难比如矿石机,再比如练书法谁都会写两下,可写好却不是一朝一夕的事儿。另一类则入门难精通易,比如超外差收音机,学会需要各种放大、振荡、反馈、混频、中频、统调等等,但是一旦你学会,做出一个高质量的收音机,确也不是难事。单片机属于后者,所以无论如何,你得用些时间,学习一些新名词并理解,甚至还得花一些小钱。但是,一旦你掌握,其乐趣也像收音机一样,很有吸引力的。本故事说给一点也不懂计算机,甚至数字电路的引引道。一般入门应
单片机入门不难------谈PIC系列

话说人间事物的学习,不外两类:一类入门易,精通难比如矿石机,再比如练书法谁都会写两下,可写好却不是一朝一夕的事儿。另一类则入门难精通易,比如超外差收音机,学会需要各种放大、振荡、反馈、混频、中频、统调等等,但是一旦你学会,做出一个高质量的收音机,确也不是难事。单片机属于后者,所以无论如何,你得用些时间,学习一些新名词并理解,甚至还得花一些小钱。但是,一旦你掌握,其乐趣也像收音机一样,很有吸引力的。本故事说给一点也不懂计算机,甚至数字电路的引引道。一般入门应该有保障。

改为:  本故事说给懂电工、电子、逻辑电路的老家伙和半老家伙,如果对电子一窍不通人讲那我劝你也别瞎子点灯了,要是边讲基础边讲pic这书就不知唱到何年何月啦。

    单片机不同于收音机,收音机的任务最终就是听好声音一个,单片机可以做很多事情,要你来安排它的工作。安排它就先的认识它,熟悉它

请看图1

 (13.22 KB) 

这个腿的小螃蟹就是我们的第一顿饭,只要把它吃下去,以后的大餐就好办了。

第1、腿接电源 +5V  和 地线。头两条腿是螃蟹钳子,好吃的很。 现在剩下了 6 条腿

第2、3条腿 使用时外接一个叫晶振的东西  我们接一个 4 MHz的。

第4条腿是复位脚,是一个信号输入脚。单片机正常运行时接高电平。当有一个低电平脉冲输入到这个脚时单片机就复位。所谓复位就是单片机内部所有的工作部件统统回到规定的状态,程序也复位到头一句上开始逐条运行。例如,你设计的一个报警锁定的 LED红灯亮后,当需要解除报警时,用一个按钮给这个脚瞬时接地一下,相当于给它一个负脉冲,系统就复位了,led灯就熄灭了,程序从头开始。

以上5个脚,几乎所有单片机都有,包括世界上最复杂的,和世界上比较简单的单片机-----PIC12CE519

轮到第5条腿了,这条叫单片机的 I/O 脚。就是输入输出脚。你可通过程序动态地控制它作为输入或输出,作为输出时可以程序控制它的输出电平为高1或低0。所以,他的工作状态有四种:输入0,输入1,输出0,输出1

剩下的两条腿和第5脚功能一个样。

pic单片机开发工具很灵活,想多花钱有专业的仿真器,编程器和配套软件。有南京伟福,北京革新,的也有。最好的是福建高奇。当然,原装美国微芯公司的也有,更贵了。

如果你想专攻PIC单片机,推荐福建高奇的PICMATE2004。

如果你是单片机各家全能,强烈推荐南京伟福V8,  它可以仿真51、96 、飞利浦、PIC  dsp 等将近30家的单片机和dsp 单片机8位、16位、32位通吃,总共大约支持几百种型号的

单片机包括dsp 芯片,各厂家软件全提供。

以上两款专业仿真器价钱差不多,将近4000元 

专业编程器如果你专攻PIC推荐picstar-plus, 有很多家做价钱近1000元。

业余条件下PIC单片机可以购买同系列 F 字样的flash型在线仿真调试,编程,价钱一到两百左右

凡带 c 字样的(包括 ce )都支持两种,即otp 和 EPROM

带测 CE  多一个 E 说明支持电可擦出EEPROM, 可以在用户程序运行时擦除写入,掉电不丢失。这对于用户很方便。例如,我用它来记录用户设定的告警上下限,和记录现场故障原因。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、

1、pic单片机销量世界第一  2、中低端单片机的性能价格比,PIC是最高的。这里我所说的中低端,包括pic17系列带乘法器的flash准dsp。

PIC12F508的指令系统和pic12ce519兼容, PIC中低端所有系列所有型号指令都兼容,当然一些硬件内部资源是有区别的,例如A/d转换,有8位,10位,12位的区别。所以尽管指令兼容,源程序的部分语句还是要小修一下。这是自然的事情。PIC12F508比519多一个8位的A/D转换。

现在貌似一般都讲F877是不是比508更先进?

产品定位和价钱不一样,试问如果你设计一个RS232同RS485的转换电路,你会选那一款作为自动处理收发协议的转换。

另外,我也推荐购买廉价的F877 ICD型开发工具,指令兼容,同样可以仿真出509 519的代码(有小差别),我拿519说事,一是简单老家伙们看了以后感兴趣,二是国内PIC12系列的中文资料几乎找不到。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

     上边我们已经把腿消化掉了,其实我们要弄明白的也就3只腿,再简单一些,先整明白两条腿,即GP0,GP1。这两条腿低级一点的用法,可以控制继电器,LED灯,高级一些的用法可以进行I2C总线,RS232总线的通信,作为扩展输入可以模拟出来A/D转换器(6--7bit),可以测量一个电阻的粗略值。作为输出也可以直接推动扬声器奏出音乐。这是后话暂且不提。

现在要控制使用这两只腿,我这个三脚猫功夫的说书的不得不讲一下软件了,要想讲明白软件又不得不涉及到单片机的内部结构。那位说啦,你可别提这软件和结构了,以前俺就是让它们打败的,现在听到这个心里就打鼓。嘿嘿,不要紧,果真如你所说,那你就不妨跟着我再失败一次, 反正吗多一次失败又不纳税,嘿嘿。不过你也要有思想准备,彻底弄明白是个渐进的过程。

       要说这程序和单片机内部结构,还真是老大难,不过蟹黄蟹肉都可都在里面。我现在要是给你说PIC单片机是哈佛结构的,51系列是冯-诺伊曼结构的,恐怕你要立马走人了。所以我得用点心思不让你溜号。

       好在PIC系列的制造商(microchip 微芯公司 美国)理解我等苦衷,全部只有35条指令,而且有一些指令我们一般很少使用,常用的也就十几句,用的时候查手册,无需记忆。就算我们两天学习一句,也就两三个月时间,总比到老了还怕它们强啊。废话少说先看下面的两个例语:

my_name006:      movlw  02h       '常数2进入W

 movwf  GPIO     'W 的数进入 寄存器GPIO

这就是我们编的程序里的两个句子,也叫源程序。有以下特点

每行只能写一句话

每句话由四部分组成:

标号:  操作指令   操作数        '程序注释

下面我结合例子把这四部分解释一下。

第一部分 my_name006: 叫做标号,它是由字母或数字组成,由冒号结束。标号可有可无,比如第二句就没有标号。

第二部分movlw 叫做操作指令。它是必须有的,不能省略。PIC 系列的单片机共有 35 条指令。

第三部分02h   叫做操作数。有的指令没有操作数或者操作数是默认的,也不用写。

第四部分是程序注释,必须以单引号开头,主要作用是提醒和备忘。注释也是可有可无。

第二个例句中,省略了标号,当然注释也可以省略。他的指令是movwf, 操作数是GPIO。操作数不一定是数字,也可能是一个由字母组成的字符串。

 知道了语句格式以后,我们下面就学习一些常用语句。我们先把这两个例句弄清楚。

这两句话的作用是把 2 这个常数写入到 GPIO 这个寄存器里。

      单片机里有一些部件需要我们使用和操作,都是通过读写寄存器来实现的。每个部件都对应有操控它的寄存器,例如我们要控制使用的管脚GP0,GP1 这两个管脚对应的寄存器就叫做GPIO。对GPIO寄存器读操作,实际等效察看管脚电平的高低;对GPIO寄存器相应的位写1操作,实际等校让管脚输出高电平。写0,输出低电平。

每个寄存器可以储存一个八位的二进制数。这八个位的每个位都有名称,从左向右的名称是:

                                            左端第首位名称叫D7,

                                            左端第二位名称叫D6,

                                            左端第三位名称叫D5,

                                            左端第四位名称叫D4,

                                            左端第五位名称叫D3,

                                            左端第六位名称叫D2,

                                            左端第七位名称叫D1,

                                                 最后一位叫D0,

而每一个位对应一个管脚的电平,例如当GPIO寄存器的D0位等于1时表示管脚GP0 的电平是高电平。D0位等于0时表示管脚GP0 的电平是低电平。常数2的八位二进制表示是“00000010”  所以,GPIO寄存器存放的8位2进制数的每个位的值以及管脚电平是:

                 D7对 应于内部总线管脚的电平      D7=0  内部总线管脚输出低电平             

                 D6对应于内部总线管脚的电平       D6=0  内部总线管脚输出低电平

                                D5对应于GP5 管脚的电平            D5=0   GP5 管脚输出低电平

                                D4对应于GP4 管脚的电平            D4=0   GP4 管脚输出低电平

                                D3对应于GP3 管脚的电平            D3=0   GP3 管脚输出低电平

                                D2对应于GP2 管脚的电平            D2=0   GP2 管脚输出低电平

                            D1对应于GP1 管脚的电平            D1=1   GP1 管脚输出低电平     

                                D0对应于GP0 管脚的电平            D0=0   GP0 管脚输出低电平

GP0---GP5管脚我们可以从上一讲的图1硬件中查出所对应的管脚。d7 d6 对应的内部时钟和数据总线我们现在暂且不要管它。以后本事大了在调教它们。在我们的例句中,向GPIO寄存器写入了2,常数2的八位二进制表示是“00000010”  因此如果此时GP0, Gp1等都已经被定义成输出的话,那么GP1输出高电平(接LED灯亮),GP0 输出低电平(所接led灯熄) 。

截止到现在,你已经学会如何控制管脚的电平高低了。尽管还有一些疑问,比如怎样定义管脚为输出脚(以后会说),我得说如果事先gp1,gp0这两个管脚处于输入状态,这两个例句无效,是控制不了电平的。

'------------------------------------------------------------------------------

再加深一下对寄存器的认识:

要把一个常数存储到,或者说写到一个寄存器中,仅用一条指令是办不到的,必须通过一个特殊的寄存器W,把数据倒过去. 这就应该使用到两个语句。

movlw   02H    指令的意思是把一个常数存入特殊寄存器W, 这个常数是2,后面的H是表示十六进制

movwf   GPIO   指令的意思是把特殊寄存器W的数值存入寄存器. 这个寄存器的名称是 GPIO

这里涉及到两个概念,常数和寄存器.

常数好说,比如说十进制数 35,  26 但要注意,在单片机系统里我们一般不用十进制,而使用十六进制. 寄存器也叫单片机的内存。

一个寄存器可以存储的数值范围是0--255,用十六进制表示就是 0---FFH.用二进制表示就是00000000----11111111.

以后要养成习惯用十六进制表示数. 

那么,一个单片机里有多少个这样的寄存器哩,pic12ce512里面有1024个这样的寄存器可以供你使用,为了使用方便生产商已经给它们编上了号码,第一号码是000H,往下依照次序为 001H,002H........3FFH.(

有了编号就像我们居住的房间有了房间号码,使用就方便的多了.房间号码在邮政行业叫地址,因此我们称这些号码叫做寄存器地址,或称地址数  例如 名称为 GPIO 的寄存器,他的地址,或地址数是  06H 。所以我们的两个例句完全等同于:

my_name006:           movlw  02h      '常数2进入w

                            movwf  06H      'W 的数进入 寄存器GPIO

'-----------------------------------------

有两个寄存器比较特殊,它们没有地址,一个名字叫做 W,  另一个叫做 TRIS. 所以他们两个在存储数据的时候比较快,一个指令就可以解决问题,例如:    movlw   03H    一条指令就把常数3写入到W寄存器了。关于TRIS寄存器,我们以后用到它再说.

除了他们两个以外的其他所有寄存器,在写入数据时一般都要用两条指令进行。

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

我们上一次讲的两个指令是如何控制管脚电平的高低。前提是所有管脚已经被定义成输出了(OUT)如果被定义成了输入,则上次的指令虽然也能运行,但运行后丝毫不能改变管脚电平的高低,因为此时管脚是输入状态,电平取决于外部输入,指令无法改变。

在PIC单片机系列中,改变I/O口的输入输出依靠写入寄存器TRIS的值,相应位写0,表示对应管脚被定义成了输出,写1,就是输入。

现在假如预把GP1、GP2管脚定义成输出,其他脚全是输入。那就应该向TRIS 寄存器写入二进制数 11111001,换算成十六进制就是F9H.   

依照以前我们学到的知识,在PIC系列单片机里,本来应该用下列的语句来完成我们的设定:

        movlw     0F9H      '常数进W  以字母开头的常数前面必须加0

       movwf    TRISA      '把W内的数复制到TRIS

实际上PIC系列的单片机也都是这么写的,后面加的A,表示第一个8位的口(有的单片机不仅一个口,还有好几个8位的I/O口如TRISB  TRISC  TRISD等等) .

但是,记住了,       PIC12系列的单片机必须改写成为:

        

        movlw    0F9H      '常数进W  以字母开头的常数前面必须加0

        tris         GPIO      '把W内的数复制到TRIS      以后凡见到这个指令一律理解成 movwf     TRISA

写法不同,意思是一样的.  这样你就又学了一个指令TRIS,不过这个指令的实质还是你曾经学过的movwf 只是写法不同罢了.

在PIC12系列里TRIS作为指令, 在其他系列(PIC16\\17\\18)里把  TRIS  作为普通寄存器看待. 

因为我们现在讲的就是PIC12CE519,所以我们暂时用  tris   GPIO这个格式,等以后进入PIC16C877 我们再写成 movwf    TRISA , 至于理解按照后者进行.

'-----------

如果我们要控制GP1  GP2管脚的输出电平, 其他管脚作为输入.并且让GP1输出低电平,GP2输出高电平.完整的程序如下:

    movlw    0F9H      '常数进W  

           tris     GPIO      '把W内的数复制到TRIS ,GP1  GP2为输出,其他为输入

                    '此行无命令,起到的作用是容易读懂程序

    movlw    04H       '常数4的二进制是 00000100 ,GP1=0  GP2=1

            movwf    GPIO      'W内的数进GPIO 输出生效,原来定义成输入的脚的电平,不会受该句影响

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

上面已经学会了三条指令,但是8位寄存器的概念一定要建立起来,程序通过给寄存器写入不同的数据控制管脚作为输入使用还是输出使用,作为输出时是输出高电平还是低电平。

这样的操作有一个特点,就是每次写入数据,同时控制的往往不是一个管脚,而是好几个个.最多一次可以控制8个管脚.在单片机里往往每8个脚叫做一个口,如口A,  口B,用英文表示就是GPIO PORTA  PORTB  PORTC 等。更多的情况是:某个口内的某一个管脚需要改变电平,其他脚电平不变.例如我们仅需要GPIO口上的GP1这个管脚的电平拉高,其他管脚电平不发生变化.这时候位操作指令为我们提供了方便,假如我们事先已经把GP1管脚定义过输出了(方法见前面讲过的):

   bcf     GPIO,GP1      '注释  GPIO口上GP1管脚电平拉低,我们行话叫    清除。

   bSf     GPIO,GP1      '注释  GPIO口上GP1管脚电平拉高,我们行话叫    置位。

怎么样,这样控制某一个管脚的电平就方便多了,你的编程效率大大提高啊.

记住:PIC所有单片机所有寄存器都是可以位操作的,这在51的单片机上是不能完全实现的.不仅如此,PIC所有单片机所有管脚的单腿驱动输出电流可以高达 25mA,所以如果你驱动一个 5到10mA电流的LED发光二极管,根本不用加三极管,串个电阻直接挂在单片机上就得了,这在51的单片机上也是不能实现的,要加驱动三极管或驱动芯片.

      单片机的大部分指令,或者说单片机所做的大部分工作,多数在写入或读出寄存器。关于寄存器的初步概念我想我们已经建立起来了,它是一个能够存储8位二进制数据(最大255 =  0FFH) 的单元 每个单元都有它的编号,我们把它叫做地址,或地址编码. 地址编码也是十六进制的,  另外寄存器里的数据掉电就会丢失。

寄存器的英文是RAM  也要记住. 

PIC12CE519 里面共有有48个寄存器供我们操作使用,  它们每一个都有固定的地址编码。

地址编码并不是连续的号码,而是分成了两段: 

第一段:  从00H 开始, 依次是01H, 02H, 03H ....0AH, 0BH......到1FH 结束.  计32个寄存器

第二段:  从30H 开始, 依次是31H, 32H, ......................到3FH 结束   计16个寄存器

这种地址不连续编号, 而是要跳过去一段的做法, 对于我们新手来说很是不习惯. 为了让我们容易入门, 我们暂时先不管第二段RAM, 只当它不存在, 所有程序我们只涉及到第一段连续的RAM 地址. 等我们熟练的掌握好了RAM的使用,再去看第二段地址的RAM, 那时,你就会理解单片机设计者把它们分成两段的苦心了.

为了规范,我们今后一律把RAM的分段叫做分页. 第一地址段叫00页面, 第二地址段叫01页面. 例如: 我们学过的 I/O 口电平控制寄存器 GPIO, 它的地址编码是 06H, 属于00页面.

所有这32+16=48个寄存器除了在地址上分成了两个页面以外,又把它们分成两类:

一类专用寄存器,一类通用寄存器.所谓专用,就是这个寄存器的功能已经由系统分配好了.例如 地址为06H 名称叫做GPIO寄存器的功能,是它的每个位,都对应到一个I/O脚的电平.

另一类 是通用寄存器,你可以理解成它的功能系统没有事先预定,而是由你在编程序的时候随机使用.

pic12ce519 的专用寄存器有 7 个, 位置在第00叶面的最前面. 这7个专用寄存器的地址编码是: 00H,01H, 02H, ----06 H,剩下的所有寄存器包括所有第01页面, 全部都是通用寄存器.

例子: 在两个通用寄存器 09H, 0AH 内, 写入常数 FCH

    movlw     0FCH    '常数进W 

    movwf     9H      '复制W内的数到通用寄存器09H 

    movwf     0AH     '复制W内的数到通用寄存器0AH  由于此时W内并没有改变,W不用再进常数.

下面是PIC12CE519的 寄存器RAM的地址地图:

                                        

02.JPG (26.97 KB)

2007-7-27 10:28

最上端的  00   01  表示的是页面号码,或叫页面地址。

左侧 从00  --- 1FH 是00页面, 右侧是01页面。

从00H 到 06H 都已经起好了名称 ,它们是专用寄存器,用处各有不同。以后我们会逐个介绍它们.剩下的都是通用寄存器 或者叫普通寄存器 General Purpose Registers  意思是一般用途的寄存器 .地址从20H 到 2FH  也不是“空洞”,也不是不能访问,只是读写它们的时候等于读写它们左侧对应的00页面。这一点我们可能有些迷惑,弄不明白也没有关系,以后随着程序理解的深入,会搞清楚的。

内存图谱,不要求记下来,但是应该有个大体印象,用的时候会察看就可以了。等编程时间一长就那么几个字节,自然就记住了。

所谓字节是衡量二进制数据长度的一个单位。一个寄存器刚好能记住一个字节的数据。如果你要存储的数据比较大超过了255,那就要占2个存储器甚至更多。描述的时候通常我们不说这个数值占了多少个寄存器,而是说这个数据是几个字节的。

………………………………………………………………………………….

下面我们学习一条新指令,叫做空操作指令

      nop     '什么事情也不做,但执行这个指令也要消耗掉一点时间。它没有操作数。

                '不要理解成程序停了,实际上程序仍在正常运行。执行一连串的空操作指令,  

                '单片机白耗费时间,什么活也不干,往往用于延时

如果你需要一个很短时间的延时,可以采用一连串的空操作。注意每个 nop 也是占一行, 例如:

movlw    0F9H      '常数进W  

      tris     GPIO      '把W内的数复制到TRIS ,GP1  GP2为输出,其他为输入

      bsf     GPIO,GP1  '管脚GP1输出高电平点亮LED灯(如果你已经接上灯的话)

      nop

nop

     nop

     nop

     nop

      ... .

            bcf      GPIO,GP1  '管脚GP1输出低电平关闭LED灯

            nop

          nop

          nop

          nop

              ...         

    运行的效果是接在管脚GP1上的LED灯先亮一段时间,再熄灭一段时间的闪烁。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

这回再说一个程序转向的语句,goto    指令,学过basic  和  c  等语言的对它不陌生。

单片机对程序的执行是逐句自上而下进行。当它运行到某个位置,如果你不希望继续运行它下面的语句,而是希望它无条件的强行转到某一句上,就可以使用goto语句。

我们还是通过例子来说明goto 的使用方法。

已知外部晶振的频率为4 MHz, 设计程序从pic12ce512 单片机的GP1管脚上输出一个方波信号,信号频率固定并计算出频率的值。

                   movlw    0F9H             '常数进W  

                   tris         GPIO             '把W内的数复制到TRIS ,GP1  GP2为输出,其他为输入

myWAVE:    bsf          GPIO,GP1       '管脚GP1输出高电平点亮LED灯(如果你已经接上灯的话)

                   nop

                   nop

                   nop

                   nop

                   nop

                   nop

                   nop

                   bcf      GPIO,GP1         '管脚GP1输出低电平关闭LED灯

                   nop

                   nop

                   nop

                   nop

                   nop

                  goto   myWAVE        'myWAVE是标号,此行必须有这个标号,否则程序通不过 

                  nop                            '由于goto的存在,以下语句得不到运行

                  nop

                  nop

当程序自上而下运行到goto 语句时, 不再继续运行它下面的语句, 而是让程序强行转向到标号为myWAVE的语句上,并继续运行.   这样一来的结果,程序会永远在标号位myWAVE的这一句 bsf      GPIO,GP1  到goto之间循环,  打转转.

客观运行的结果是 GP1管脚电平不停地一会高,一会低, 就输出了方波信号.

要计算方波的频率,我们必须知道单片机每运行一条指令需要多少时间.这个时间的单位不以通常的秒 毫秒 或微秒作为单位, 而是以”机器周期” 为单位.  以后凡是我们讨论单片机内部的时间问题都要以机器周期作为时间单位.  至于一个机器周期究竟是多少微妙或毫秒, 取决于单片机的品牌和振荡频率大小, 等一会我们再用公式计算我们PIC12CE512在4MHz震荡频率下的机器周期是多少个微妙。

我们先看看此程序中GP1脚的高电平低电平都是用了多少个机器周期.

PIC单片机所有指令都是单机器周期的指令,

例外的情况是goto 语句要用2个机器周期  还有一个call指令用的时间也不完全是一个机器周期(待后续)      其他品牌的某些单片机可不是这样,一条指令往往要用几个周期……

从bsf 到bcf有8个指令,都是单周期指令,所以GP1高电平时间长度是8个机器周期

从bcf 到bsf有7条指令,其中6条是单周期指令  1条双周期指令(goto). 所以GP1低电平时间长度也是8个机器周期

这样,我们输出方波的周期长度就是16 个机器周期.

Pic品牌的机器周期 = 4/振荡频率          (公式)

所以,在我们的例子当中         1个机器周期=4/4MHz= 1 uS

也就是说,我们的例子中,执行一条指令仅需要1微秒的时间.

这样,我们输出的方波周期就是16微秒, 频率是    f  =1/16   =0.0625 兆赫     =62.5 KHz

如果这个方波的频率比较低,你再接一个扬声器到GP1脚上你就可以听到声音了,频率降低到几赫兹的时候, 接一个led灯, 就会不停的闪烁.

当然, 频率太低你用的nop指令的数目会很多,程序虽简单但是臃肿, 这没有关系,我们主要是在学习程序, 弄清楚道理是目的。

要想使得程序不臃肿我们有的是办法,这就必须再学习新的指令.

如果此前我讲的你基本都弄明白了,那你现在已经抓住单片机入门的门把手了, 还需轻轻的推开.

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

也许你从没有留意你按下的节目频道、音量等这些 标有 + / - 符号的键盘是怎样工作控制大小的。  

下面我们学习两个新指令 incf  和  decf  ,它们都是对某一个寄存器进行增1 或减1  操作,例句中假如我们要操作的寄存器是 09H

    movlw    02H   '常数2进入W 

    movwf    09H   '把w 内的数2 复制到09H 这个寄存器 

                            '现在09H 寄存器内存储的数是2

   incf         09H     '寄存器09H内存储的数 增加1  

                            '现在09H内存储的数变成3

   decf       09H     '寄存器09H内存储的数 减掉1

                             '现在09H内存储的数变成2

   movlw    0FFH     '常数255进入W 

   movwf    09H       '把w 内的数255 复制到09H 这个寄存器 

                              '现在09H 寄存器内存储的数是255

   incf     09H          '寄存器09H内存储的数 增加1  

                              '现在09H内存储的数变成0

   decf     09H            '寄存器09H内存储的数 减掉1

                                '现在09H内存储的数又变成255

    如果你事先定义好了地址为09H 的这个寄存器里存储的数字大小,代表电视机节目频道的话,你会很喜欢这两个指令的。并且当节目频道到达最大值255  或最小值0的时候无需担心,寄存器在0时减1 会得255, 255状态下增1 会得0

至于为什么会这样,学过环形计数器的人不会感到奇怪的。你要是没有学过计数器电路也不要紧,记住一个寄存器的最大存储数值是255  = 0FFH   就可以了,加减法都会导致它“进位”

当然控制音量时这个程序不能使用,因为它在0和255之间变化,音量忽大忽小怎们行。

为解决这个问题, 我们必须再学习两条指令    incfsz 和 decfsz

它们与上两个功能基本相同,不同的是: 寄存器增1 或减1操作以后,该指令会自动判定寄存器内的结果是否为零,如果不为零,继续正常执行该指令后面的语句.   但如果结果为零的话,则程序会 "跳一步" .绕过紧挨着它下面的一条指令,继续执行更下面的语句,举例子说明

假定我们操作的寄存器还是09H: 

   

   movlw    0FDH   '常数253进入W 

   movwf    09H   '把w 内的数253 复制到09H 这个寄存器 

                           '现在09H 寄存器内存储的数是253

   incfsz    09H   '寄存器09H内存储的数 增加1,结果变成254   结果不等于0,故程序继续                        执行下一指令

   nop                 '该句得到执行(因为上一句寄存器09H的计算结果不等于0)  

   incf      09H      '寄存器09H内存储的数 增加1,结果是255

   incfsz    09H     '寄存器09H内存储的数 增加1,结果变成0  

                           '因为结果等于0,故程序要跳过下面的一句(不运行下面的一句).

   incf      09H      '由于上一句的存在并结果为0,该句得不到执行,被忽略

   incf      09H      '程序跳入这一句继续运行 寄存器09H内存储的数 增加1

   nop                  '因此现在 09H寄存器存储的数是1

   nop                  '继续运行.

思考题:设计一段程序代码,当用户连续按下音量减小键后,判定音量寄存器09H的存储音量数值,

防止该寄存器的值从0 变成255,以免震惊到用户。

SMALL_SOUND:  nop      '标号可以任意写的,此前用户一旦按下音量减,就把程

                                                                                ' 序引导到这一句上来

                   decfsz    09H   '寄存器09H内存储的数 减1,如果结果为0 就跳一步  

                   goto      OK    '如果上一句结果不为0,执行该句后,程序去了ok语句 

                   movlw     01H   '跳到这一步说明寄存器结果是0

                   movwf     09    '强行把 09H内的数值写成1,仍然是小音量,这样音量不会被 因为 减小而变成255

OK:             nop     '继续运行   

思考题:利用decfsz 指令设计一段延时代码,使得延时时间可以在10个机器周期到65535个机器周期之间,

可以通过程序任意控制  

在这个例子中,设我们要控制的延时时间大约是24086个机器周期,用16进制表示就是 5E16 H.

如果用到通用寄存器,请使用 0AH, 0BH

yanshi:   movlw              5EH             ' 常数5E进W 标号是延时

              movwf              0BH    ,        '0B寄存器数为5EH

              movlw              16H              '常数16进W

              movwf              0AH              '0A寄存器数为16H

jixu:         decfsz             0AH             '0A寄存器内的数减1,如果结果为0跳 步                

               goto                jixu              '结果不为0,继续 

        

               decfsz             0BH            '0B寄存器内的数减1,如果结果为0跳步                

               goto                jixu               '结果不为0,继续  

        

                nop             '延时完毕

下面介绍单片机汇编语言里的一个概念      “子程序”

下面我介绍 “子程序”

我先打个比方,如果你做一顿饭,要做汤,炒菜,炖鱼,汆丸子, 奥,忘了还有炒小螃蟹(大螃蟹现在都叫人吃的逮不着了:))期间有一个动作在我看来不断的重复,这个动作就是放盐  放盐的过程描述是这样的:

放盐:  用一把小勺子深入盐罐

        舀出氯化钠适量 。

        把小勺子里的氯化钠 均匀洒在锅里。

        完毕

如果我们把做饭定义为主任务 那么放盐这个动作就叫做  子任务。

这样定义的一个好处就是描述主任务的时候比较方便,当你用语言文字描述主任务的时候,无论哪一道菜,到了该加盐的时候不必细说用一把小勺子深入盐罐...... 因为很多菜都有同样的这个过程,所以,你用 “放盐” 两个字就可以了。但是在你使用 放盐 这个词之前或者之后,你应该解释一下放盐 这个词的具体过程是什么。

我们单片机的程序也是一样的,如果你设计一个电视机的自动搜索频道的程序,程序要求电视机每搜索成功一个频道,它面板上的发光二极管就眨一次眼睛,也就说,先熄灭一段时间然后再点亮。这样就会遇到很多这样的眨眼动作,为了简化主程序我们可以把眨眼这样一个过程定义为一段子程序,以后每次遇到需要眨眼的时候就调用一次子程序就可以了。

子程序的定义是这样的

Zhayan:     bcf        GPIO,GP1        '管脚GP1输出低电平关闭LED灯   做为子程序标号是必须有的 标号

                                              ' 就是子程序的名字

            nop

            nop

            nop

            nop

            nop

            ... .

            

            bsf      GPIO,GP1  '管脚GP1输出高电平点亮LED灯

              nop

            nop

            nop

            nop

              ...         

    return           '这个命令表示子程序的结束 是必需的 否则这个子程序没有结束

这样,子程序就定义完了 如果想在程序的某个位置需要led灯熄灭以下(眨眼一次),只需在那个程序位置调用一下子程序就可以了。

调用的方法是用 call 命令。

主程序:

     ....               '这些点点表示主程序里的语句

     ....

     ......

     ......              '这个位置搜所成功一个台 需要“眨眼”一次

     call  Zhayan         

     ......              '继续搜索下一个台的命令行

      ......

     ......

     ......

     ......              '这个位置搜所成功一个台 需要“眨眼”一次

     call  Zhayan

     ......              '继续搜索下一个台的命令行

      ......

     ......

     ......              '这个位置搜所成功一个台 需要“眨眼”一次

     call  Zhayan         

     ......              '继续搜索下一个台的命令行

      ......

疑问1  我在一个主程序里固然可以调用另一个子程序,而我在一个子程序里能不能调用另一个子程序?

答  可以的,这叫子程序嵌套,甚至还可以在另一个子程序中再继续调用别的子程序。

疑问2  嗯,那继续往下调用下去,有么?

答  有,这叫允许嵌套的层数 每个品牌 型号的单片机允许的嵌套层数都是有规定的 例如pic16f74 允许8层

   pic12e519 允许两层  也就是说pic12e519的主程序里可以调用子程序,子程序里还可以再调用子程序,到此为止不要再往下调用了,否则程序报错或者超出你预计的结果。

疑问3  在同一层程序空间里,例如在我的某个子程序之中,调用另一个子程序的次数有么?

        回答 没有,只要你的程序寄存器装得下你的程序。

疑问4  我听说单片机在调用子程序以前,好像需要程序“堆栈”访问什么的,要进行一些程序计数器的保存保护,以保证子程序返回来得时候,程序能够正确回到原来位置和环境。是这样的么?

答 pic单片机不用管这些问题,它是硬件自动完成这些堆栈的事情,我们的指令里不用关心这些。尽管如此,中档pic单片机的例如 pic16等系列,它们的程序存储器地址是分页的,尽量调用本页的子程序,如果子程序不在本页,而是在另一个页面里存放,你还是要告诉单片机你的子程序所在的页面数据的,具体操作指令可以查相关指令说明。我们的pic12c519的程序存储器,没有分页,不用关心这事。

先回答问题:

1、你的怀疑是对的,置数24086 (5E16H), 和得到的实际延时确实不相等,所以我的原文用“大约”,不过也大的太多了。但是你的计算方法好像也不正确,感觉不会差那么多。

作为实际的精确时间,可以通过仿真器进行仿真测试出来。写上述思考题的时候,我还在热带雨林里工作,没有带仿真器和参考书,是我完全靠记忆,别说内容了,基本指令我现在还得检查一下再说。如果非要计算,也不是不可以,主要是goto  跳步语句比较难办作为实际,一般先给出一个大概置数,在通过仿真器调整到你需要的精确延时(可以精确到几个机器周期)

2、非常正确。这个思考题的例子里  高8位寄存器0B的值,最小为1  不能是0

3、道理和要求同上。

所以,我在题目里把最小时间定为 10个机器周期左右,而不是0。

因为这个例子最小时间是置数 0101H,  运行也就大约10个机器周期(10uS,  if  4MHz)左右

单片机的中断,概念并不难以理解。只是要真正理解运用编程处理一些实际中断的例子,却也不是很容易,甚至是单片机学习、入门的拦路虎。要想学会实际的中断处理编程,也还需要清楚一些程序存储器,程序结构,程序计数器,硬件堆栈,现场保护等这些个另杂碎概念。

因此,我们在学习中断以前,以后和学习中断过程中,都有必要介绍回顾复习一些有关上述关键词的概念和知识,否则,尽管你学了中断,用起来可还是不能得心应手,以至于茫然。

我还是用比喻的方法介绍一下中断的概念:

你的主程序任务是做一桌可口的饭菜,期间可能要多次调用子程序“撒盐”。

尽管子程序下边还有更小的子任务,比如“计算食盐的量”等过程,尽管这些子过程很复杂,但他们的出场时间和顺序是可以预料的,是可以预先安排的。也就说你肯定知道在什么时候放盐。

有一类子程序,他的出场时间是不确定的,突然的,处理他们的时间刻不容缓,必须赶紧的。我们称这一类子程序为中断子程序,也就是我们所说的中断.你正在做菜的过程中,隔壁邻居小孩突然敲门说 他的二大爷在他房间里摔倒了 请你帮忙把二大爷扶起来。这是急迫的,必须处理的事务。你肯定关掉炉子一溜烟跑出去帮忙,等回来以后再点着炉子继续做菜。这个事件的特点就是发生的时间你无法预先知道,而这个任务必须得停下当前工作去处理,并且是刻不容缓。

     从开始关炉子到回来点着炉子的这段时间里以及你的救人行为,就叫做  “中断子程序”。  在中断子程序过程中,你关炉子的动作,叫做“中断现场保护”  点着炉子叫做“中断现场恢复”中间走出去扶起隔壁二大爷到回来 叫做“中断任务处理”,小孩子敲门就叫做“中断请求”,这就是中断的基本概念。在单片机里,中断的例子也是很多的。我举一个你手里的手机的例子,你的GSM手机正工作在赋闲,屏幕上也就显示个时间日期中国电信什么的,表面看没有什么。其实它内部的CPU高速运行忙碌地工作在诸如联络无线网络,查询是否有短消息发来,计算当前信号强度,时间等任务中。你突然按下数字键“8”,此时内部CPU必须停下它正在干的工作来应付你,也就是清屏,显示你按下的数字8,然后再回到它原来的任务接着运行。(当然,这个例子不一恰当,现在有操作系统Windows-ce windows-mobile的手机的工作机制远没有如此的简单)

下面我们要接触和复习一些另杂碎,学习中断必须要弄明白单片机这些另杂碎,所以你还得忍耐他们一阵子。

PIC单片机快速入门 《电子制作》2008年11月 站长原创,如需引用请注明出处

    笔者曾经在2004年—2008年写下51单片机综合学习系统系列教程文章数十篇,很多读者朋友通过学习之后已经顺利地跨入了51单片机的大门,受到了广大读者朋友的好评,也让笔者感觉非常高兴,在学完了51单片机之后,笔者将为大家介绍一系列PIC单片机基础知道与入门学习教程,为此特地写下“PIC单片机快速入门”一文,配合文中所讲的单片机学习、开发设备,提供给学习者一个理论与实践相结合的平台,使广大单片机初学者朋友能够以最快的速度跨入PIC单片机的大门,文中讲述一些单片机常用的开发设备,我们应该如何去使用、操作它们。

    首先,我们先来看一看,在下面的学习过程中将要用到的硬件设备有哪些,它们分别是:PIC编程器,ICD2仿真烧写器和增强型PIC实验板,实物如图所示,你只需要有一台电脑就可以进行学习和开发了。三板在手,可谓是资源足矣,学习起来够你用的了。至于一些难度较高的应用我们在此先不作介绍,说多了,反而会使问题复杂化。

图1

    PIC编程器:如图1所示,用来将我们在PC机上编好的程序烧写至单片机芯片中去,以完成程序的固化工作,通过我们也称其叫“烧写器”,讲的是同一个东西,我们要使用的PIC编程器支持市面常见的芯片型号,如PIC16F877A,PIC16F876,PIC16F54,PIC12C508,PIC12F508,PIC16C65,PIC18F452,PIC18F6720等百余种PIC单片机芯片,相对于市场上出售的编程器,其价格已经非常低廉了。

图2

    ICD2仿真烧写器:如图2所示,用来提高我们的软件开发效率,实现芯片的在线仿真,一听到仿真器大家都会想到一个贵字,但我们提供的仿真器相信大部分朋友都可以承受,所以推荐给大家。我们在MPLAB IDE编程软件中设置好要仿真的芯片型号即可。

图3

    增强型PIC实验板(与PIC编程器、ICD2仿真烧写器配合使用):如图3所示,方便我们完成各种单片机实验,如流水灯,数码管显示,继电器控制,发声实验,IIC总线通信等等,应该说足够学习使用的了。

    我们准备好了学习PIC单片机的硬件设备后还需要准备好哪些软件平台呢?我们完成软件开发又需要完成哪些步骤呢?

    我们需要安装的软件主要有两个,分别是“MPLAB 集成开发环境”和“PIC编程器烧写软件”。

    MPLAB 集成开发环境(IDE)是一个综合性的设计平台界面,适用于使用Microchip PICmicro 和dsPIC 单片机进行嵌入式设计的应用开发。我们在这个软件界面中编写程序代码,并通过它将写好的源程序代码编译成目标代码,即HEX文件,同时配合硬件调试器、开发板完成软件程序的调试工作,最终通过编程器将定型的目标代码写入到开发板的单片机芯片中去。

    首先,在配套光盘中找到MPLAB IDE安装文件,该文件也可以从Microchip网站下载,双击Install.exe文件根据向导安装完成即可。注意:此时MPLAB IDE软件只支持使用汇编语言进行编程,我们准备使用C语言来进行程序编缉,所以,还需要为MPLAB IDE软件安装一下C编译器插件,其具体安装方法由于文章篇幅有限,详见光盘内说明文件。

    其次,将光盘“PIC编程器驱动软件”目录复制到计算机硬盘上,这是我们一会要使用的烧写软件,用来将我们编好的程序烧入PIC单片机芯片内。现在,我们将PIC编程器插上USB线与电脑连接,系统提示发现新硬件,要求用户指定驱动程序所在路径,我们将其指定到配套光盘“USB驱动程序”目录,点击确定按钮后,系统完成了编程器USB驱动程序的安装。安装好后你的电脑会增加一个串口,如图4所示,这时编程器硬件就连接在这个USB转成的串口上。

图4

    “MPLAB 集成开发环境”和“PIC编程器烧写软件”都安装完成后,我们就可以进行程序编写和烧录工作了,以下我们将与这些单片机开发设备相结合来讲述具体的实践学习过程。

    我们的第一个实验是要用PIC单片机点亮实验板上的其中一只LED发光管。想用单片机来完成一些智能化的控制,这个是最简单的一个程序例子,以给大家一个感性的认识。在此,出于通俗易懂的角度出发,我们使用PIC编程器与增强型PIC实验板配合来完成本次实验,力求用最简洁的代码,最方便的操作方式,让大家了解到底该如何让单片机工作。本次实验,我们使用的芯片为PIC16F877A,它涵盖了PIC16F***子系列的所有功能,特别适合初学者使用,它在PIC家族中的地位类似51家族中的S51或者S52,不过内部包含了更多的功能,比如内部集成了AD等特殊单元。

图5

    图5是跟增强型PIC实验板上跟LED控制相关部分的电路,我们可以看到LED上串接的电阻是470欧姆,如果此时LED上的电压是2.0V,那么此时通过LED的电流则为(5V-2V)/470Ω=6.38mA,如果需要提高亮度,一般会电流控制在10mA左右,则此时电阻应该选择(5V-2V)/10mA=300Ω,所以可以就近选择330Ω。

    电路已经确定,然后就是连接到单片机的I/O口上,见图5,我们可以看到LED的正极通过限流电阻连接到PIC单片机的I/O口,负极连接到了GND地线,因此要使LED发光,也就是使电流流过LED,只需要把I/O口置成高电平即可,所以最终我们对LED的控制变成了对一个I/O口的控制,比如要点亮标号为“D11”的LED,就是把RC1口设置成高电平而已,这就是实现方法。

    下面就开始写程序了,打开MPLAB IDE软件,选择File(文件)>New(新建),出现一个文本编辑窗口,在该窗口中输入以下C语言源程序:

#include

main()

{

TRISC=0X00; /*TRISC寄存器被赋值,PORTC每一位都为输出*/

while(1) /*循环执行点亮发光二极管的语句*/

{

PORTC=0X02; /*向PORTC送数据,点亮第二个LED发光管*/ 

}

}

    这是一个最简单的PIC点LED的C程序代码,也希望能给初学者朋友们一个感性的认识,我已把能省略的语句尽量都省去了,能把每句话都看懂了,PIC的C程序最小框架你也就明白了。

    第一行 #include 用于加载标准库函数,如51单片机中的 reg51.h 库文件一样。

    main()是C语言中的主函数,一个C程序代码中,也只有一个main()主函数,程序就是从这里开始执行的。

    语句“TRISC=0X00;”用来设置RC口的输入、输出状态。

    while(1) 是死循环语句,即周而复始地执行{ }内的语句体,如我们现在的程序中的作用即是不停地执行 PORTC=0X02; 这条语句。

    语句“ PORTC=0X02;”的功能则是给RC口赋值,即第二个引脚RC1为高电平,用“1”来表示。

    说明:PIC系列单片机各类数据存储器都是以寄存器方式工作和寻址的。专用寄存器包括了定时寄存器TMRO、选择寄存器OPTION(又称为项选寄存器)、程序计数器PCL、状态寄存器STATUS、间接寻址寄存器INDF和FSR、端口I/O寄存器(如PORTA、PORTB…)和相对应的端口I/O控制寄存器(又称为端口I/O数据方向寄存器,如TRIAS、TRISB…)、保持寄存器PCLATH和中断控制寄存器INTCON等。我们现在暂时只用到了TRISC和PORTC口寄存器。

    先创建文件夹D:\\FirstPro,然后将上面输入的源程序保存到该文件夹,注意文件名为led.c。文件保存完成后,我们可以发现源程序编辑窗口中的程序字体颜色改变了,这些颜色能帮助我们更好地阅读源程序,快速发现输入错误的命令。文件保存后,我们需要进行项目的创建,项目将文件组织起来以便进行编译,我们选择菜单Project(项目)>new(新建),出现New Project(新项目)对话框,在对话框中,我们将项目命名为MyPro,使用Browse 按钮,将项目放在刚才创建的FirstPro文件夹中。单击OK按钮,在MPLAB IDE 界面中我们会看到已创建项目的的项目窗口,如果项目窗口未打开,请选择菜单View->Project。现在,我们需要将刚才创建好的源程序文件追加到项目中去,在此,源文件是必须添加的。其他文件,如头文件、库文件、链接描述文件,视项目的具体情况来确定是否追加。我们现在只需要将源文件led.c追加即可,在屏幕左面的项目窗口中找到Source Files节点,点击鼠标右键,在弹出菜单中选择Add Files,双击要添加的文件led.c 即可。

    项目和源程序创建完成后,我们需要给项目设置好目标芯片型号和配置位。

    选择菜单Configure>Select Device ,在Select Device 对话框中,点device栏右边的下拉箭头,选择器件为PIC16F877A,注意后面带有字母“A”。(提醒:PIC16F877A和PIC16F877是两个内部结构和功能不同的芯片,两个芯片不能直接替换)。设置完成后,点击“OK”即可,如图6所示。

图6

    设置配置位,选择菜单Configure->ConfigurationBits。通过点击 “Settings”栏中的文本,可以更改这些配置位,我们将其做如图7所示配置。

图7

    接下来,我们要为源程序做一项编译工作,即产生目标文件,等会我们要把该文件烧入到我们的PIC16F877A单片机芯片中去。选择菜单中Project->Build All项,或者按快捷键Ctrl+F10就可以完成编译工作了,这时,你会在led.c文件所在目录下发现一个名为“led.hex”的文件,这就是我们所用来完成烧写芯片工作时使用到的目标程序文件,该文件为16进制文件。

    咱们继续讲,我们现在已经完成了软件程序的编制工作,下面我们就来讲一讲,咱们的最后一道工序,即程序定形后,我们如何将其烧到我们的单片机芯片中去。

    打开PIC编程器烧写软件,软件运行前,应该先连接好编程器硬件,即插入USB线。退出运行时先关闭软件,再拔出 USB 线。首先,在第一次使用前需要进行端口配置。通过“我的电脑-->硬件-->设备管理器”查看使用了哪个端口,然后在软件菜单中选择“文件”-->“选择端口”,输入端口号,如COM3,选择好以后,这时屏幕的中下方其中一栏显示连接的串口好以及软包装执行状态。

    然后在软件窗口右下角选择芯片型号为“16F877A”,点击“载入”按钮,选择刚才我们已经生成等待烧写的led.hex文件,按软件窗口右边的芯片插放图片,在锁紧座上插好目标器件。点击窗口下方“编程”按钮,开始编程,烧写完成后,弹出下面的窗口表示烧写成功,否则会弹出相应的错误提示。OK,大功告成。至此,我们已经完成了从软件编写,直到烧写芯片的全部步骤。一定很辛苦了吧:)下面就让我们来看看我们的成果吧,把刚才烧写好的PIC16F877A芯片插在增强型PIC实验板上,并接上外接电源,来看看板上的一个LED发光管是不是亮了。结果如图8所示,板上的一个LED发光管点亮,现在我们已经脱离了我们的仿真器而使用的是单片机芯片。

图8

    笔者写到这里,整个实验、开发步骤已经全部完成,虽然这是一个很简单的实验,但很大复杂的例子都是基于各种简单的原理之上。所有的实验方法、步骤完全一样,只是程序代码变了。

    最后,笔者写下此文,希望能够帮助广大单片机初学者可以尽快入门,给大家一个感性的认识,最重要的是能够提供给大家一个实验的硬件环境以及软硬件相结合的实践性描述,以使增加单片机初学者的实践动手能力。我们提供的试验板上资源非常丰富,可以做流水灯、数码管、蜂鸣器、键盘、继电器控制、IIC总线通信等实验,光盘上也都配有例程、实验中的一些视频操作录像及编程器、仿真器的全部驱动程序,以供大家方便学习,实验中的一些视频录像请见光盘“实验录像”下的视频文件。因此,你只要有一台电脑就可以进行学习、开发了,相信只要你发挥你的想象,一定可以将单片机发挥出它更大的潜力。

 1、PIC单片机振荡电路中如何选择晶体?

   对于一个高可靠性的系统设计,晶体的选择非常重要,尤其设计带有睡眠唤醒(往往用低电压以求低功耗)的系统。这是因为低供电电压使提供给晶体的激励功率减少,造成晶体起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因时上电时电路有足够的扰动,很容易建立振荡。在睡眠唤醒时,电路的扰动要比上电时小得多,起振变得很不容易。在振荡回路中,晶体既不能过激励(容易振到高次谐波上)也不能欠激励(不容易起振)。晶体的选择至少必须考虑:谐振频点,负载电容,激励功率,温度特性,长期稳定性。

  2、如何判断电路中晶振是否被过分驱动? 

   电阻RS常用来防止晶振被过分驱动。过分驱动晶振会渐渐损耗减少晶振的接触电镀,这将引起频率的上升。可用一台示波器检测OSC输出脚,如果检测一非常清晰的正弦波,且正弦波的上限值和下限值都符合时钟输入需要,则晶振未被过分驱动;相反,如果正弦波形的波峰,波谷两端被削平,而使波形成为方形,则晶振被过分驱动。这时就需要用电阻RS来防止晶振被过分驱动。判断电阻RS值大小的最简单的方法就是串联一个5k或10k的微调电阻,从0开始慢慢调高,一直到正弦波不再被削平为止。通过此办法就可以找到最接近的电阻RS值。

  3、晶振电路中如何选择电容C1,C2?

  (1):因为每一种晶振都有各自的特性,所以最好按制造厂商所提供的数值选择外部元器件。

  (2):在许可范围内,C1,C2值越低越好。C值偏大虽有利于振荡器的稳定,但将会增加起振时间。

  (3):应使C2值大于C1值,这样可使上电时,加快晶振起振。

  4、PIC系列单片机I/O脚有什么特点?

  PIC系列单片机的任意一条I/O管脚都有很强的带负载能力(至少可提供或灌入25mA的电流)。因此,在某些场合,这些管脚可作为可控的电源。举个例子,在一些低功耗的设计中,希望一些周围的器件在系统待命时不耗电或尽量少耗电,此时,可考虑这些器件的电源供电由一条I/O脚负责提供,在工作时,MCU在该条管脚上输出高电平(接近VDD),带几个mA的负载绝对不成问题;若要进入低功耗模式,MCU就在该管脚输出低电平(接近0),被控器件没有了电源,也就不会耗电。比如LCD显示电路,信号调制电路等都非常适合此类控制。 

  5、为何系统在外界磁场和电场的干扰时,不能正常工作?

   如果在主控电路中没有滤波电路,您用的芯片在/MCLR端应接一个能保证滤去该端口上的窄脉冲电路。因/MCLR上加的低电平宽度应大于2US,系统才能复位,而小于2US的低电平将会干扰系统的正常工作。 

  6、使用带A/D的PIC芯片时,怎样才能提高A/D转换的精度?

  (1):保证您的系统的时钟应是适合的。如果您关闭/打开A/D模块,应等待一段时间,该段时间是采样时间;如果您改变输入通道,同样也需等待这段时间,和最后的TAD(TAD为完成每位A/D转换所需的时间)。TAD可以在ADCON0中(ADCS1、ADCS0)中选择,它应在2US-6US之间。如果TAD太小,在转换过程结束时,没有完全被转换;如果TAD太长,在全部转换结束之前,采样电容上的电压已经下降。对该时间的选择的具体细节请参照有关的数据手册或应用公式。

  (2):通常模拟信号的输入端的电阻太高(大于10Kohms)会使采样电流下降从而影响转换精度。若输入信号不能很快的改变,建议在输入通道口用0。1UF的电容;它将改变模拟通道的采样电压;由于电流的补给,内在的保持电容为51.2PF。

  (3):若没有把所有的A/D通道用完,最好少用AN0端。因它的下一个脚与OSC1紧靠在一起,会对A/D对转换造成影响。

  (4):最后,在系统中,若芯片的频率较低,A/D转换的时钟首选的是芯片的振荡。这将在很大范围内降低数字转换噪音的影响。同时,在系统中,在A/D转换开始后,进入SLEEP状态,必须选择片内的RC振荡作为A/D转换的时钟信号。该方法将提高转换的精度。 

  7、PIC16C7XX的A/D片内RC振荡器能否用于计数器?

   16C71A/D转换器片内RC振荡器的作用是让MCU处于睡眠时(此时主振停振)能有一个时钟源来进行A/D转换。此RC振荡器因其内部设计的不能被其他电路使用。 A/D转换器内部RC振荡器钟频典型值为250K,但会随着环境温度,工作电压,产品批号等不同而有相当的变动。 定时器的时钟源可以选择内部的振荡频率,也可以是外部的脉冲输入信号。若你能选择后者,那就能方便地做到MCU的主频很高而时钟的溢出率较低。不然,除了用软件来计数分频,好象也没有其它招数。 另一种选择是用其它型号的MCU,其内部至少还另有一个TIMER1,因为TIMER1可以有的一颗晶体作为时钟振荡的基准,你可以方便地选用频率低的晶体来完成你的设计。

  8、为什么PIC单片机应用中,有时出现上电工作正常,而进入睡眠后唤醒不了?

  对于一个高可靠性的系统设计,晶体的选择非常重要。在振荡回路中,晶体既不能过激励(容易振到高次谐波上),也不能欠激励(不容易起振)。尤其在设计带有睡眠唤醒(往往用低电压以求低功耗)的系统中,若还是随手拿一颗晶体就用,你的系统可能会出问题。这是因为低供电电压使提供给晶体的激励功率减少,造成晶体起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因时上电时电路有足够的扰动,很容易建立振荡。在睡眠唤醒时,电路的扰动要比上电时小得多得多,起振变得很不容易。评价振荡电路是否工作在最佳点的简单方法时用示波器看OSC2脚上的波形(必须考虑示波器接入电容!)最好的情形是看到非常干净漂亮的正弦波,没有任何波形畸变,而且要满幅(接近VCC和GND)晶体的选择至少必须考虑:谐振频点,负载

电容,激励功率,温度特性,长期稳定性。 

  9、PIC单片机应用中晶体选择的注意事项。

   对于一个高可靠性的系统设计,晶体的选择非常重要。在振荡回路中,晶体既不能过激励(容易振到高次谐波上)也不能欠激励(不容易起振)。尤其在设计带有睡眠唤醒(往往用低电压以求低功耗)的系统中,若还是随手拿一颗晶体就用,你的系统可能会出问题。这是因为低供电电压使提供给晶体的激励功率减少,造成晶体起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因时上电时电路有足够的扰动,很容易建立振荡。在睡眠唤醒时,电路的扰动要比上电时小得多得多,起振变得很不容易。 有人评价:PIC单片机对晶体的要求怎么这么高,用51好象从来就没有这么麻烦,手里抓到什么就用什么,也不见有问题呀?且慢,这样比较前提并不一样,同样在睡眠时,有谁见过51系列不用复位而仅靠内部或外部事件唤醒吗?若你并不需要这么高级的设计技术,PIC也大可以让你逮到什么晶体就用什么。 评价振荡电路是否工作在最佳点的简单方法时用示波器看OSC2脚上的波形(必须考虑示波器接入电容!)最好的情形是看到非常干净漂亮的正弦波,没有任何波形畸变,而且要满幅(接近VCC和GND) 晶体的选择至少必须考虑:谐振频点,负载电容,激励功率,温度特性,长期稳定性。 

  10、为何使用PICSTAR-PLUS烧写16CE625-04/P有时无法把保密位烧成"保密"?

   使用PICSTAR-PLUS对芯片编程时,程序代码是放在计算机的RAM中,每次写程序时通过串口把数据下载到烧写器中去编程,所以可能会出错。我不怀疑你操作有问题,但是请注意的PICSTAR-PLUS是用于开发用途的编程器,不推荐用于规模生产。你能计算出出错概率为1%,看来你是用它来作大规模生产了。为保证烧写可靠,推荐你使用高奇公司生产的PICKIT编程器。 

  11、PIC单片机型号中,后缀A/B/C分别代表什么?

   PIC单片机型号中,后缀A/B/C表示的是芯片生产的工艺不同。从A到C是工艺不断更新,硅片圆盘(Wafer)的直径变大,线宽变窄,线距变密,在同一个圆盘上可以制作出更多的芯片,从而降低了生产成本。 从功能角度来看,三者是一样的。当然,新版本的芯片中会把现有版本中存在的一些问题作些修正,功能会得到扩充。 从性能指标上来讲,三者有些差距。一个明显的表现是在电源电压的承受范围。制作线宽越细,所能承受的电压越低。例如,PIC16C57的最高电源电压指标为6V,而57C的指标为5.5V。 绝大多数情况下新版的片子可直接替换旧版。从目前发现的问题来看,主要出在晶体振荡电路部分。原因是新版芯片振荡电路内部的反向放大器的增益要比旧的高出许多。若晶体选择的不合理,可能会振荡到高次谐波上去。有些客户也提出新版的片子抗干扰的性能不比旧版的片子。其实,我们公布的技术指标在这方面并没有任何牺牲,只是工艺上的原因,我们留的余量减少了。请大家注意不要认为PIC的片子抗干扰能力强,在电路设计时就一点不考虑应有的抗干扰措施。 

  12、PIC单片机型号的温度级如何识别?

  以16C54-04X / P为例:

  X =没有,商业级,温度范围是0-70℃;

  X= I, 工业级,-40-85℃;

  X = E, 汽车级,-40-125℃;

  例如:PIC16C54C-04/P 商业级 PIC16C54C-04I/P 工业级 PIC16C54C-04E/P 汽车级

  13、PIC单片机的各种中断有没有优先级之分?

   中档PIC单片机的中断入口只有一个,硬件不分优先级,但可用软件查询的方式决定其优先级高低:先查先做,优先级为高。高档的17和18系列,包括即将推出的16位dsPIC,中断有硬件优先级。 

  14、为什么PIC单片机应用中,有时出现上电工作正常,而进入睡眠后唤醒不了?

   对于一个高可靠性的系统设计,晶体的选择非常重要。在振荡回路中,晶体既不能过激励(容易振到高次谐波上),也不能欠激励(不容易起振)。尤其在设计带有睡眠唤醒(往往用低电压以求低功耗)的系统中,若还是随手拿一颗晶体就用,你的系统可能会出问题。这是因为低供电电压使提供给晶体的激励功率减少,造成晶体起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因时上电时电路有足够的扰动,很容易建立振荡。在睡眠唤醒时,电路的扰动要比上电时小得多得多,起振变得很不容易。

  评价振荡电路是否工作在最佳点的简单方法时用示波器看OSC2脚上的波形(必须考虑示波器接入电容!)最好的情形是看到非常干净漂亮的正弦波,没有任何波形畸变,而且要满幅(接近VCC和GND)晶体的选择至少必须考虑:谐振频点,负载电容,激励功率,温度特性,长期稳定性

文档

PIC单片机入门

单片机入门不难------谈PIC系列话说人间事物的学习,不外两类:一类入门易,精通难比如矿石机,再比如练书法谁都会写两下,可写好却不是一朝一夕的事儿。另一类则入门难精通易,比如超外差收音机,学会需要各种放大、振荡、反馈、混频、中频、统调等等,但是一旦你学会,做出一个高质量的收音机,确也不是难事。单片机属于后者,所以无论如何,你得用些时间,学习一些新名词并理解,甚至还得花一些小钱。但是,一旦你掌握,其乐趣也像收音机一样,很有吸引力的。本故事说给一点也不懂计算机,甚至数字电路的引引道。一般入门应
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top