矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
楼主: 崂山

单片机入门不难------谈PIC系列

  [复制链接]
     
发表于 2007-7-29 03:16:35 | 显示全部楼层
关注中·!再继续
     
 楼主| 发表于 2007-7-29 11:41:00 | 显示全部楼层
继续
由于本人一向散漫,随写随发的感觉不错,等到以后再整理不迟。发现错误不能编辑时在下一贴里纠正

这回再说一个程序转向的语句,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指令的数目会很多,程序虽简单但是臃肿, 这没有关系,我们主要是在学习程序, 弄清楚道理是目的。
要想使得程序不臃肿我们有的是办法,这就必须再学习新的指令.



如果此前我讲的你基本都弄明白了,那你现在已经抓住单片机入门的门把手了, 还需轻轻的推开.
发表于 2007-8-4 13:13:18 | 显示全部楼层
真好!俺还要细嚼烂咽。谢谢!
发表于 2007-8-14 13:26:35 | 显示全部楼层
赞,一口气,从头到尾读完了,通俗易懂,清楚明了;天天在关注中,期待高抬贵手更新。谢
     
发表于 2007-8-19 21:00:08 | 显示全部楼层
一气看完,效果比我原来看书管用,入点儿门,谢谢,接着来吧。
发表于 2007-8-23 14:38:46 | 显示全部楼层
还没出新的哦,我的系统坏了没备份收藏夹,好不容易再次找到这里,请崂山抽空发点新的上来。
发表于 2007-8-25 12:29:45 | 显示全部楼层
晕,不更新了????????????????????????
发表于 2007-8-27 15:50:56 | 显示全部楼层
很精彩!学习了,谢谢崂山前辈!
     
 楼主| 发表于 2007-9-15 04:48:50 | 显示全部楼层
对不起各位,崂山入林一个多月,是在南美的热带雨林之中完成任务。没有网络,没有手机信号。有的是蚊子,大蜥蜴(个头像 猫),蚂蚁(个头一个多厘米),食蚁兽以及多的叫不出名字的鸟类。

今天领导特别批准,首次回到当地的省城休息,也只有两天时间就必须回到雨林里。所以现在根本没有心思白话。或许明天可以。
     
发表于 2007-9-15 08:23:16 | 显示全部楼层
崂山前辈,等着您继续写下去,我学了以后才好开工写PIC控制的旋转LED电子钟的程序.
发表于 2007-9-15 10:15:07 | 显示全部楼层

感想

自《聊斋》的崂山道士以来,这里的崂山是给俺印象最深的了。
崂兄是老师?其实优秀教师里也没几个能做到这样的。
想起了盖莫夫的《从一到无穷大》,他把深奥的现代科学写得比小说还趣味至深,那本书俺曾爱不释手。
     
发表于 2007-9-15 23:31:30 | 显示全部楼层
崂山兄去那里做什么去了?是不是架电台去了?
     
 楼主| 发表于 2007-9-17 10:36:47 | 显示全部楼层
当你坐在家里吃着月饼,惬意地用电视遥控器选择电视频道,不停地用 +/- 键盘调节电视音量到合适的时候,你可曾想过,此时崂山也许正钻在在温度高达35摄氏度以上的树丛里,忍耐蚊子蚂蚁的叮咬,研究用什么样的通信线更好地防止雨水侵蚀和动物的啃咬。

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

下面我们学习两个新指令 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             '延时完毕
         .
        .
        .
        .     
         
你现在可以只用这几个简单句子完成任意时间的延时程序了。

[ 本帖最后由 崂山 于 2007-9-17 10:46 编辑 ]
     
 楼主| 发表于 2007-9-17 10:59:54 | 显示全部楼层
明天崂山入林修道,估计一个月内上不了网。
所以您要是吃透了上面的意思,一个月后再来我的道场也误不了事。祝兄弟们开心。
     
发表于 2007-9-17 20:45:17 | 显示全部楼层
崂山前辈, Bolivia 我去过, 祝您工作愉快!
您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-28 22:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表