PIC单片机

一种单片机所能识别的全部指令集合,就称为该单片机的指令系统或指令集。单片机时钟振荡器电路产生的时钟信号,经内部4分频后形成一个不重叠的方波信号Q1~Q4,叫作4个节拍,由4个节拍构成一个指令周期Tcyc,一个指令周期内部包含4个时钟周期Tosc。前一个指令周期内完成取值操作,在后一个指令周期内完成指令的译码和执行。当Q1节拍的上升沿出现时,程序计数器PC增1,指令码是在Q4节拍取出并放入指令寄存器的。指令码的译码和执行贯穿下一个指令周期的Q1~Q4节拍。由于单片机在执行一条指令的同时,就可以提取下一条指令,从而实现流水作业,这样,每一条指令的运行时间平均为一个指令周期,因此习惯上说单片机采用的是单周期指令。严格地说,大多数指令的运行时间都是一个指令周期,但是少数引起程序执行顺序发生跳转的指令则是两个周期。

1. PIC的性能特点:

通常,每一条指令都用指意性很强的英文单词或缩写来代表,将代表一条指令的一个字符串称为“助记符”。PIC16F627共有35条指令,均是长度为14位的单字节指令,按其操作对象的不同可分为3类,即面向字节操作类(17条)、面向位操作类(4条)以及常数操作和控制操作类(14条)。

指令代码符号:

W

代表工作寄存器(即累加器)

f

代表7位寄存器单元地址,最多可区分128个单元

b

表示某一bit在一个寄存器内部8bit数据中的位置(即伴地址),由3位组成

k

代表8bit数据常数,或者代表11位地址常数

d

代表目标寄存器:d=0,目标寄存器为W;d=1,目标寄存器为f

表示运算结果送入目标寄存器

代表逻辑“与”运算符

代表逻辑“或”运算符

代表逻辑“异或”运算符

3类指令代码格式如下:

1)面向字节操作类指令代码分配格式:

13~8

7

6~0

操作码

d

f(寄存器地址)

2)面向位操作类指令代码分配格式:

13~10

9~7

6~0

操作码

b

F(寄存器地址)

3)常数操作和控制操作类指令代码分配格式:又分3种情况。

⑴携带8bit常数的指令代码分配格式:

13~8

7~0

操作码

k(数据)

⑵携带13比特常数的CALL和GOTO指令代码分配格式:

13~11

10~0

操作码

k(程序地址)

⑶不携带常数的指令代码分配格式:(如NOP)

13~0

操作码

2. 面向字节操作类指令:

寄存器加法指令:ADDWF f,d
操作:W+f→d,影响状态位:C、DC、Z
说明:将寄存器f和工作寄存器W的内容相加,d=1结果存入寄存器f中,d=0存入W
示例:ADDWF REG1,0
指令执行前 W=0x17 REG1=0xC2
指令执行后 W=0xD9 REG1=0xC2
状态位 Z=0 C=0 DC=0
寄存器逻辑与指令:ANDWF f,d
操作:W∧f→d,影响状态位:Z
说明:将寄存器f和工作寄存器W的内容相与,d=1结果存入寄存器f中,d=0存入W
示例:ANDWF REG1,1
指令执行前 W=0x17 REG1=0xC2
指令执行后 W=0xD9 REG1=0x02
寄存器清零指令:CLRF f,d
操作:0→W,影响状态位:Z
说明:将寄存器清零。d=0,f和W同时清零;d=1,仅f被清零
示例:CLRF REG1
指令执行前 REG1=0x5A
指令执行后 REG1=0x00
状态位 Z=1
工作寄存器W清零指令:CLRW
操作:0→W,影响状态位:Z
说明:将W寄存器清零,状态位被置1。
示例:CLRW
指令执行前 W=0x5A
指令执行后 W=0x00
状态位 Z=1
寄存器取反指令:COMF f,d
操作:~f→W,影响状态位:Z
说明:将寄存器f的内容取反。d=1,结果存入寄存器f中;d=0,存入工作寄存器W中
示例:COMF REG1,0
指令执行前 REG1=0x13
指令执行后 REG1=0x13 W=0xEC
寄存器减1指令:DECF f,d
操作:f-1→d,影响状态位:Z
说明:将寄存器f的内容减1。d=1,结果存入寄存器f中;d=0,存入工作寄存器W中
示例:DECF CNT,1
指令执行前 CNT=0x01 Z=0
指令执行后 CNT=0x00 Z=1
递减跳转指令:DECFSZ f,d
操作:f-1→d,结果为0则跳转,不影响状态位,产生跳转时指令周期为2
说明:将寄存器f的内容减1存入d。结果为0则跳过下一条指令执行,否则顺序执行下一条指令(单周期)。
示例:HERE DECFSZ REG1,1
GOTO LOOP
NUM ......
指令执行前 PC=地址 HERE
指令执行后 REG1=REG1-1
如果REG1=0,PC=地址NUM
如果REG1≠0,PC=地址HERE+1
寄存器加1指令:INCF f,d
操作:f+1→d,影响状态位:Z
说明:将寄存器f的内容加1。d=1,结果存入寄存器f中;d=0,存入工作寄存器W中
示例:INCF REG1,1
指令执行前 REG1=0xFF Z=0
指令执行后 REG1=0x00 Z=1
递增跳转指令:INCFSZ f,d
操作:f+1→d,结果为0则跳转,不影响状态位,产生跳转时指令周期为2
说明:将寄存器f的内容加1存入d。结果为0则跳过下一条指令执行,否则顺序执行下一条指令(单周期)。
示例:HERE INCFSZ REG1,1
GOTO LOOP
NUM ......
指令执行前 PC=地址 HERE
指令执行后 REG1=REG1+1
如果REG1=0,PC=地址NUM
如果REG1≠0,PC=地址HERE+1
寄存器逻辑或指令:IORWF f,d
操作:W∨f→d,影响状态位:Z
说明:将寄存器f和工作寄存器W的内容做逻辑或运算,d=1结果存入寄存器f中,d=0存入工作寄存器W中
示例:IORWF REG1,0
指令执行前 REG1=0x91 W=0x13
指令执行后 REG1=0x93 W=0x13 Z=0
寄存器逻辑异或指令:XORWF f,d
操作:W⊕f→d,影响状态位:Z
说明:将寄存器f和工作寄存器W的内容相异或,d=1结果存入寄存器f中,d=0存入工作寄存器W中
示例:XORWF REG1,1
指令执行前 REG1=0xAF W=0xB5
指令执行后 REG1=0x1A W=0xB5
F寄存器传送指令:MOVF f,d
操作:f→d,影响状态位:Z
说明:将寄存器f内容送至工作寄存器W(d=0)或自己本身(d=1),如果是传给自己,一般是用来影响状态位Z,以判断寄存器f是否为0
示例:MOVF REG1,0
指令执行后 W=REG1寄存器中的值 Z=1
W寄存器传送指令:MOVWF f
操作:W→f,不影响状态位
说明:将工作寄存器W的内容送到寄存器f中。
示例:MOVWF REG1
指令执行前 REG1=0xFF W=0x4F
指令执行后 REG1=0x4F W=0x4F
空操作指令:NOP
操作:无任何操作
说明:不产生任何结果,只使PC+1。
寄存器带进位位循环左移指令:RLF f,d
操作:f(n)→d(n+1),f(7)→C,C→d(0),影响状态位:C
说明:将寄存器f接位循环左移,结果存入d。f最高位(bit7)移入状态位C(进位位),进位位C移入d(0)中。
示例:RLF REG1,0
指令执行前 REG1=1110 0110 C=0
指令执行后 REG1=1110 0110 W=1100 1100 C=1
寄存器带进位位循环右移指令:RRF f,d
操作:f(n)→d(n-1),f(0)→C,C→d(7),影响状态位:C
说明:将寄存器f接位循环右移,结果存入d。f最低位(bit0)移入状态位C(进位位),进位位C移入d(7)中。
示例:RRF REG1,0
指令执行前 REG1=1110 0110 C=0
指令执行后 REG1=1110 0110 W=0111 0011 C=0
寄存器减法指令:SUBWF f,d
操作:f-W→d,影响状态位:C、DC、Z
说明:将寄存器f的内容减去工作寄存器W的内容,d=1结果存入寄存器f中,d=0存入工作寄存器W中。(该指令是将工作寄存器W的内容求补后与寄存器f的内容相加)
示例:SUBWF REG1,1
指令执行前 REG1=3 W=2 C=?
指令执行后 REG1=1 W=2
状态位 C=1; 结果为正 Z=0 DC=0
示例:
指令执行前 REG1=2 W=2 C=?
指令执行后 REG1=0 W=2
状态位 C=1; 结果为零 Z=1 DC=1
示例:
指令执行前 REG1=1 W=2 C=?
指令执行后 REG1=0xFF W=2
状态位 C=0; 结果为负 Z=0 DC=0
(f>W:C=0,Z=0; f=W:C=1,Z=1; f 寄存器半字节交换指令:SWAPF f,d
操作:f(0-3)→d(4-7),f(4-7)→d(0-3),不影响状态位
说明:将寄存器f内容的高4位和低4位相交换,d=1结果存入寄存器f中,d=0存入工作寄存器W中。
示例:SWAPF REG1,0
指令执行前 REG1=0xA5
指令执行后 REG1=0xA5 W=0x5A

3. 面向位操作类的指令:

位清零指令:BCF f,b
操作:0→f(b),不影响状态位
说明:将寄存器f的第b位清零
示例:BCF REG1,7
指令执行前 REG1=0xC7
指令执行后 REG1=0x47
位清零指令:BSF f,b
操作:1→f(b),不影响状态位
说明:将寄存器f的第b位置1
示例:BSF REG1,7
指令执行前 REG1=0x0A
指令执行后 REG1=0x8A
位测试为零跳转指令:BTFSC f,b
操作:如果f(b)=0则跳,不影响状态位
说明:测试寄存器f的第b位,如果为0,则跳过下一条指令;如果不为零,则逐条执行
示例:HERE BTFSC REG,1
FALSE GOTO LOOP
TRUE ......
指令执行前 PC=地址 HERE
指令执行后 如果REG<1>=0,PC=地址TRUE(指令周期为2)
如果REG<1>=1,PC=地址 FALSE(指令周期为1)
位测试为1跳转指令:BTFSS f,b
操作:如果f(b)=1则跳,不影响状态位
说明:测试寄存器f的第b位,如果为1,则跳过下一条指令;如果不为零,则逐条执行
示例:HERE BTFSS REG,1
FALSE GOTO LOOP
TRUE ......
指令执行前 PC=地址 HERE
指令执行后 如果REG<1>=0,PC=地址FALSE(指令周期为1)
如果REG<1>=1,PC=地址 TRUE(指令周期为2)

4. 面向常数操作和控制操作类指令:

常数加法指令:ADDLW K
操作:W+K→W,影响状态位:C、DC、Z
说明:将立即数K和工作寄存器W的内容相加,结果存入工作寄存器W中
示例:ADDLW 0x15
指令执行前 W=0x10
指令执行后 W=0x25
常数逻辑与指令:ANDLW K
操作:W∧K→W,影响状态位:Z
说明:将立即数K和工作寄存器W的内容相与,结果存入工作寄存器W中
示例:ANDLW 0x5F
指令执行前 W=0xA3
指令执行后 W=0x03
常数逻辑与指令:ANDLW K
操作:W∧K→W,影响状态位:Z
说明:将立即数K和工作寄存器W的内容相与,结果存入工作寄存器W中
示例:ANDLW 0x5F
指令执行前 W=0xA3
指令执行后 W=0x03
子程序调用指令:CALL K
操作:PC+1→堆栈顶,K→PC(10:0),PCLATCH(4:3)→PC(12:11),不影响状态位
说明:调用子程序。返回地址(PC+1)被压入堆栈,11位立即数地址被装入PC(10:0),PC的高位从PCLATCH装入,指令周期为2。
示例:HERE CALL THERE
指令执行前 PC=地址 HERE
指令执行后 PC=地址 THERE 堆栈=地址 HERE+1
看门狗定时器清零指令:CLRWDT
操作:0→WDT,0→预分频器
说明:复位看门狗,还将复位WDT的预分频器。状态位TO和PD被置1。
示例:CLRWDT
指令执行前 WDT计数器=?
指令执行后 WDT计数器=0x00 WDT预分频器=0 TO=0 PD=1
无条件跳转指令:GOTO K
操作:K→PC(10:0),PCLATCH(4:3)→PC(12:11),不影响状态位
说明:常数K(地址)置入PC低11位,PC高位装入PCLATCH(4:3),如果程序存储器大于2K,且目标程序位于不同的页面,那么在执行GOTO指令前,PCLATCH必须装入子程序的页号。指令周期为2。
示例:GOTO THERE
指令执行后 PC=地址 THERE
常数逻辑或指令:IORLW K
操作:W∨K→W,影响状态位:Z
说明:将立即数K和工作寄存器W的内容做逻辑或操作,结果存入工作寄存器W中
示例:IORLW 0x35
指令执行前 W=0x9A
指令执行后 W=0xBF Z=0
常数传送指令:MOVLW K
操作:K→W,不影响状态位
说明:将立即数K送入工作寄存器W中
示例:MOVLW 0x5A
指令执行后 W=0x5A
中断返回指令:RETFIE
操作:堆栈顶→PC,不影响状态位
说明:从中断返回,并将位于栈顶的返回地址写入PC。指令周期2。
示例:RETFIE
中断后 PC=堆栈顶TOS GIE=1
子程序带值返回指令:RETLW K
操作:K→W,堆栈顶→PC,不影响状态位
说明:将立即数K送到工作寄存器W中,并将位于栈顶的返回地址写入PC,适合查表。指令周期2。
示例: CALL TABLE
......
TABLE ADDWF PC
RETLW K1 ;带K1值返回
RETLW K2
......
RETLW Kn ;带Kn值返回
指令执行前 W=0x07
指令执行后 W=K8的值
子程序返回指令:RETURN
操作:堆栈顶→PC,不影响状态位
说明:从子程序返回。执行出栈操作,将位于栈顶的单元内容装入PC。指令周期2。
示例:RETURN
中断后 PC=堆栈顶TOS
睡眠指令:SLEEP
操作:0→PD1→TD,0→WDT,0→WDT的预分频器(PSA=1时)。影响状态位:PD TD
说明:停止OSC1进入低功耗模式。各端口引脚没有输出。
常数减法指令:SUBLW K
操作:K-W→W,影响状态位:C、DC、Z
说明:用立即数K减去工作寄存器W的内容,结果存入工作寄存器W中。(该指令是将工作寄存器W的内容求补后与立即数K相加)
示例:SUBLW 0x02
指令执行前 W=1 C=?
指令执行后 W=1
状态位 C=1; 结果为正 Z=0
示例:
指令执行前 W=2 C=?
指令执行后 W=0
状态位 C=1; 结果为零 Z=1
示例:
指令执行前 W=3 C=?
指令执行后 W=0xFF
状态位 C=0; 结果为负 Z=0
(K>W:C=1,Z=0; K=W:C=1,Z=1; K 常数逻辑与指令:XORLW K
操作:W⊕K→W,影响状态位:Z
说明:立即数K和工作寄存器W的内容做逻辑异或,结果存入工作寄存器W中
示例:XORLW 0xAF
指令执行前 W=0xB5
指令执行后 W=0x1A
还有2条指令,但为了保持与将来型号的向上兼容性,建议不要使用,这是为了与旧型号PIC16C5X产品代码兼容。
OPTION寄存器装入指令:OPTION
操作:(W)→OPTION,不影响状态位
说明:将工作寄存器W的内容装入到OPTION寄存器。OPTION是可读写的寄存器,用户可对其直接寻址,例如用MOVWF指令。
TRIS寄存器装入指令:TRIS f
操作:(W)→TRIS寄存器f,不影响状态位
说明:将工作寄存器W的内容装入到TRIS寄存器。TRIS是可读写的寄存器,用户可对其直接寻址。

5. 寻址方式:

指令是由操作码和操作数组成的,操作数是指令的一个重要组成部分,用于指定参与运算的数据或者数据所在的单元地址。所谓寻址方式,就是寻找操作数的方法,就是获取操作数所在地址的方法。PIC16F62X的指令系统中,根据操作数的来源不同,设计了4种寻址方式。

1)立即寻址:指令码中携带着实际操作数(立即数)。
示例:ADDLW 16H ;将立即数16H与W内容相加,结果送W
2)直接寻址:指令码中有寄存器单元的地址
示例:IORWF 26H,0 ;将地址26H的RAM单元的内容与W内容相或,结果送W
3)间接寻址:对映射寄存器INDF的操作
示例:XORWF INDF,1 ;将FSR内容所指向地址的内容与W内容相异或
对INDF的操作就是对间接寻址寄存器FSR所表示的地址所指向的单元的内容进行操作。
4)位寻址:对任意寄存器中的任一比特位直接寻址访问
示例:BSF 05H,4 ;把地址为05H的寄存器单元内的第b4位设置为1。

6. 汇编语言:

所谓汇编语言,就是用助记符来表示二进制代码。单片机仅仅能够识别二进制形式的机器语言程序(机器码程序),但如果直接用机器语言来设计程序,编写起来很繁琐且容易出错,也给程序的阅读、修改、调试等环节带来极大的困难。所以,在开发单片机程序时通常都使用汇编语言。
汇编语言是对机器语言的改进,采用便于人们记忆的一些符号来表示操作码、操作数和地址码等。汇编语言的语句通常与机器语言指令一一对应。单片机并不能识别汇编语言,需要用编译软件将汇编语言编写的程序翻译成机器语言程序,被称为“目标程序”,然后烧写进单片机。
汇编语言的语句格式:
标号: 操作码(指令助记符) 操作数 ; 注释
汇编语言源程序既可以用大写字母书写,也可以用小写字母书写,还可以大小写混用,一个语句行最多允许有225个半角字符。
标号:就是该条指令的符号地址,是在编译时被赋以该指令在程序寄存器中所存放的具体地址。只有那些将被其他语句引用的语句才需要加标号,标号可以单独作为一行。标号最多由32个字母、数字和其他一些字符组成,第一个字符必须是字母或下划线,必须从一行的第一列开始写,后面用空格、制表符或换行符与操作码隔开。标号不能用指令助记符、寄存器代号或其他在系统中已有固定用途的字符串。一个标号在程序中只能定义一次。
操作码:操作码可以是指令系统中的助记符,也可以是用于控制汇编器的伪指令。操作码前面至少保留一个空格,以便于标号区别。
操作数:操作数是操作对象,也就是数据或者地址,可以用常数或符号两种形式表示。常数,可以是二进制、八进制、十进制、十六进制或者字符;符号,可以是在此之前经过定义(或者赋值)的代表数据或地址的标号、字符串。如果操作数有两个,中间要用逗号分开。
注释:注释可有可无,但最好附带注释,便于阅读、交流、修改和调试程序。注释用半角分号与指令部分分开,编译器对该部分不作任何处理。
MPASM的默认进制是十六进制,十六进制数由数字0~9和字母A~F组成。当在程序中采用后缀H表示一个以A~F开头的十六进制数时,则必须在它前面增添一个0作为先导,以便编译器将其与符号名相区分。二进制数要以B为后缀,八进制以Q或O为后缀,十进制数则以D为后缀。字符,要用单引号括住,字符代表的常数就是该字符的ASCII码。

7.伪指令:

所谓伪指令,并不是单片机的真实指令,没有对应的机器码,仅在编译过程中起作用。伪指令,是程序设计人员向编译器发出的控制指令,告诉编译器如何完成汇编过程和一些规定的操作,以及控制编译器的输入、输出和数据定位等。MPASM可以使用的伪指令有十多条。
EQU:符号名赋值伪指令。格式:符号名 EQU xxH
即给符号名赋予一个特定值或者说是给符号名定义一个数值。格式中的符号名通常是代表寄存器名称或专用常数的一个字符串,xxH通常是一个不大于8bit二进制数的数值。一个符号名一旦由EQU赋值,其值就固定下来了,不能再被重新赋值。符号名应从一行的第一列开始书写,其后至少保留一个空格与EQU隔离。
ORG:程序起始地址定义伪指令。格式:ORG xxxxH
用于指定该伪指令后面的源程序存放的起始地址,也就是编译后的机器码目标程序在单片机的程序存储器中开始存放的首地址。xxxxH是一个13bit长的地址参数。
END:程序结束伪指令。
END伪指令通知编译器MPASM结束对源程序的编译。一个源程序中必须要有并且只有一条END伪指令,放在整个程序的末尾。

8.程序基本格式:

示例
;TITLE This is......程序标题
;符号名定义和变量定义
INDF EQU 00H ;个操作寄存器地址定义,将要用到的寄存器单元地址和位地址
TMR0 EQU 01H ;用表意性很强的符号名预先定义
PCL EQU 02H
STATYS EQU 03H
FSR EQU 04H
PORTA EQU 05H
TRISA EQU 85H
X EQU 20H ;对程序所需变量预先进行定义
Y EQU 21H ;复位矢量和中断矢量安排(对于PIC16F873)
ORG 0000H ;地址0000H为复位矢量
GOTO MAIN ;跳转到主程序
ORG 0004H ;地址0004H为中断矢量
GOTO INT_BODY ;跳转到中断服务程序
;主程序区
ORG 0005H ;从0005H开始存放主程序
MAIN CLRW ;主程序标号一定要处在0页内
CALL SUB
......
GOTO MAIN
;子程序和中断服务程序区
SUB MORLW 01H ;子程序
......
RETURN ;子程序返回
INT_BODY ;中断服务程序
MOVLW 0FFH
......
RETIE ;中断服务程序返回
END ;程序结束

9.程序基本结构:

程序,按其执行顺序,可分为顺序结构、分支结构、循环结构和子程序结构4种。
1)顺序结构:
计算机执行程序时表现为从头至尾严格按照次序一条语句一条语句地顺序执行,并且每一条语句均被执行一遍。
2)分支结构:
3)循环结构:
程序设计中,对某一段程序重复执行多遍。一个循环程序结构包含循环初态设置、循环体和循环控制三部分。循环初态设置就是在循环开始时,指定或定义一个循环变量(可以是循环次数计数器、地址指针等),并且给它设置一个初始值;循环体为要求重复执行的程序段;循环控制就是根据循环结束条件判断是否结束循环。在循环程序中必须给出循环结束条件,否则就成为“死循环”。
4)子程序结构:
实际程序中,常常会遇到一些完全相同的计算和操作,可以编制成标准化的程序段,存储于程序存储器的指定区域,在每次需要时调出使用,这种程序段就称为子程序。
PIC系列单片机编程时,在主程序的适当地方放置CALL指令来实现跳转,在子程序的开头需要使用地址标号,作为子程序的名称,末尾用RETURN或RETLW指令,以便子程序的调用和子程序的返回。在子程序调用子程序时,会遇到参数传递和现场保护问题。
所谓参数传递,就是在调用子程序前,主程序应先把有关参数放到某些约定的存储器单元,进入子程序后就可以从约定的单元取出有关参数加以处理。处理完之后,子程序也应把处理结果送到约定单元。在返回主程序后,主程序可以从这些约定单元获得所需结果。在主程序和子程序之间传递8位参数是,工作寄存器W是理想的选择。
所谓现场保护,就是主程序在运行过程中使用了一些寄存器来存放临时数据(或中间结果),在子程序运行过程中有时也要用到这些寄存器,为了避免对于主程序还有用的临时数据被子程序覆盖,就要设法保护这些临时数据。在执行完子程序返回主程序时,还要恢复这些数据,这成为现场保护。对应PIC单片机,一般是用合理分配寄存器单元的办法,避免子程序的数据和主程序的数据发生冲突,这样可以省略现场保护和现场恢复的过程。

10. 常用程序示例:

1)RAM存储器单元拆分成高和低两个半字节:
MOVF 20H ;将20H单元的内容送入W
ANDLW 0FH ;将W高4位清零,低4位保持不变
MOVWF 21H ;将拆分后的低4位送21H单元
SWAPF 20H,0 ;将20H单元内容高/低半字节换位后送入W
ANDLW 0FH ;将W高4位清零,低4位保持不变
MOVWF 22H ;将拆分后的高4位送22H单元

2)将地址从30H开始的50个单元都填入00H:
COUNT EQU 20H ;指定20H单元作为循环次数计数器(即循环变量)
FSR EQU 04H ;定义FSR寄存器地址为04H
INDF EQU 00H ;定义映射寄存器INDF地址为00H
MOVLW D’50’ ;把计数器初始值50送入W
MOVWF COUNT ;再把50转入计数器(作为循环变量的初始值)
MOVLW 30H ;将30和(起始地址)送入W
MOVWF FSR ;再把30H转入FSR寄存器用作地址指针
NEXT CLRF INDF ;把以FSR内容为地址所指定的单元清零
INCF FSR,1 ;地址指针内容加1,指向下一个单元
DECFSZ COUNT,1 ;计数值减1,结果为0就跳过下一条指令到STOP处
GOTO NEXT ;跳转回去并执行下一条循环
STOP GOTO STOP ;结束循环之后执行该语句,实现停机

3)设置I/O口的输入/输出方向:
MOVLW 0FH ;0000 1111B
MOVWF TRISB ;将W中的0FH写入RB控制寄存器,高4位输出/低4位输入

4)检查寄存器的值是否为零:
MOVF 10H,1 ;F10→F10,结果影响零标记状态位Z
BTFSS STATUS,Z ;F10为零则跳转
GOTO NZ ;Z=0,即F10不为零时转入标号NZ处理程序
...... ;Z=1,即F10=0处理程序

5)比较两个寄存器值的大小:减法运算,根据C判断,结果放入W而不影响寄存器原值
MOVF 8H,0 ;F8→W
SUBWF 9H,0 ;F9-W→W
BTFSC STATUS,Z ;判断是否F8=F9
GOTO F8=F9 ;
BTFSC STATUS,C ;C=0则跳转
GOTO F9>F8 ;C=1相减结果为正,F9>F8
GOTO F9 ......

6)循环n次的程序:以F10做计数器,使程序循环8次
COUNT EQU 10H ;定义F10名称为COUNT
......
MOVLW 08H ;
MOVWF COUNT ;循环体
LOOP DECFSZ COUNT,1 ;COUNT减1,结果为零则跳
GOTO LOOP ;结果不为零,继续循环
...... ;结果为零,跳出循环

7)查表程序:利用带值返回指令RETLW K来实现,构成一维数据表
采用带入口参数和出口参数的子程序结构,用数据表构成子程序的主体部分。在子程序的开头安放一条修正程序计数器PC值的指令,来实现子程序内部的跳转。查表时,在主程序中先把地址偏移量存入W,然后将地址偏移量取出并与程序计数器PC的当前值叠加,则程序指针就会指向携带着所需段码的RETLW指令处。由该指令将段码装入W中,向子程序传递参数,然后返回主程序。
PCL EQU 02H ;定义寄存器PCL的地址为02H
STATUS EQU 03H ;定义寄存器STATUS的地址为03H
RPO EQU 06H ;定义RP0比特的位地址为06H
PORTB EQU 06H ;定义寄存器PORTB的地址为06H
TRISB EQU 86H ;定义寄存器TRISB的地址为86H
ORG 0000H ;设置复位矢量
GOTO MAIN ;跳转到主程序
ORG 0005H ;设置主程序起始地址
MAIN BSF STATUS,RP0 ;选择BANK1
CLRF TRISB ;定义PORTB端口各脚全部为输出
BSF STATUS,RP0 ;恢复BANK0
MOVF 20H,0 ;把20H单元的数据送W
ANDLW 0FH ;屏蔽掉高4位后作为查表地址偏移量
CALL CONVERT ;调用数码转换子程序
MOVWF PORTB ;送到PORTB端口显示
STOP GOTO STOP ;停机
;-----------------------------
CONVERT ;子程序名称
ADDWF PCL,1 ;W内容叠加到PC的低8位上
TABLE RETLW 3FH ;”0”的段码
RETLW 06H ;”1”的段码
RETLW 5BH ;”2”的段码
RETLW 4FH ;”3”的段码
RETLW 66H ;”4”的段码
RETLW 6DH ;”5”的段码
RETLW 7DH ;”6”的段码
RETLW 07H ;”7”的段码
RETLW 7FH ;”8”的段码
RETLW 6FH ;”9”的段码
RETLW 77H ;”A”的段码
RETLW 7CH ;”B”的段码
RETLW 39H ;”C”的段码
RETLW 5DH ;”D”的段码
RETLW 79H ;”E”的段码
RETLW 71H ;”F”的段码
END
以上程序是用8位端口PORTB作为共阴极LED数码管的驱动端口,把寄存器单元20H中的数据的低4位送到LED显示。数据表表头为TABLE,当程序跳转到子程序时,便开始执行ADDWF指令。这时,程序计数器PC的当前值已经指向表头,在此基础上再叠加W中的表内地址偏移量,叠加后的PC值指向相应的RETLW指令,使程序跳转到该指令并执行它,执行后便返回主程序,并同时将返回值装入W中。
8)单嵌套延时程序:较短的软件延时
N EQU 20H ;
M EQU 21H ;
;延时0.3ms子程序
DELAY1 MOVLW X ;循环变量初始值X(待定)经W转送N
MOVWF N ;
LOOP DECFSZ N,1 ;N-1送N并判断结果是否为0,若是则跳出循环
GOTO LOOP ;若否,则循环回去
RETURN
9)双嵌套延时程序:较长的软件延时
;延时100ms子程序
DELAY3 MOVLW D’133’ ;外循环变量初始值经W转送M
MOVWF M ;
LOOP1 MOVLW D’251’ ;内循环变量初始值经W转送N
MOVWF N ;
LOOP2 DECFSZ N,1 ;N-1=0? 若是,跳出内层循环
GOTO LOOP2 ;否,循环回去
DECFSZ M,1 ;M-1=0? 若是,跳出循环
GOTO LOOP1 ;否,循环回去
RETURN
10)定时器延时:TMR0使用1/256分频比,4MHz振荡频率下延时65536us
TMR0 EQU 1
......
CLRF TMR0 ;TMR0清0
MOVLW 07H
OPTION ;选择预设倍数1/256→RTCC
LOOP MOVLW 255 ;TMR0计数终值
SUBWF TMR0,0
BTFSS STATUS,Z ;TMR0=255?
GOTO LOOP
......
11)程序跨页跳转和调用程序:主程序放置在页面0内,子程序部分放置页面1内。
页面0的地址范围为0000H~07FFH,页面1的地址范围为0800H~0FFFH。PCLATCH[3]位作为页面选择位。程序较长并且超过2K时,必然会跨页存放。
PCLATCH EQU 0AH ;将符号名PCLATCH定义为0AH(地址0AH)
ORG 0000H ;地址为0的单元专门用作复位矢量
GOTO MAIN ;存放一条到主程序的跳转指令
ORG 0500H ;从页面0的500H单元开始存放主程序
MAIN BSF PCLATCH,3 ;预置页选位,准备选择页面1
CALL SUB ;调用子程序,引起程序跳转
LOOP ...... ;从子程序返回后执行的第一条指令
;-------------------------------
ORG 0900H ;从页面1的900H单元开始存放
SUB MOVLW ;子程序
......
RETURN ;返回到位于页面0的主程序的LOOP处
END
在执行子程序的返回指令RETURN之前,不必理会页选位PCLATCH[3],这是因为在发生跳转时,程序计数器PC的值先被压入堆栈中保留,然后才用来自PCLATCH的页选位和来自CALL指令的11位地址吗填充。在子程序执行完毕返回时,因为堆栈的宽度是13位的,从堆栈中弹出PC原值,从而可以使程序回到原页面中。
12)散转程序:程序同时有多个分支
LOOP CLRF FLAG0
MOVF FLAG1,0
ADDWF PCL,1
GOTO INF0 ;转去运行INF0程序段
GOTO INF1 ;转去运行INF1程序段
GOTO INF2 ;转去运行INF2程序段
GOTO INF3 ;转去运行INF3程序段
GOTO INF4 ;转去运行INF4程序段
GOTO INF5 ;转去运行INF5程序段
GOTO INF6 ;转去运行INF6程序段
GOTO INF7 ;转去运行INF7程序段
13)二进制转换为BCD数的程序:
;入口参数:S1、S0为输入的16位二进制数
;出口参数:R2、R1和R0为转换后的5位BCD数
;****16位二进制转换为BCD数子程序****
INDF EQU 00H ;定义INDF寄存器地址为00H
FSR EQU 04H ;定义FSR寄存器地址为04H
COUNT EQU 20H ;移位次数寄存器
S0 EQU 21H ;二进制的低8字节
S1 EQU 22H ;二进制的高8字节
R0 EQU 23H ;存放BCD数的第5位数
R1 EQU 24H ;存放BCD数的第4、3两位
R2 EQU 25H ;存放BCD数的第2、1两位
TEMP EQU 26H ;用来暂存比较时用的寄存器
MOVLW 10H ;
MOVWF COUNT ;把十进制数16送往移位次数寄存器
BINTOBCD MOVLW D’16’ ;
MOVWF COUNTE ;
BCF STATUS,0 ;清进位标志位C
BCF STATUS,0 ;清进位标志位C
CLRF R2 ;清R2寄存器
CLRF R1 ;清R1寄存器
CLRF R0 ;清R0寄存器
LOOPC RLF S0 ;左移S0寄存器
RLF S1 ;左移S1寄存器
RLF R2 ;左移S2寄存器
RLF R1 ;左移S1寄存器
RLF R0 ;左移S0寄存器
DECFSZ COUNT,1 ;16位二进制是否移位完
GOTO ADJDEC ;未完,转为调整子程序
RETURN
ADJDEC MOVLW R2
MOVWF FSR ;将R2寄存器的地址存入FSR
CALL ADJBCD ;调整R2
MOVLW R1
MOVWF FSR ;将R1寄存器的地址存入FSR
CALL ADJBCD ;调整R1
MOVLW R0
MOVWF FSR ;将R0寄存器的地址存入FSR
CALL ADJBCD ;调整R0
GOTO LOOPC
ADJBCD MOVLW 03H
ADDWF INDF,0 ;LSD加3
MOVWF TEMP
BTFSC TEMP,3 ;结果>7?
MOVWF INDF ;是,结果存INDF所对应的寄存器地址;否,跳
MOVLW 30H
ADDWF INDF,0 ;MSD加3
MOVWF TEMP
BCTFSC TEMP,7 ;结果>7?
MOVWF INDF ;是,结果存INDF所对应的寄存器地址;否,跳
RETURN
END
14)BCD数转换为二进制数模块:
;入口参数:R2、R1和R0为5位BCD数
;出口参数:S1、S0为输出的16位二进制数,S0放高位,S1放低位
;****BCD数转换为16位二进制子程序****
INCLUDE
COUNT EQU 20H ;移位次数寄存器
S0 EQU 21H ;二进制的高8字节
S1 EQU 22H ;二进制的低8字节
R0 EQU 23H ;存放BCD数的第5位数
R1 EQU 24H ;存放BCD数的第4、3两位
R2 EQU 25H ;存放BCD数的第2、1两位
ORG 25H
BCDTOB MOVLW 10H ;
MOVWF COUNT ;把十进制数16送往移位次数寄存器
CLRF S0
CLRF S1
LOOPC BCF STATUS,C
RLF R0 ;左移S0寄存器
RLF R1 ;左移S1寄存器
RLF R2 ;左移S2寄存器
RLF S0 ;左移S0寄存器
RLF S1 ;左移S1寄存器
DECFSZ COUNT,1 ;16位二进制是否移位完成
GOTO ADJDEC ;未完,转为调整子程序
RETURN
ADJDEC MOVLW R2
MOVWF FSR ;将R2寄存器的地址存入FSR
CALL ADJBIN ;调整R2
MOVLW R1
MOVWF FSR ;将R1寄存器的地址存入FSR
CALL ADJBIN ;调整R1
MOVLW R0
CALL ADJBIN ;调整R0
GOTO LOOPC
ADJBIN MOVLW 03H
BTFSC INDF,3 ;IF>7?
SUBWF INDF ;是,结果存INDF所对应的寄存器地址;否,跳
MOVLW 30H
BCTFSC INDF,7 ;结果>7?
SUBWF INDF ;是,结果存INDF所对应的寄存器地址;否,跳
RETURN
END
15)两个16位数加运算模块:
;入口参数:ACCC中为被加数的高字节ACCCH和低字节ACCCL
;入口参数:ACCA中为加数的高字节ACCAH和低字节ACCAL
;出口参数:寄存器ACCC为和的高/低字节
;----无符号双精度数加法子程序----
ADD16 MOVF ACCAL,W
ADDWF ACCCL ;(ACCCL)+(ACCAL)→(ACCCL)
BTFSC STATUS,C
INCF ACCCH ;(ACCCH)+1→(ACCCH)
MOVF ACCAH,W
ADDWF ACCCH ;(ACCCH)+(ACCAH)→(ACCCH)
RETURN
16)两个16位数减运算模块:
;入口参数:ACCC中为被减数的高字节ACCCH和低字节ACCCL
;入口参数:ACCB中为减数的高字节ACCBH和低字节ACCBL
;出口参数:寄存器ACCC为差的高/低字节,进位C=0表示被减数小于减数,C=0则相反
;----无符号双精度数减法子程序----
SUB16 MOVF ACCBL,W
SUBWF ACCCL ;(ACCCL)-(ACCBL)→(ACCCL)
BTFSC STATUS,C
DECF ACCCH ;有借位(C=0)(ACCCH)-1→(ACCCH)
MOVF ACCBH,W
SUBWF ACCCH ;(ACCCH)-(ACCBH)→(ACCCH)
RETURN
17)两个16位数相乘模块:
;入口参数:ACCA中为被乘数的高字节ACCAH和低字节ACCAL
;入口参数:ACCB中为乘数的高字节ACCBH和低字节ACCBL
;出口参数:乘积从高到低存放在ACCCH、ACCCL、ACCDH、ACCDL中
;----无符号双精度数乘法子程序----
MU16 MOVLW 10H
MOVWF CNT_MU
CLRF ACCCH
CLRF ACCCL
CLRF ACCDH
CLRF ACCDL
MLOOP RRF ACCBH,1 ;将乘数ACCB的最低位移入进位位C
RRF ACCBL,1
BTFSC STATUS,0 ;C=1,加被乘数ACCA至部分积ACCC
CALL DADD
RRF ACCCH,1 ;部分积带进位位右移1位
RRF ACCCL,1
RRF ACCDH,1
RRF ACCDL,1
DECFSZ CNT_MU,1
GOTO MLOOP
RETURN
;双精度加法(ACCA+ACCC=ACCC)
DADD MOVF ACCAL,0
ADDWF ACCCL,1 ;(ACCAL)+(ACCCL)→(ACCCL)
BTFSC STATUS,0
INCF ACCCH,1
MOVF ACCAH,0
ADDWF ACCC,1 ;(ACCAH)+(ACCCH)→(ACCCH)
RETURN
18)两个16位数相除模块:
;入口参数:BCCB中为被除数的高字节BCCBH和低字节BCCBL
;入口参数:BCCA中为乘数的高字节BCCAH和低字节BCCAL
;出口参数:商存放在BCCB,余数放在BCCC中
;----无符号双精度数除法子程序----
DIVS CALL SETUP1 ;被除数放入BCCD
CLRF BCCCH
CLRF BCCCL
DLOOP BCF STATUS,C
RLF BCCDL,1 ;被除数低位左移1位
RLF BCCDH,1 ;被除数高位左移1位
RLF BCCCL,1 ;余数低位左移1位
RLF BCCCH,1 ;余数高位左移1位
MOVF BCCAH,0 ;比较双精度数大小
SUBWF BCCCH,0
BTFSS STATUS,C ;余数高位大于等于除数高位,C=1,跳过下一条
GOTO NOCHK ;余数高位小于除数高位,返回
MOVF BCCAL,0 ;比较余数的低位和除数的低位
SUBWF BCCCL,0
NOCHK BTFSS STATUS,C ;余数低位大于等于除数低位,结果左移
GOTO NOGO
MOVF BCCAL,0
SUBWF BCCCL,1
BTFSS STATUS,C ;余数低位大于等于除数低位,执行下一条
DECF BCCCH,1 ;余数低位小于除数低位,余数高位减1
MOVF BCCAH,0
SUBWF BCCCH,1
BSF STATUS,C ;够减,进位位置1,左移进入结果
NOGO RLF BCCBL,1 ;运算结果左移
RLF BCCBH,1
DECFSZ CNT_DIS,1
GOTO DLOOP
CLRWDT
RETURN
SETUP1 MOVLW 10H
MOVWF CNT_DIS
MOVF BCCBH,0 ;被除数(BCCB)→(BCCD),BCCD放被除数
MOVWF BCCDH
MOVF BCCBH,0
MOVWF BCCDH
MOVF ACCAH,0
CLRF BCCBH
CLRF BCCBL
RETURN

本文转自:http://www.dwenzhao.cn/profession/mcu/picasm.html

围观 1563

pic单片机是常用器件之一,每位学习pic单片机的朋友在学习过程中总会遇见各种难题,如pic单片机选型问题。本文将对pic单片机选型进行详细阐述,以帮助大家扫清选型难点。

pic单片机相当于一个小的计算机,pic单片机(Peripheral Interface Controller)是一种用来开发和控制外围设备的集成电路(IC)。一种具有分散作用(多任务)功能的CPU。与人类相比,大脑就是CPU,pic 共享的部分相当于人的神经系统。pic单片机有计算功能和记忆内存像CPU并由软件控制运行。然而,处理能力—般,存储器容量也很有限,这取决于pic的类型。但是它们的最高操作频率大约都在20MHz左右,存储器容量用做写程序的大约1K—4K字节。

用pic单片机使电路做的很小巧变得可能。而且因为pic单片机可以把计算部分、内存、输入和输出等都做在一个芯片内。所以她工作起来效率很高、功能也自由定义还可以灵活的适应不同的控制要求,而不必去更换不同的IC。这样电路才有可能做的很小巧。

当今单片机厂商琳琅满目,产品性能各异。针对具体情况,我们应选何种型号呢?首先我们要搞清楚各种型号之间的区别,从pic单片机的命名规则中我们可以了解很多。

单片机的选型是一件重要而费心的事,如果选型得当,则做出来的产品就会性价比较高,且工作稳定;反之,则可能会造成产品成本过高或影响产品正常运行,甚至可能根本就达不到预先设计要求。

pic单片机选型之前需要了解命名规则。



pic单片机选型技巧

(1)“芯片含有(功能或数量)略大于设计需求”,“设计需求尽可能(用)芯片完成(少用外围器件)”;
(2)“选大(大厂)不选小,选多(供应量多)不选少,选名(名牌)不选渺(飘渺,不知详情的厂子),选廉(廉价)但要好(质量保证)”。具体要从单片机应用的技术性、实用性和开可发性等方面来考虑:

1、内存

单片机FLASH的容量根据程序的大小确定,FLASH容量必须大于代码量。举例来说,如果你的代码量大约50 KB,那么建议你选择FLASH容量为64 KB或128 KB的单片机。

2、速度

单片机的运行速度首先看时钟频率,一般情况对于同一种结构的单片机,时钟频率越高速度越快。如果你的设计对速度要求很高,那么要选择一个运行速度较快的单片机。例如,一般情况下,电机控制应用大多采用100ksps或更高的采样速率,因此当单片机用于电机控制时,时钟频率要足够高。总之,在选用单片机时要根据产品需要选择时钟频率,不要片面追求高速度,时钟频率越高功耗也就越大。此外,单片机的稳定性、抗干扰性等参数基本上跟单片机的运行速度成反比。因此,要尽量寻找可以在很高的时钟频率下运行而功耗又不高的单片机。

3、外设需求

如果你的设计需要ADC、SPI、GPIO、USB等之类的外设,那么你需要寻找一款集成所有这些外设的单片机。因为,使用一个具有上述外设的单片机显然比使用一个普通的单片机及外围加一个单独的ADC更为经济。此外,外设集成于单片机同时也意味着更低的功耗,因为没有可以产生功耗的外围电路,也没有用于连接外围电路的能产生功耗的敷铜,只有单片机本身产生功耗。

4、方便的开发工具

这是个非常重要的方面,因为开发工具可以极大地影响你所设计的产品的功耗。很多公司都已经开发出了具有代码优化功能的编译器,所以当你编译代码的时候,编译器会告知具体编译信息,你可以根据编译信息优化代码以降低功耗。举例来说,如果你的设计需要用到ADC、UART和GPIO等外设,你就需要初始化这些器件,但是设计中使用UART是有条件的(仅用于调试时显示结果),此时编译器会提示你禁用这个外设以降低功耗。必须得说这种智能化的开发工具对开发者来说是一种福音。

5、未来需求和兼容性

设计者在设计产品时需要考虑产品未来可能需要升级等之类的问题。例如,若需要给设计增加某些功能,那么可能需要增加内存、外设等,还可能需要加提高单片机的运行速度。因此,在单片机的选型上需要在当前设计需求以及未来设计上寻找平衡,以满足不同程度的要求。

6、成本

一个好的设计不仅要功能完善,而且要满足成本要求,如果无法控制成本,再好的设计也是枉然。因此,需要尽可能地降低单片机甚至整个产品的成本。

7、工作电压(VCC)

单片机的工作电压是指可以让其正常工作所需要提供的电压。工作电压越高,单片机的功耗也就越大。因此,为了降低产品功耗,必须要尽可能地降低工作电压。

除此之外,我还要建议设计者根据具体产品需求选择合适芯片架构。若仅是个简单的控制应用(如照明系统、电子玩具等),那么并不需要一个像ARM那样具有复杂架构的芯片。此外,对于低功耗设计,单片机必须具有睡眠模式,基于中断操作的睡眠模式/低功耗模式的使用是降低功耗的一个标准的行业惯例。

最后再来一句老生常谈:不要拘泥与芯片是否先进,单片机只是一个工具,真正的功夫在于你的专业知识,要用最合适的芯片做出最合适的产品。

来源:网络整理

围观 105

单片机入门不难,这是几年前的一篇老文章,讲得通俗易懂,分享给初学者。

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

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

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

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

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

轮到第几条腿啦?奥,是第5条腿,这条叫单片机的 I/O 脚。就是输入输出脚。你可通过程序动态地控制它作为输入或输出,作为输出时可以程序控制它的输出电平为高1或低0。所以,他的工作状态有四种:输入0,输入1,输出0,输出1,剩下的两条腿和第5脚功能一个样。

上边我们已经把8条腿消化掉了,其实我们要弄明白的也就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这两个管脚处于输入状态,这两个例句无效,是控制不了电平的。

无论如何,这一会儿,你就学会了两个指令,35条我看也没啥难的。单片机的入门就是这么简单。

来源:EDN电子技术设计

围观 36

仿生机器鱼实验平台属于教育部和北京邮电大学共同出资支持的一项“国家级大学生创新性实验计划”项目,是一个集光、机、电、流体、智能于一体的实验平台,研究内容包括:仿生机器鱼机械结构的研究,推荐效率的研究以及控制性能的研究。

1、仿生机器鱼平台简介:

设计制作的机器鱼模仿鲹科鱼类的外形,头部采用刚性结构的塑料材料。其形状采用流线型,模仿真鱼鱼头的形状和大小比例。在鱼头的内部空间里安装电源及控制电路,并在鱼头两侧鱼眼处及在头前部的偏下侧安装了3 个红外传感器,构成了一个探测左、前、右三个方向的传感器网络,让鱼具有自助避障的功能。

使用铝合金制作的鱼骨架把三个舵机串联起来,鱼骨架支撑起套于舵机外面的橡胶鱼皮,便构成了了机器鱼的鱼身这个三关节的驱动系统。使用铝合金制作的连接件将鱼身通过螺纹连接的方式固定在在刚性鱼头上,鱼身的橡胶鱼皮使用热熔胶粘在鱼头上,这样便构成了机器鱼的整体结果。具体如图1 所示。实验证明,这种方法简单易行,且方便拆卸和组装。

基于PIC单片机的仿生机器鱼的舵机控制

机器鱼技术指标:巡游速度:1.2~1.5m./s;全电量巡游距离:4.5~5.5 千米;转弯半径:15~20cm。

2、系统组成及工作原理:

从功能上看,整个鱼体的系统可以分成三大块,分别是:感知区,决策区,行为区。感知区对应着多红外传感器网络和无限传输模块,而决策区指的是主控芯片(MCU),动作区对应着舵机串联组成的三关节驱动系统。具体如图2所示。本系统的最重要的工作集中在对多舵机的协调控制,因此主要围绕舵机的控制工作进行细致详尽的介绍。

基于PIC单片机的仿生机器鱼的舵机控制

3、舵机的控制

3.1 舵机的工作原理:

舵机主要由以下几个部分组成:舵盘、减速齿轮组、比例电位器(位置反馈电位计)、直流电机(马达)、控制电路板等。其工作原理:控制电路板接受来自信号线的控制信号,控制直流电机转动,直流电机带动一系列齿轮组,其齿轮组的输出轴与一个线性的比例电位器相连,该电位器把输出轴转过的角度θ 转换成比例的电压反馈给控制电路,控制电路将其与输入的控制脉冲信号比较,产生纠偏脉冲,并驱动马达正向或反向地转动,使齿轮组的输出位置与期望值相符,令纠正脉冲趋于为0,从而达到使舵机精确定位的目的。舵机是一个典型闭环反馈系统,其工作原理由图3 所示。

基于PIC单片机的仿生机器鱼的舵机控制

舵机的输入线共有三条,红色中间,是电源线,一边黑色的是地线,这两根线给舵机提供最基本的能源保证,主要是电机的转动消耗。电源有两种规格,一是4.8V,一是6.0V,分别对应不同的转矩标准,另外一根线是控制信号线,一般为白色。

3.2 单舵机和多舵机的角度控制

3.2.1 单舵机的角度控制:

由舵机的工作原理可知,给舵机输入一个周期在20ms 左右,脉冲宽度在0.5ms 至2.5ms 之间的周期性脉冲信号,驱动舵机输出轴达到-90°到90° 之间的转角,呈线性变化。并且无论外界转矩怎样改变,舵机的输出轴都会保持在一个相对应的角度上,直到给它提供一个另外宽度的脉冲信号,才会改变输出角度到新的对应的位置上。通过编程,借助单片机的输出端口得到需要的周期性脉冲信号。

程序示例:(晶振为:4MHZ,脉冲从PORTDbits.RD0 输出)
基于PIC单片机的仿生机器鱼的舵机控制
从上面的程序可知,通过改变delay 函数的形参j,可以根据需要,得到具有相应脉冲宽度和周期的脉冲信号。例如,改变以上程序段的1 至4 行为:
基于PIC单片机的仿生机器鱼的舵机控制
得到输出脉冲宽度为1ms,周期为20ms 的脉冲信号,然后借助for 循环,将能得到所需要的周期性脉冲信号,驱动舵机输出轴达到-90°到90° 之间的转角。

3.2.2 多舵机不同角度的控制:

通过多舵机不同角度的控制,可以控制几个舵机同时向不同角度扭转,以达到预期的控制目的。

具体的实现方法是:在定时器延时函数中设定一个计时值t(在程序中t 在初始化时值为0),使t 在每次定时器计时完毕时加1。例如,定时器一周期的定时时间为0.25ms,则t值每加1 就相当于0.25ms。当t 的代表值达到20ms 也就是当t 等于80 时清零,这样就可以将脉冲周期控制在20ms,再通过使用if 语句查询方式,可以调节同一周期脉冲的脉冲宽度,即能使多舵机同时向不同角度旋转。

程序示例:(晶振为:4MHZ,脉冲从PORTDbits.RD0,PORTDbits.RD1,PORTDbits.RD2三个端口中输出)
基于PIC单片机的仿生机器鱼的舵机控制

通过以上程序再配合for 循环,便能在PORTDbits.RD0,PORTDbits.RD1,PORTDbits.RD2三个端口得到脉冲宽度分别为1ms,1.5ms,2ms,周期同为20ms 的三种周期脉冲信号,从而达到对三个舵机同时进行不同控制的要求。当然利用以上的方法,可以很轻松地对3 个以上的多个舵机同时进行控制。

3.3 舵机的速度控制

通过舵机的特性可以了解到舵机的瞬时运动速度是由其内部的直流电动机和变速齿轮组的配合来决定的,在恒定的电压驱动下,其数值是恒定的。但舵机的平均运动速度可通过分段停顿的控制方式来改变,例如,把动作幅度为90°的转动细分为128 个停顿点,通过控制每个停顿点的时间长短来实现0°到90°变化的平均速度。也就是说,将90 度的连贯一步转动变为128 个停顿的步进转动,通过每步之间的短暂停顿可实现减速的目的,因为停顿时间非常短因此可看做是90°的连贯转动,由于篇幅的限制,这里不再给出相应的程序实例,感兴趣的读者可以自己参考上面的程序实例进行编写。

4、结束语

本文介绍的这种方法产生的PWM 波形精度高,能够很好的完成舵机的控制工作,舵机工作稳定,我们设计制作的机器鱼成功地实现了鱼类的一些基本运动动作,如前游,加速,停止,前进中转弯等,这也验证了所采用的多关节驱动方式和对多舵机的控制方法是行之有效的。本文通过以仿生机器鱼为载体进行撰文,意在抛砖引玉,希望对其它的舵机控制应用起到帮助。

来源:畅学单片机

围观 328

ICSP(In-Circuit Serial Programming)即在线串行编程,通过保持RB6和RB7引脚为低电平,VDD 为编程电压,并将MCLR(VPP)引脚电压从VIL增加到VIHH,器件便进入编程/校验模式。此时,RB6为编程时钟线,RB7为编程数据线。在该模式下,RB6和RB7都是施密特触发器输入,当RB7驱动数据时,它是CMOS输出驱动。

复位后,为使器件进入编程/校验模式,程序计数器(PC)指向00h地址。然后可向器件发送一个6位的命令,根据这一命令是装入还是读出,14位编程数据将被提供给器件或是从器件中读出。但是在线串行编程模式下,看门狗定时器电路不能产生器件复位。

硬件电路

在线串行编程电路应该注意以下问题:

1)MCLR/VPP引脚与电路其它部分相隔离

通常设计中MCLR/VPP引脚与RC电路相连,上拉电阻接VDD,电容接地。VPP电压必须与电路的其它部分隔离,根据电容器的大小,RC电路可能影响ICSP的操作。因此当RC电路与MCLR/VPP相连时,可以使用了肖特基型二极管来隔离电路。当对PICmicro ® 单片机编程时,MCLR/VPP引脚将被同时驱动至大约13V,因此应用电路必须与编程器提供的编程电压隔离。

2)RB6和RB7的负载

RB6和RB7引脚用于PICmicro®单片机的串行编程。RB6是时钟线,RB7是数据线。RB6由编程器驱动,RB7是双向引脚,编程时由编程器驱动,校验时由PICmicro®单片机驱动。这两个引脚必须与电路的其它部分隔离,从而在编程时不会对信号产生影响。将RB6和RB7与电路其它部分隔离时必须考虑编程器的输出阻抗。隔离电路必须使RB6能够作为PICmicro®单片机的输入,而RB7能够作为双向引脚(PICmicro® 单片机和编程器都能驱动它)。

为简化接口设计,使用microchip推荐的I/O引脚的最佳方法:将RB6/RB7专用于ICSP;这些端口作为输出时,具有极轻的负载;采用隔离电路,使信号满足ICSP规范。

3)VDD、MCLR/VPP、RB6和RB7引脚的电容问题

编程引脚的总电容将影响编程器输出信号的上升速率。典型电路中,一般在VDD和地之间接有几百微法的滤波电容以抑制噪声和电源电压波动。但是这种电容需要编程器必须具有相当强的驱动能力,才能满足VDD上升速率的要求。大多数编程器只能对PICmicro®单片机进行编程,而不能驱动整个应用电路。一种解决方案是在编程器和应用电路之间加一块驱动电路板。驱动电路板有独立的电源,应该满足VPP和VDD引脚电压上升速率的要求,并可为整个应用电路供电。RB6和RB7是否需要缓冲取决于具体的应用。

4)VDD的最小和最大工作电压

Microchip 编程规范规定器件应在5V电压下编程。如果应用电路只能在3V电压下工作,那么需要一些特殊的措施。例如在编程时将PICmicro®单片机与其它应用电路完全隔离。另一个问题是,必须在应用电路的最小和最大工作电压下对器件进行校验。例如,在一个使用三个1.5V电池供电的系统中,其工作电压范围是2.7V到4.5V。而编程器必须在5V电压下对器件进行编程,并且必须在2.7V和4.5V电压下对程序存储器进行校验,以确保编程正确。这样可以保证PICmicro® 单片机在整个工作电压范围内都能正常工作。

5)PICmicro®单片机的振荡器

PIC单片机在代码执行前振荡器上电延迟定时器要等候1024个振荡周期。RC振荡器不需要上电延迟时间,因此不使用上电延迟定时器。编程器必须在RC振荡器振荡4次之前,令MCLR/VPP达到进入编程模式所需的电压。如果RC振荡器振荡了4次或4次以上,程序计数器将会增加到一个不确定的值X。如果这时器件进入编程模式,程序计数器不为零,编程器将从偏移量X开始烧写代码。有一些方法可以弥补MCLR/VPP的低上升速率问题。第一种方法是先不接RC振荡器的电阻,对器件编程后再接入R电阻。另一种方法是在编程时用编程接口将 PICmicro® 的OSC1引脚短接到地,这样在编程期间便不会产生振荡。

综合考虑以上情况,使用最简方式实现PIC18F4550的ICSP连接电路。在电路中,增加了由RD0和RD1口驱动的发光二极管,由此来验证烧写电路是否能够正常工作。

PIC单片机在线串行编程(ICSP)的实现

对于ICSP接口与PIKkit™ 3连接的如下图所示,必须使PIKkit™ 3与ICSP的引脚对应。
PIC单片机在线串行编程(ICSP)的实现

转自:markmin214

围观 742

我们把所设计的数据采集系统功能分解为三大部分:数据采集部分、数据通信部分、数据处理部分。

数据采集部分应包含:A/D转换器,时序、模式控制,数据缓冲功能。它应能接受来自主机的命令,按不同模式控制A/D转换器采集数据,暂存于数据缓冲区,再根据主机命令发给主机。这部分功能由一个单片机及接口来实现是最优方式。

数据通信部分应包含:简单、高效、通用的数据通信模式和软硬件支持。它应能在数据采集和数据处理两部分之间实现目前最好的连接和沟通。因为USB作为一种外部总线标准,用于规范电脑与外部设备的连接和通讯,并具有传输速度快,使用方便,支持热插拔,连接灵活,独立供电等优点,所以这部分功能采用USB接口连接最好。

数据处理部分应包含:强大、高效、通用、适应性好的软硬件支持平台。它应能完成主控和数据处理两大功能。主控就是根据用户需要,给数据采集部分下达命令,采集数据,同时管理数据通信部分,实现信息的上传下达,读取数据。数据处理就是要提供方便实用的数据的分析、处理、存储、显示、输出等各种应用功能,满足用户的尽可能多的需求。这部分功能自然非PC机莫属。

系统功能安排是:PC机作为主机(也称上位机),单片机(也称下位机)负责数据采集与缓冲保存,USB接口负责两者之间的数据通信。

具体工作流程是:PC机接收用户的应用命令,按系统功能配置数据采集参数,通过USB接口,给单片机发送控制命令,单片机按下达的命令控制A/D转换进行数据采集,并将采集到的数据作缓冲保存,采集好一批数据后,再按主机要求通过USB接口发送给PC机,PC机完成数据的存储、简单分析、处理、显示、输出等基本应用。更进一步还可以对数据进行格式转换,供其它专业数据处理软件作输入数据,实现更多高级数据处理功能。

MCU选型

为实现设计要求,微处理器必须含有具有A/D转换功能和USB通信功能的两个基本模块,以及其它实现拓展功能的模块。

基于PIC单片机USB接口的数据采集系统设计

上图所示为设想的功能板图,控制器通过它的功能模块与外围设备进行联系: USB模块与PC机连接,进行USB通信;A/D模块接模拟量输入,进行A/D转换;D/A模块接模拟量输出,产生输出波形;I/O接口外接输入输出;I2C模块与传感器等含I2C的器件连接,进行I2C通信;SPI模块与外围设备相连,使单片机与各种外围设备以串行方式进行通信以交换信息。

USB总线的数据采集方案一般有两种,一种是采用专用的USB通信芯片。另一种是利用具有USB接口功能的单片机。考虑到实际情况,本设计选用第二种方案。

PIC18F4550是Microchip公司生产的带全速USB接口的8位高档单片机,该单片机具有精简指令集、哈佛结构等特点,运行速度快、执行效率高。它的硬件资源非常丰富,并集成有多个功能模块: ICSP接口模块,可以通过PICkit™ 3与PC机联系,进行程序的烧写和调试;它的全速USB 2.0接口模块,可以方便、快捷的实现USB通信。

由此,我们选用PIC18F4550单片机来进行设计。它的优势在于:

1、利用它的USB接口,可以实现与PC机之间通信,不需要另加USB接口芯片。

2、利用它的ICSP模块,可以实现PC机对单片机进行程序的直接烧写,并进行在线调试。

3、能够让电路的设计更为简洁、实用,既提高了整个设计的安全性和可靠性,又降低整个系统的功耗。

4、Microchip公司提供了集成开发环境Mplab和汇编语言、C语言编译器,使我们在程序调试,模拟运行方面更容易、更方便快捷。Microchip公司同时还提供了USB通信的范例和demo子程序,使我们在使用USB通信功能时更加的简单、快捷。

围观 447

所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7~RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。

在设计引脚中断程序时,有三个需要特别注意的地方。

一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。

二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假中断。

三是,一般都利用PIC单片机的引脚功能来检测按键,所以必须处理好按键消抖的问題。

在主程序里先设置有关的寄存器。

◇设置TRISB寄存器,使RB7~RB4相关的引脚处于输入状态;

◇如果需要弱上拉,通过OPTION_REG的第7位设置;

◇RBIF=O;

◇RBIE=1;

◇GIF=1。

响应状态变化后的中断服务程序。

◇检查RBIF是否为l,为l则是引脚变化引起的中断;

◇调用延时程序,延时20~30 ms,目的是为了按键去抖;

◇判断是引脚出现上升沿还是下降沿引起的中断;

◇调用按键处理程序;

◇读PORTB口的值,取消状态变化的硬件信号;

◇清除RBIF标志。

笔者认为上面程序设计最大的问题是在中断程序里调用延时程序。大家知道,中档PIC单片机只有8层深度的硬件堆栈,在中断里调用于程序出现极易堆栈溢出的情况。另外,PIC单片机中断程序人口只有一个,在响应中断的请求时,PIC单片机就会自动把全局中断的使能位(INTCON的第7位GIF)清除,这样其他中断就暂时不能被响应(此时,如果别的中断发出的中断请求,标志位将一直保留着),直到这个中断程序退出后才会得到响应。这就要求我们设计中断程序的时候必须尽量短,避免调用子程序,更不要在中断里进行复杂的运算。

下面给出笔者设计程序时的思路。

当引脚状态变化引起中断时,在中断子程序里首先判断引起中断的原因是不是我们需要的变化引起的中断。如果是,不要在这里延时,而是设置一个标志位,接着清除中断标志,退出中断。中断程序如下:

else if((RBIE&RBlF)==1){ //如果引脚变化引起中断

if(RB4==0){ //RB4上的按钮接地

key=1; //按键标志位置位

}

RBIF=0; //清除引脚中断标志位

}

其中,if(RB4==0)语句相当于读取了PORTB端口数据寄存器,取消了状态变化的硬件信号。

下面详细介绍怎么样进行按键去抖。

首先,在定时器中断里设置一个lms的时间基准标志位“SYSlms”,每到lms,“SYSlms”便置位。程序如下:

unsigned char count;

if((ToIE&TOIF)==1){ //定时器中断

TMRO+=0x09; //每250μs中断一次

if(count==4){

count=0;

SYSlms=l; //系统时间标志

couot++;

}

T0IF=0; //清除时钟中断标志位

}

有了这个时间基准,便可以在主程序里进行按键去抖处理了。为了更好地利用这个时间基准,定义一个消息标志SYSTime,笔者把它称作时间消息。为了让这个消息有自我发布和自我消失的功能.定义了如下一个宏:

bit SYSTime;

#defincTimeEnahle()SYSTime=0,if(SYSlms){SYSTime=l;SYSlms=0;)

可以把TimeEnable()放到主程序死循环的任何地方,每当程序执行这个宏,SYSTime就会清零,这就是标志位的自我消失.如果在定时器时间基准标志位SYSlms已经置位的话,SYSTime就会置1,这样别的程序就可以利用这个时间消息了,这就是消息的自我发布。下面就是利用这个时间消息来进行按键延时去抖的,首先看一下按键扫描子程序;

void seaakey(){

unsigned char KeyTime,KeyTask;//定义任务时间参数、

//任务参数

switch(KeyTask){

case0:if(key){

KeyTime=30; //准备延时30 ms

KeyTask++; //准备好下一个任务

kcy=0;

}

break;

case I:KeyTime--; //延时30 ms

if(KeyTime==0)Key+ask++;

break;

case2;if(RB4==o){

//调按键处理程序

KeyTask=0;

}

else KeyTask=0;//退出任务

break;

}

}

在主程序的死循环中这样用:

while(1){

TimeEnable();

If(SYSTime==1){scankey();)

//在此可以添加其他程序

只有有时问消息的时候才执行按键扫描程序。可以看到,进入扫描程序执行第一次的时候,程序首先判断按键标志位有没有置位,置位的话(也就是有按键按下的话),任务时间参数(KeyTime)赋值为30,这是延时30ms,去抖,当然你也可以设置为其他的时间值;同时任务参数 (KeyTask)加1。1ms后,再进入扫描程序,这个时候扫描程序执行casel的语句,这样30次后(延时了30ms),任务参数(KeyTask)加1,值为2。lms后,再进入扫描程序,将执行case 2的语句,首先在这里再次判断是不是按键还在按下,如果是就调按键的处理程序,如果不是。就退出按键扫描程序。在这里,还可以加入按键是否抬起的判断程序。

这样设计的引脚变化程序,CPU开销小,效率高,不会出现堆浅溢出的问题,提高了系统的实时性。

来源:畅学电子网

围观 429

在UPS等电力电子设备中,控制方法是核心技术。早期的控制方法使得输出为矩形波,谐波含量较高,滤波困难。SPWM技术较好地克服了这些缺点。

目前SPWM的产生方法很多,汇总如下:

1)利用分立元件,采用模拟、数字混和电路生成SPWM波。此方法电路复杂,实现困难且不易改进;

2)由SPWM专用芯片SA828系列与微处理器直接连接生成SPWM波,SA828是由规则采样法产生SPWM波的,相对谐波较大且无法实现闭环控制;

3)利用CPLD(复杂可编程逻辑器件)设计,实现数字式SPWM发生器;

4)基于单片机实现SPWM,此方法控制电路简单可靠,利用软件产生SPWM波,减轻了对硬件的要求,且成本低,受外界干扰小。

而当今单片机的应用已经从单纯依赖于51系列单片机向其它多种单片机发展,尤其以嵌入式PIC单片机的发展应用更为广泛。PIC单片机含具有PWM功能的外围功能模块(CCP),利用此模块更容易通过软件实现SPWM,且具有更快的执行速度。

本文采用软硬件结合设计的方法,利用面积等效法,并且基于PIC单片机实现对试验逆变系统的SPWM控制。

1、面积等效的SPWM控制算法:

目前生成SPWM波的控制算法主要有4种:
(1)自然采样法;
(2)对称规则采样法;
(3)不对称规则采样法;
(4)面积等效法。

理论分析后知自然采样法和面积等效法相对于规则采样法谐波较小,对谐波的抑制能力较强。又因为PIC单片机片内无较大空间实现在线运算,所以自然采样法不利于软件实现。本文的试验系统采用面积等效法实现SPWM控制,其原理如图1所示。

基于PIC单片机的SPWM控制技术

图1 SPWM面积等效算法 利用正弦波小块面积S1与脉冲面积S2相等原则,将正弦波的正半周分为N等分,则每一等分的宽度为π/N弧度,利用面积等效法计算出半个周期内N个不同的脉宽值,将产生的脉宽数列以列表形式存于PIC单片机的ROM中,以供程序调用。 脉宽产生的基本公式为
基于PIC单片机的SPWM控制技术

式中:M为调制度; N为载波比,即半个周期内的脉冲个数,实验中N取64; k取值为0~63。由式(1)计算出的实际脉宽转换成计时步阶后生成64个值的正弦表存入PIC的ROM中以供调用。产生的SPWM脉宽表是一个由窄到宽,再由宽到窄的64个值的表。

2、软硬件结合试验系统:

以PIC单片机内部的两个外围功能模块(CCP)为基础,利用该模块具有的PWM功能,软件控制两路SPWM波形的输出。再将这两路SPWM波利用互补导通原则变换成4路,经隔离放大后驱动IGBT逆变器,实现对输出的控制。

2.1 硬件设计

试验硬件系统如图2所示。

选择PIC单片机的中档系列,该系列单片机的主要特点有:

(1)具有高性能的RISCCPU;

(2)除程序分支指令为两个周期外,其余均为单周期指令,且仅有35条单字指令;

(3)8K%26;#215;14个FLASH程序存储器,368%26;#215;8个数据存储器(RAM)字节;

(4)中断能力强,达到14个中断源;

(5)外围功能模块丰富,含2个16位寄存器的CCP模块,具有PWM功能;

(6)含3个定时器,其中与PWM功能相关的定时器2(即TMR2)带有8位周期寄存器,且带有8位预分频器和后分频器。

基于PIC单片机的SPWM控制技术

图2 硬件试验系统 逆变部分采用自关断器件IGBT实现单相全桥逆变。IGBT是全控型电力电子器件,它的控制级为绝缘栅场效应晶体管,输出级为双级功率晶体管,因而它具有两者的优点而克服了两者的缺点。它开关频率相对高,驱动功率小,构成的功率交换器输出电压纹波小,线路简单,是当今最具有应用前景的功率器件。

2.2 软件设计

2.2.1 PIC单片机的设置

试验中设置SPWM的频率为20kHz,并外接20MHz晶振信号,计算得指令周期即计时步阶为0.2μs。PIC单片机CCP外围功能模块的PWM功能实现主要依靠相关寄存器值的设定,且以定时器2(TMR2)作为PWM的时基。

相关寄存器的设置如下:  

(1)SPWM周期的设定由寄存器PR2设定

(PWM)周期=(PR2+1)%26;#215;4%26;#215;Tosc%26;#215;(TMR2)预分频(4) 试验中Tosc为20MHz,为提高分辨率,TMR2预分频设为1:1,由此计算得PR2=0XF9;

(2)定时器TMR2的控制寄存器T2CON设定 因为SPWM频率高,周期短,在每个周期内完成脉宽的调整比较困难,故在此寄存器中设置后分频为1:3,这样每输出3个相同脉宽的SPWM波后改变一次脉宽值;

(3)2个CCP模块的控制寄存器CCP1CON及CCP2CON的设定 两个CCP模块控制寄存器的设置类似,选择CCP模块作用于PWM功能模式,即bit3:0=11ⅹⅹ。

(4)CCPR1L脉宽写入寄存器 写入的脉宽值在下个TMR2周期开始时转至CCPR1H,通过读CCPR1H的脉宽值来改变PWM脉宽。

(5)寄存器TRISC 对应于CCP1和CCP2的输入输出设置,应设置为输出形式,即TRISC的bit2:1=00。

2.2.2 SPWM波形产生的实现过程

软件控制PIC单片机使之产生SPWM波形?首先将之前设置的寄存器值写入相关寄存器,当PIC的PWM功能开启后TMR2从0开始计数,同时CCP模块引脚输出高电平。 当TMR2≥CCPR1L时,PWM功能引脚开始输出低电平。 当TMR2≥PR2时,则TMR2=0,重新开始另一个周期计数,PWM功能引脚开始输出高电平。同时TMR2的中断标志位被系统置高,即TMR2IF=1,转去执行中断服务程序。 因实验中设置TMR2后分频为1:3,故在3个PR2周期后程序才转去执行中断服务程序。在中断服务程序中查找脉宽表,将下一个脉宽值写入寄存器CCPR1L中。

下个周期输出的PWM的脉宽即为刚写入CCPR1L中的脉宽值,也就是说脉宽的变化在中断程序中实现,中断程序流程如图3所示。

基于PIC单片机的SPWM控制技术

图3 中断服务程序流程图 程序中利用标志位F实现SPWM输出在CCP1和CCP2中的转换。在F=1时,CCP1输出PWM波形,CCP2设置输出为0电平;在F=0时,CCP2输出PWM波形,CCP1设置输出为0电平。

3、试验结果与分析

由PIC单片机产生的SPWM波可由示波器测出。由于SPWM频率为20kHz,程序中又设置每3个脉宽相等,故在示波器中不能清楚地看到脉宽从最小到最大的完整的变化过程。由PIC单片机的CCP1引脚输出SPWM波形的一段如图4所示。

基于PIC单片机的SPWM控制技术

这段波形中的脉宽由窄逐渐变宽,符合SPWM的变化规律。 图4 SPWM波形的一段 试验中由PIC单片机的两个CCP模块产生两路SPWM波,将这两路SPWM波变换成4路后经隔离驱动逆变系统的IGBT。产生的两路SPWM波形分别对应正弦波的正负半波,完整周期的两路SPWM互补波形如图5所示。
基于PIC单片机的SPWM控制技术

图5 两路互补的SPWM波 试验系统在直流电压为30V时负载运行所得正弦波如图6所示,可知周期为19.9ms,满足工频要求。
基于PIC单片机的SPWM控制技术

图6 负载正弦波 试验系统为单相全桥逆变系统,这种工作模式有明显的倍频效应。倍频效应有利滤波,也可以降低器件的开关频率,减小开关损耗。又因为本试验系统采用面积等效法,相对于规则采样法谐波抑制能力较强。谐波分析后可在低电压时基本无偶次谐波,且所含奇次谐波幅值较小,能满足UPS逆变系统对谐波的要求。

4、结语

本文介绍的基于PIC单片机的SPWM控制技术很好地把软硬件技术结合在一起,针对规则采样法谐波大的缺点,利用面积等效法较好地抑制了谐波。本文给出了具体的硬件试验系统及软件设计,分析试验结果波形后表明此方法输出谐波较小,在对输出波形质量要求较高的UPS逆变系统中有较强的实用价值。如今PIC单片机应用越来越广泛,电力电子技术发展越来越快速的阶段,这种软硬件结合的控制技术在其它很多应用领域也有较大的发展空间。

转自:博客园 - 奔流聚海

围观 434

页面

订阅 RSS - PIC单片机