单片机与嵌入式
51单片机的寻址方式
51单片机的汇编指令系统
51汇编语言的伪指令
51汇编语言程序结构与程序示例
Keil C51程序设计
Keil C51的库函数
PIC单片机的基本结构
PIC单片机的汇编语言指令
PIC单片机的C语言编程
ATmega16单片机基本结构
ATmega16单片机的汇编语言
ATmega128单片机的结构
STM32单片机基础
使用STM32CubeMX开发STM32单片机
uC/OS-II嵌入式操作系统
uC/OS-II在STM32F10xx上的移植
FreeRTOS系统介绍
Linux系统介绍
Linux系统编程
嵌入式Linux编程
1. PIC的性能特点:
1)采用哈佛结构:芯片内部将数据总线和指令总线分离,并且采用不同的宽度。
2)指令的单字节化:PIC的指令字节宽度是不同的,12bit、14bit和16bit。
3)采用精简指令集:PIC单片机只有35条指令,易学好用。
4)寻址方式简单:只有寄存器间接寻址、立即数寻址、直接寻址和位寻址4种方式。
5)代码压缩率高:最节省程序存储空间的单片机。
6)运行速度高:指令读取和执行采用了流水线作业方式,使单片机的运行速度大大提高。
7)功耗低:有些型号在4MHz时钟下工作时耗电不超过2mA,睡眠模式下低到1uA以下。
8)驱动能力强:每个I/O端口输入/输出电流最大值可达25mA和20mA。
9)具备I2C和SPI接口:一些型号具备I2C和SPI串行总线端口。
10)寻址空间设计简洁:程序、堆栈、数据有相互独立的寻址空间。
11)外围电路简单:片内集成了上电复位、I/O引脚上拉、WDT等电路,可减少外围器件。
12)开发方便:有各种档次的烧录器(或编程器)和硬件仿真器,MPLAB软件开发环境。
13)编程语言:提供了C语言编程。
14)品种丰富:有3个层次、50多个型号,封装从8脚到68引脚,满足不同的应用需求。
15)规格齐全:OTP(EPROM)型,带窗口的EPROM型,ROM掩模型,Flash或EEROM型。
16)程序保密性强:目前尚无法对片内程序直接进行解密拷贝。
2. PIC单片机的型号命名:
PIC |
XX |
XXX |
XXX |
(X) |
-XX |
X |
/XX |
1)前缀:PIC为Microchip公司的单片机代号,dsPIC为集成DSP功能的单片机
2)系列号:PIC10/12/16/18为8位单片机,PIC24、dsPIC30/33为16位,PIC32为32位。
3)器件类型:C--CMOS,CR--CMOS ROM,LC--小功率CMOS,LCS--小功率保护,LCR--小功率CMOS ROM,LV--低电压,AA-- 1.8V,F--Flash,HC--高速CMOS,FR--FLEX ROM
4)改进类型或选择:54A、58A、61、62、620、621、622、63、64、65、71、73、74等
5)晶体标示:LP--小功率晶体,RC--电阻电容,XT--标准晶体,HS--高速晶体
6)频率标示:02--2MHz,04--4MHz,10--10MHz,16--16MHz,20--20MHz等
7)温度范围:空白--0~70℃,I-- -45~+85℃,E-- -40~125℃
8)封装形式:L--PLCC,JW--陶瓷熔封双列直插(有窗),P--塑料双列直插,PQ--陶瓷四面引线扁平封装,W--大圆片,SL--14脚微型封装150mil,JN--陶瓷熔封双列直插(无窗),SM--8脚微型封装207mil,SN--8脚微型封装150mil,VS--超微型封装8x13.4mm,SO--微型封装300mil,ST--薄型缩小的微型封装4.4mm,SP--横向缩小型塑料双列直插,CL--68脚陶瓷四面引线(带窗),SS--缩小型微型封装,PT--薄型四面引线扁平封装,TS--薄型微型封装8x20mm,TQ--薄型四面引线扁平封装
3. PIC16F627的内部资源及管脚定义:
PIC16F627:1024x14bit程序存储器Flash,224x8bit数据RAM,128x8bit内部EEPROM,指令字节14bit,18PIN双列直插封装,工作速度最高20MHz,8级深度硬件堆栈,35条单字节指令(除转移指令),宽工作电压2.0~5.5V。Flash可经受10万次写操作,EEPROM可经受100万次写操作,数据保持期40年。内有两个模拟比较器,可编程的片上参考电压模块。2个8位定时/计数器,1个16位定时/计数器,10位PWM模块,USART/SCI。
具有高精度的内部4MHz振荡器,出厂时精度校准为±1%;低功耗内部48kHz振荡器,可使用晶振和谐振器作为外部振荡器。WDT带有独立的振荡器,能保证可靠运行。
低功耗功能:待机电流,电压2.0V时,典型值100nA;工作电流,频率32kHz电压2.0V时,典型值12uA,频率1MHz电压2.0V时,典型值120uA。WDT电流,电压2.0V,典型值1uA。TMR1振荡器电流,频率32kHz电压2.0V时,典型值1.2uA。
引脚的复用功能:
MCLR/Vpp:复位输入/编程电压输入,低电平复位,该脚电压超过Vdd会进入编程模式。
OSC2/CLKIN:振荡器晶体/外部时钟输入端。
OSC2/CLKOUT:振荡器晶体输出端,RC方式时输出OSC1频率的1/4信号。
TOCK1:TMR0计数器输入端。
TICK1:TMR1时钟输入端。
TIOSI:TMR1的振荡输入端。
TIOSO:TMR1的振荡输出端。
RD、WR、CS:代表并行口读信号、写信号和片选控制线。
AN0~AN7:A/D转换的模拟量输入端。
CCP:捕捉/比较/PWM等功能端,是Capture/Compare/PWM的缩写
SCK/SCL:同步串行通信时钟输入端。
TX/CK:异步通信发送端/SCI同步传输的时钟端。
SDI/SDA:SPI通信数据输入端。
SDO:SPI通信数据输出端。
4. PIC16F627的内部存储器:
1)程序存储器:
PIC16F627/628/648有一个13位的程序计数器PC。13位PC可寻址空间8Kx14,地址编码的最大范围为0000H~1FFFH,PIC16F627/628/648单片机实际的程序存储器分别只有1Kx14(0000H~03FFH)、2Kx14(0000H~07FFH)和4Kx14(0000H~0FFFH)单元。对超出以上范围的单元寻址时,会导致内部溢出返回。
PIC的指令CALL和GOTO只提供11位地址,因此只能在2K范围内跳转,因此要将程序存储器空间按2K为单位进行分页,用寄存器PCLATCH寄存器的D4和D3两位来选择页面。
程序存储器保留了两个特殊单元,一是地址为0000H的单元,存放复位矢量;另一个是地址为0004H的单元,专门存放中断矢量。复位矢量,就是主程序的入口地址,单片机复位后,都将从该地址执行主程序。所谓中断矢量,就是中断服务子程序的入口地址,无论何种原因引起的单片机中断,都将从该地址进入中断服务子程序。
2)堆栈:
PIC16F627的堆栈具有8x13的独立空间,8级深度13位宽,栈指针不能读写,也没有堆栈操作专用指令。当执行CALL或者CPU响应中断而发生程序跳转时,把当前程序计数器PC的值自动压入堆栈;当执行RETURN、RETFIE或RETLW指令时,会从堆栈中弹出并恢复程序计数器PC原先的值。
在操作过程中,无法获取堆栈信息,没有指示堆栈满或未满的标志。堆栈是作为循环缓冲区使用的,当压栈超过8次后,第9次压栈时进栈的数据将覆盖第1次压栈存储的数据,而第10次压栈时进栈的数据将覆盖第2次压栈存储的数据,以此类推。
3)数据存储器RAM:
RAM数据存储器被划分为4块存储区,每个区是128x8单元,占用512个地址空间,地址编码需要9位,即000000000B~111111111B。其中,0区的地址范围是000H~07FH,1区的地址范围是080H~0FFH,2区的地址范围是100H~17FH,3区的地址范围是180H~1FFH。
每个存储区的前32个存储单元为特殊功能寄存器SFR(Special Function Register),后面的96个单元为通用寄存器GPR(General Purpose Register)。其中有一些寄存器单元在4个寄存器区上是相互映射的,如状态寄存器STATUS、寄存器INDF、程序计数器低8位PCL、间接地址寄存器FSR、程序计数器的高位锁存器PCLATCH和中断控制寄存器INTCON。也就是说,在4个寄存器区内的相同位置,是同一个寄存器,该单元具备4个不同的地址,例如状态寄存器STATUS的4个地址是03H、83H、103H和183H,利用这4个地址都能找到该寄存器单元。而选项寄存器OPTION_REG、定时/计数器TMR0、端口RB的数据寄存器PORTB和方向寄存器TRISB等都有两个不同的地址。
通过状态寄存器STATUS的两个位RP1和RP0的设置,可以选择访问这4个存储区中的一个:00--存储区0,01--存储区1,10--存储区2,11存储区3。
其中的通用寄存器GPR是由用户自由安排和存放数据的空间,上电复位后内容不确定,可直接访问或通过指针寄存器FSR间接访问。而特殊功能寄存器SFR的每个单元都有固定的用途,用于配置CPU内核或控制外围功能模块的操作。
5. PIC16F627的特殊功能寄存器:
1)状态寄存器STATUS:地址03H、83H、103H、183H
状态寄存器,用来记录算术逻辑单元ALU的运算状态和算术特性、CPU的特殊运行状态以及RAM的选择等信息,其中一些位(TO和PD)只能读而不能写,另一些位则会随运算结果而变化。
IRP |
RP1 |
RP0 |
TO- |
PD- |
Z |
DC |
C |
R/W |
R/W |
R/W |
R |
R |
R/W-x |
R/W-x |
R/W-x |
C:进位/借位标志,1--最高位有进位,0--最高位无进位。ADDWF、ADDLW、SUBLW、SUBWF指令会影响其内容。
DC:辅助半进位/借位标志,1--发生了第4位向高位的进位,0--第4位没有向高位进位。ADDWF、ADDLW、SUBLW、SUBWF指令会影响其内容。(对借位,极性是相反的)
Z:全零标志,1--算术或逻辑运算结果为0,0--结果不为0。
PD-:掉电标志,1--上电或执行CLRWDT指令后,0--执行SLEEP指令后。
TO-:超时标志,1--上电执行CLRWDT或SLEEP指令后,0--WDT超时溢出.
RP1/RP0:寄存器选择位(用于直接寻址),00--0页(00H~7FH),01--1页(80H~FFH),10--2页(100H~17FH),11--3页(180H~1FFH)。每页128字节。
IRP:寄存器存储区选择位(用于间接寻址),1--选择2、3页(100H~1FFH),0--选择0、1页(00H~FFH)。
注意:如果STATUS寄存器作为一条影响Z、DC、C标志位指令的目标寄存器,则会禁止写入这3个标志位,根据器件逻辑,这些位会被置位或清零。建议仅使用BCF、BSF、SWAPF、MOVWF指令去改变STATUS寄存器,因为这些指令不会影响任何状态位。
对于借位,C、DC的极性是相反的,因为减法操作是通过加上第2个操作数的二进制补码来完成的。对于移位指令RRF、RLF,此位值来自寄存器的最高位或最低位。
PD-和TO-可用来判断RESET的原因:00--WDT溢出时唤醒SLEEP,01--WDT溢出(非SLEEP),10--MCLR端加低电平唤醒SLEEP,11--电源上电。例如,对系统初始化时,需判断这次复位是否因上电引起的,如果不是上电复位,则不再进行初始化。
2)选择寄存器OPTION:地址81H、181H
选择寄存器,用来配置TMR0/WDT预分频器、外部RB0/INT中断、TMR0和PORT弱上拉。
RBPU |
INTEDG |
TOCS |
TOSE |
PSA |
PS2 |
PS1 |
PS0 |
PS2/PS1/PS0:预分频器分频比选择位。
PS2 |
PS1 |
PS0 |
TMR0比率 |
WDT比率 |
0 |
0 |
0 |
1:2 |
1:1 |
0 |
0 |
1 |
1:4 |
1:2 |
0 |
1 |
0 |
1:8 |
1:4 |
0 |
1 |
1 |
1:16 |
1:8 |
1 |
0 |
0 |
1:32 |
1:16 |
1 |
0 |
1 |
1:64 |
1:32 |
1 |
1 |
0 |
1:128 |
1:64 |
1 |
1 |
1 |
1:256 |
1:128 |
注:要使TMR0的预分频比为1:1,应将预分频器分配给WDT(PSA=1)。
PSA:预分频器分配控制位,1--分配给WDT,0--分配给Timer0模块。
TOSE:TMR0外部信号源边沿选择,1--RA4/TOCKI/CMP2引脚电平发生下跳变时递增,0--发生上跳变时递增。
TOCS:TMR0时钟源选择位,1---RA4/TOCKI/CMP2引脚的信号作为时钟源,0--内部指令周期信号CLKOUT作为时钟源。
INTEDG:中断触发边沿选择位,1--RB0/INT端信号上升沿中断,0--下降沿中断。
RBPU-:PORTB上拉使能位,1--关闭弱上拉,0--使能弱上拉。
3)中断控制寄存器INTCON:地址0BH、8BH、10BH、18BH
GIE |
PEIE |
TOIE |
INTE |
RBIE |
TOIF |
INTF |
RBIF |
RBIF:RB端口输入电平改变中断标志位,1--RB[7:4]输入发生变化(至少有一个引脚),需软件清零,0--RB[7:4]输入没有发生变化。
INTF:RB0/INT外部中断标志位,1,发生了外部中断(必须软件清零),0--未发生外部中断。
TOIF:TMR0溢出中断标志位,1--TMR0寄存器已经溢出(必须软件清零),0--未发生溢出。
RBIE:RB中断使能位,1--RB端口的高4位电平变化中断允许位,0--禁止RB口中断。
INTE:RB0/INT外部中断允许位,1--使能RB口中断,0--禁止RB口中断。
TOIE:TMR0溢出中断允许位,1--使能TMR0中断,0--禁止TMR0中断。
PEIE:外部中断使能位,1--使能所有外部中断,0--禁止所有外部中断。
GIE:全局中断允许位,1--允许所有未屏蔽的中断,0--禁止所有中断。
注:当一个中断条件发生时,不管相应的中断允许位或全局允许位GIE的状态如何,中断标志位都将置位。
4)外设中断允许寄存器1 PIE1:地址8CH
寄存器中包含中断允许位。
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
TMR1IE:TMR1中断使能位,1--使能TMR1中断,0--禁止TMR1中断。
TMR2IE:TMR2与PR2匹配中断允许位,1--允许TMR2与PR2匹配中断,0--禁止。
CCP1IE:CCP1中断使能位,1--允许CCP1中断,0--禁止CCP1中断。
TXIE:USART发送中断允许位,0--允许USART发送中断,0--禁止USART发送中断。
RCIE:USART接收中断允许位,1--允许USART接收中断,0--禁止USART接收中断。
CMIE:比较器中断使能位,1--使能比较器中断,0--禁止比较器中断。
EEIE:EE写操作完成中断允许位,1--允许EE写操作完成中断,0--禁止EE写操作完成中断。
5)外设中断标志寄存器1 PIR1:地址0CH
寄存器中包含中断标志位。
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
TMR1IF:TMR1中断标志位,1--TMR1发生中断溢出,0--TMR1未发生中断。
TMR2IF:TMR2与PR2匹配中断标志位,1--发生了TMR2与PR2匹配(必须用软件清零),0-- TMR2与PR2不匹配。
CCP1IF:CCP1中断标志位。捕捉模式下,1--发生了TMR1寄存器捕捉(必须用软件清零),0--没有发生TMR1寄存器捕捉;比较模式下,1--发生了TMR1寄存器比较匹配(必须用软件清零),0--没有发生TMR1寄存器比较匹配;PWM模式下未使用。
TXIF:USART发送中断标志位,1--USART发送缓冲器是空的,0--发送缓冲器已满。
RCIF:USART接收中断标志位,1--USART接收缓冲器已满,0--接收缓冲器是空的。
CMIF:比较器中断标志,1--比较器输出发生了改变,0--比较器输出没有改变。
EEIF:EEPROM写操作中断标志位,1--写操作完成(必须用软件清零),0--写操作未完成或未开始。
注:当一个中断条件发生时,不管相应的中断允许位或总的中断允许位GIE的状态如何,中断标志位都将置位。用户软件应在允许一个中断之前,确保先将相应的中断标志位清零。
6)电源控制寄存器PCON:地址8EH
PCON寄存器包含用来区分上电复位、外部MCLR复位、WDT复位或欠压复位的标志位。
- |
- |
- |
- |
OSCF |
- |
POR- |
BOR- |
BOR-:欠压复位状态,1--没有发生欠压复位,0--发生了欠压复位(复位后需用软件清零)。
POR-:上电复位状态,1--没有发生上电复位,0--发生了上电复位((复位后需用软件清零)。
OSCF:INTOSC振荡器频率位,1--典型值4MHz,0--典型值48kHz。
注:BOR-在上电复位时未知,必须在上电复位后由用户置位,并在接下来的复位中检查BOR-位是否清零,从而指示是否发生的是欠压复位。如果禁止了欠压电路(将配置字中的BOREN位清零),则BOR-状态位可忽略,也没必要对其内容作出预测。
7)程序指针寄存器PC、PCLATCH:
程序寄存器PC为13位宽,专门提供程序寄存器的地址,为了与其他8位宽的寄存器进行数据交换,分为PCL和PCH两部分。低8位的PCL有自己的地址,可读写;高5位的PCH没有地址,不能直接写入,只能用PCLATCH寄存器装载的方式间接写入。对PCH装载分为两种,一是当执行以PCL为目标的指令时,PC的低8位来自ALU,高5位来自PCLATCH;二是当执行跳转指令GOTO或调用子程序指令CALL时,PC的低11位来自指令码中直接携带的11位地址,高2位来自PCLATCH。
使用GOTO跳转指令时,通过向PC加一个偏移量来实现,通过改变PCL值得到。偏移量只有8位,所以只能寻址256字节范围。当使用GOTO指令进行读表操作时,要注意表地址是否超过了PCL能确定的256字节范围。
PIC的指令CALL和GOTO只提供11位地址,因此只能在2K范围内跳转,因此要将程序存储器空间按2K为单位进行分页,用寄存器PCLATCH寄存器的D4和D3两位来选择页面。当执行CALL和GOTO指令前,用户必须首先确定页面选择位,使之指向所需要转移的页面。
如果执行RETURN指令,整个13位的PC值弹出堆栈,寄存器PCLATCH的D4和D3两位不需要进行设置。执行RETURN和RETFIE指令后,PCLATCH的内容不受影响,因此在子程序调用或GOTO时,用户必须重写PCLATCH。
8)间接寻址寄存器FSR和映射寄存器INDF:
位于RAM数据存储器最顶端、地址码最小的映射寄存器INDF,其实是一个空寄存器,只有地址码,并不是一个真正的寄存器单元。INDF寄存器与FSR寄存器配合,可实现间接寻址,当寻址INDF寄存器时,实际上是访问以FSR内容为地址的数据存储单元。
直接寻址:最大寻址512字节,用9位寻址地址,其中指令码中包括7位直接寻址位,还有2位来至状态寄存器STATUS的寄存器选择位RP1/RP0,用于选择存储区。示例:
BSF STATUS.RP0 ;指向第1页
MOVLW 0F0H ;
MOVWF TRISB ;RB0~RB3定义为输出,RB4~RB7定义为输入
BCF STATUS.RP0 ;指向第0页
间接寻址:最大寻址512字节,用9位寻址地址,状态寄存器STATUS的IRP与FSR的最高位组合选择存储区,而FSR的低7位则确定存储区中的地址单元。示例:
MOVLW 86H ;将常数86H送到间接寻址寄存器
MOVWF FSR
MOVLW 0F0H
MOVWF INDF ;将常数0F0H送到86H所指向的单元
对映射寄存器INDF的操作就是对间接寻址寄存器FSR的内容所代表地址所指向单元的操作。
6. EEPROM数据存储模块:
EEPROM数据存储器在正常工作状态下是可读写的,但不是直接映射到文件寄存器空间,而是通过特殊功能寄存器对其进行间接寻址。有4个用于读写EEPROM的寄存器,分别是EECON1、EECON2、EEDATA和EEADR。PIC16F627/628有128字节的EEPROM,地址范围00H~7FH;PIC16F648A有256字节的EEPROM,地址范围00H~FFH。
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
9AH |
EEDATA |
EEDAT7 |
EEDAT6 |
EEDAT5 |
EEDAT4 |
EEDAT3 |
EEDAT2 |
EEDAT1 |
EEDAT0 |
9BH |
EEADR |
EEADR7 |
EEADR6 |
EEADR5 |
EEADR4 |
EEADR3 |
EEADR2 |
EEADR1 |
EEADR0 |
9CH |
EECON1 |
- |
- |
- |
- |
WRERR |
WREN |
WR |
RD |
EECON1为EEPROM控制寄存器,只有低4位存在。RD为读控制位,1--开始读EEPROM,0--未启动读操作。WR为写控制位,1--开始写周期,0--数据EEPROM写周期完成。WREN为写使能位,1--允许写EEPROM写操作,0--关闭EEPROM写操作。WRERR为错误标志位,1--提前终止写操作,0--写操作完成。
EEDATA寄存器中存放的是要读写的数据。当要对EEPROM存储器写入时,先要把写入数据置入EEDATA中;而当读EEPROM存储器时,CPU即是把读出数据放入EEDATA中再由用户用程序读取。EEPROM数据存储器允许字节读写,字节写操作会自动擦除目标单元并写入新数据。
EEADR[6:0]指定EEPROM读写操作的目的地址单元(128个地址单元)。PIC16F627/628只有128地址单元,EEADR7必须设置为0;PIC16F648有256字节的EEPROM,EEADR7置1将读写128个高地址单元的EEPROM。
EECON1控制寄存器的低4位是物理实现的,高4位实际不存在。控制位RD/WR分别启动读和写,用软件只能将这些位置位而无法清零,是在读/写操作完成后由硬件清零。
置位WREN位将允许一次写操作。上电时,WREN位被清零。正常工作时,当写操作被MCLR复位或WDT超时复位中断时,WREER位置位。在这些情况下,复位后用户可以检查WRERR位的状态并重写该单元。EEDATA和EEADR寄存器中的数据和地址将保持不变。
写操作完成时,PIR1寄存器中的中断标志位EEIF会置位,此位必须用软件清零。EECON2不是物理寄存器,它专用于防止在存储器写序列中的非法写操作,只在写操作时起作用,读到的是0。
1)EEPROM数据读取:
要读取数据存储器单元,用户必须将地址写入EEADR寄存器,然后置位控制位RD。随后的一个周期数据就出现在EEDATA寄存器中,因此该数据可在下一条指令中读取。EEDATA将把此值保存至下一次用户向该单元读取或写入数据时(在写操作过程中)为止。
为了进行一次EEPROM读操作,步骤如下:将EEPROM的单元地址放入EEADR;置RD=1;读取EEDATA寄存器。示例:
BSF STATUS,RP0 ;选择BANK1
MOVLW 20H ;
MOVWF EEADR ;地址20H→EEADR
BSF EECON1,RD ;启动读操作
MOVF EEDATA,W ;将EEPROM数据读入W寄存器
BCF STATUS,RP0 ;选择BANK0
2)EEPROM数据写入:
要写入EEPROM数据单元,用户必须首先将地址写入EEADR寄存器,并将数据写入EEDATA寄存器。然后,用户必须按特定顺序开始写入每个字节。
为了进行一次写操作,步骤如下:将EEPROM单元地址放入地址寄存器EEADR;将要写入的数据放入数据寄存器EEDATA中;写入固定的格式程序并恢复开中断。示例:
BCF STATUS,5 ;选择BANK0
MOVLW 20H ;
MOVWF EEADR ;地址20H→EEADR
MOVLW 88H ;
MOVWF EEDATA ;数据88H→EEDATA
BSF STATUS,RP0 ;选择BANK1
BSF EECON1,WREN ;写操作使能
BCF INTCON,GIE ;关闭所有的中断
BTFSC INTCON,GIE ;确认无中断存在
GOTO $-2
MOVLW 55H ;
MOVWF EECON2 ;
MOVLW AAH ;
MOVWF EECON2 ;写入固定的格式程序
BSF EECON1,WR ;启动写操作
BSF INTCON,GIE ;恢复开中断
如果未完全按照上例中的顺序(先将55H写入EECON2,再将AAH写入EECON2,最后将WR位置1)逐字节写入,写操作将不会开始。在这一段代码段执行中建议禁止中断。
此外,必须将EECON1中的WREN置位以使能写操作。这种机制可防止由于执行错误代码导致误写EEPROM。除了更新EEPROM时以外,用户应始终保持WREN清零。只有WREN置1,WR才能够置1,写周期完成后,WR位由硬件清零,并且EEIF置1。用户可以使能此中断或查询此位,EEIF必须用软件清零。
写操作完成后,WREN要清零,保证平时EEPROM不会被意外写入。上电时,WREN被清零。
7.PIC16F627的复位功能和系统时钟:
1)复位功能:
单片机有一个复位端,以便于人为地输入复位信号,使其回到初始状态。单片机有几种自动实现复位的途径:
⑴人工复位:无论单片机是在正常运行程序,还是处在睡眠状态,或者出现死机,只要在人工复位端加入低电平信号,就会令其复位。
⑵上电复位:每次单片机加电时,上电复位电路都要对电源电压Vdd的上升过程进行检测,当Vdd上升到规定值1.6~1.8V,就产生一个有效的复位信号,需经72ms+1024个时钟周期的延时,才会使单片机复位。
⑶看门狗复位:不论何种原因,只要没有对看门狗定时器WDT进行周期性地及时清零,WDT就会出现超时溢出,也就会引起单片机复位。
⑷欠压复位:
2)系统时钟:
单片机内部的各种功能几乎全为数字电路组成,数字电路的触发器工作需要时钟信号,每一步动作都是在一个共同时间基准信号下完成的。作为时基发生器的时钟振荡电路,为整个单片机芯片的工作提供系统时钟信号,也为单片机与其他外接芯片之间的通信提供可靠的同步时钟信号。
PIC16F627的时钟电路是由片内的一只反相器和一只反馈电阻与外接石英晶体和两只电容器共同构成的一个自激多谐振荡器。构成振荡器的反相器是具有受控端的三态门,当执行睡眠指令SLEEP时,三态门输出端呈现高阻状态,令时钟电路停振,从而迫使单片机的绝大部分片内电路停止工作,进入低功耗模式,达到节电的目的。
模式 |
频率 |
OSC1(C1) |
OSC1(C2) |
LP |
32kHz |
15~30pF |
15~30pF |
200kHz |
0~15pF |
0~15pF |
|
XT |
100kHz |
68~150pF |
150~200pF |
2MHz |
15~30pF |
15~30pF |
|
4MHz |
15~30pF |
15~30pF |
|
HS |
8MHz |
15~30pF |
15~30pF |
10MHz |
15~30pF |
15~30pF |
|
20MHz |
15~30pF |
15~30pF |
8. 功能模块:
1)定时/计数器模块:
PIC16F627系列单片机具有定时/计数器,分别是定时/计数器0(TMR0)、定时/计数器1(TMR1)和定时/计数器2(TMR2)。TMR0是一个8位的简单增量溢出定时/计数器,TMR1是一个16位定时/计数器,TMR2是一个8位定时/计数器。
⑴定时/计数器0:
TMR0具有如下特性:8位定时/计数器、可读写、带8位可软件编程的预分频器、可选择内部或外部时钟信号、在计数从FFH到00H时计数溢出可产生中断、可选择外部时钟信号的触发边沿。与定时/计数器0有关的寄存器如表:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
01H,101H |
TMR0 |
TMR0模块寄存器 |
|||||||
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
81H,181H |
OPTION |
RBPU |
INTED |
T0CS |
T0SE |
PSA |
PS2 |
PS1 |
PS0 |
85H |
TRISA |
TRISA7 |
TRISA6 |
TRISA5 |
TRISA4 |
TRISA3 |
TRISA2 |
TRISA1 |
TRISA0 |
OPTION寄存器的第5位T0CS决定TMR0的工作模式,0--定时器模式,1--计数器模式。
OPTION寄存器的低3位设置预分频器的分配比,PSA=0,预分频器分配给TMR0使用。
定时器模式下,TMR0寄存器的值在每2个指令周期递增1(无预分频时);计数器模式下,TMR0的值将在RA4/T0CKI/CMP2引脚的每个上升沿或下降沿递增计数,递增沿由OPTION寄存器的T0SE位决定,0为上升沿,1为下降沿。
当TMR0寄存器发生从FFH到00H的溢出时,即产生TMR0中断,将T0IF位置1。中断可以通过清零T0IE位来屏蔽。在重新允许中断前,必须在TMR0模块的中断服务程序中用软件将T0IF位清零。休眠状态时,因定时器被关闭,TMR0无法唤醒单片机。
当TMR0用于外部时钟输入时,为了使外时钟满足采样要求,T0CKI引脚上信号的周期至少为4Tosc(加上40ns的RC延时)供预分频器分频。T0CKI引脚上的电平信号,要满足最小宽度10ns的要求。
预分频器,当分配给TMR0使用时,所有对TMR0寄存器的写操作指令(CLRF、MOVWF、BSF等)都将清零预分频器。当预分频器分配给WDT时,执行CLRWDT指令将同时清零预分频器和WDT。
⑵定时/计数器1:
TMR1为16位定时/计数器,由2个可读/写的寄存器组成。TMR1从0000H开始加1计数,到FFFFH后,再加1计数溢出,产生溢出中断,同时计数器回到0000H。当使用内部时钟计数时为定时器模式,使用外部时钟计数时为计数器模式。与TMR1有关的寄存器如表:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
||||
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
||||
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
||||
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
||||
0EH |
TMR1L |
16位TMR1寄存器低字节寄存器 |
|||||||||||
0FH |
TMR1H |
16位TMR1寄存器高字节寄存器 |
|||||||||||
10H |
T1CON |
- |
- |
T1CKPS1 |
T1CKPS0 |
T1OSCEN |
T1SYNC |
TMR1CS |
TMR1ON |
TMR1的控制寄存器为T1CON。TMR1ON为TMR1开关控制位,置1--启动;0--关闭。TMR1CS选择时钟源,1--来自RB6/T1OSO/T1CKI引脚的外部时钟(上升沿有效),0--内部时钟(Fosc/4)。T1SYNC为外部时钟同步控制位,1--与外部时钟输入不同步,0--与外部时钟输入同步。T1OSCEN为TMR1使能位,1--振荡器开启,0--振荡器关闭。T1CKPSC1/0为TMR输入时钟预分频器选择,11--1/8,10--1/4,01--1/2,00--1。
TMR1CS位清零,输入时钟是Fosc/4,即工作于定时器模式,总是同步的,T1SYNC无效。
TMR1CS位置1,为计数器模式,信号输入端由T1OSCEN决定,置1时信号来自RB7/T1OSI,清零时信号来自RB6/T1OSO/T1CKI。计数器模式又分为同步计数和异步计数。T1SYNC清零,则外部时钟输入与内部时钟相位同步,同步是在预分频器之后完成的。由于休眠模式下关闭同步电路,所以此时不能唤醒CPU,但预分频器会继续递增计数。
如果T1SYNC置1,外部时钟输入就不同步,休眠状态下继续运行,并能在溢出时产生中断并唤醒CPU。异步模式下,TMR1不能用作捕捉器或比较器工作的时基。
当计数器工作在外部异步时钟下时,TMR1H/TMR1L寄存器能够分别读取。对于写操作,建议停止计数器后再写入需要的数值,如果在递增计数时向定时/计数器寄存器写入数据可能产生写竞争,会产生无法预知的值。
在T1OSI和T1OSO引脚间内接振荡电路,外加晶振(建议32768Hz/15pF)时可以将T1OSCEN置1使能该电路。软件也要提供必要延时,确保正确起振。
T1CON寄存器在上电复位或欠压复位时为00H,相当于关闭了TMR1定时器,而在其他复位时则不受影响。在对TMR1H/TMR1L寄存器进行写操作时,预分频器被清零。
⑶定时器TMR2:
TMR2是一个带前后分频器的8位定时器,主要用作PWM的时基。TMR2有一个周期寄存器PR2,TMR2寄存器的值从00H开始递增计数,直到与PR2寄存器的值匹配为止,然后在下一个计数周期复位至00H。PR2寄存器可读写,复位时初始化为FFH。
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
11H |
TMR2 |
TMR2寄存器 |
|||||||
12H |
T2CON |
- |
TOUTPS3~TOUTPS0 |
TMR2ON |
T2CKPS1 |
T2CKPS0 |
|||
92H |
PR2 |
TMR2周期寄存器 |
T2CON为TMR2的控制寄存器。T2KPS1/0为预分频选择,00--1,01--1/4,1x--1/16。TMR2ON为TMR2开关控制,1--开启,0--关闭。TOUTPS3~TOUTPS0为TMR2输出后分频器选择,0000--1,0001--1/2,......,1111--1/16。
TMR2有预分频器,内部时钟首先在预分频器分频,分频比由T2CON的控制位T2CKPS1/0设定。而TMR2的匹配输出通过后分频器产生TMR2中断(中断标志位TMR2IF)。控制位TMR2ON可以关闭TMR2,以降低功耗。TMR2的输出还可以输入到同步串行端口CCP模块,用作移位时钟。当发生下列任一种情况,都会将预分频器和后分频器计数器清零:对TMR2寄存器进行写操作;对T2CON寄存器进行写操作;任何器件复位(上电复位、MCLR复位、WDT复位或者欠压复位)。当对T2CON进行写操作时,TMR2寄存器并不清零。
示例:定时/计数器2的初始化
CLRF T2CON ;停止定时/计数器2,预分频比1,后分频比1
CLRF TMR2 ;清TMR2寄存器
CLRF INTCON ;关中断
BSF STATUS,RP0 ;选择BANK1
CLRF PIE1 ;关外围中断
BCF STATUS,RP0 ;选择BANK0
CLRF PIR1 ;清外围中断标志位
MOVLW 72H ;设预分频比1/16,后分频比1/15
MOVWF T2CON ;关定时/计数器2
BSF T2CON,TMR2ON ;定时/计数器2开始计数
BTFSS PIR1,TMR2IF ;
GOTO $-1 ;等待定时/计数器2溢出中断
BCF PIR1,TMR2IF ;清标志位,继续
2)比较器模块:
PIC16F627比较器模块包含2个模拟比较器。在Vdd=5V条件下,比较器的最大相应时间为400ns。比较器的4个输入端与PA0~RA3复用片内的参考电压可以作为比较器的输入。
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
1FH |
CMCON |
C2OUT |
C1OUT |
C2INV |
C1INV |
CIS |
CM2 |
CM1 |
CM0 |
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
85H |
TRISA |
TRISA7 |
TRISA6 |
TRISA5 |
TRISA4 |
TRISA3 |
TRISA2 |
TRISA1 |
TRISA0 |
CMCON是比较器配置寄存器,决定比较器的工作模式及输入/输出构造。CM[2:0]是比较器工作模式选择位,可读写。CIS为比较器输入选择开关,只在CM[2:0]为001/010时有效。
CM[2:0]=001时,CIS=1,则比较器C1的IN-连接到RA3端。
CIS=0,则比较器C1的IN-连接到RA0端。
CM[2:0]=010时,CIS=1,则比较器C1的IN-连接到RA3,比较器C2的IN-接RA2。
CIS=0,则比较器C1的IN-连接到RA0,比较器C2的IN-接RA1。
C1INV是比较器1输出反相位,1--C1输出反相,0--C1输出不反相。C2INV是比较器2输出反相位,1--C2输出反相,0--C2输出不反相。C1OUT为比较器1输出位,当C1INV=0时,1--C1 IN+>C1 IN-,0--C1 IN+<C1 IN-;当C1INV=1时,1--C1 IN+<C1 IN-,0--C1 IN+>C1 IN-。C2OUT为比较器2输出位,当C2INV=0时,1--C2 IN+>C2 IN-,0--C2 IN+<C2 IN-;当C2INV=1时,1--C2 IN+<C2 IN-,0--C2 IN+>C2 IN-。
比较器可以有8种工作模式,有寄存器CM[2:0]决定。每种模式下,比较器管脚的数据方向由寄存器TRISA控制。如果改变比较器的工作模式,输出在一定时间内无效,最大延时10us,这时应禁止比较器中断,否则可能产生假中断。
工作模式0:CM[2:0]=000。双比较器,RA0/RA1分别是比较器C1/C2的IN-输入端,RA3/RA2分别是比较器C1/C2的IN+输入端。此模式下,比较器处于复位状态,输出为0。
工作模式1:CM[2:0]=001。双比较器,三输入端,比较器C1/C2的IN+共用RA2,比较器C2的IN-来自RA1,比较器C1的IN-由CIS决定,CIS=0时RA0为比较器C1的IN-,CIS=1时RA3为比较器C1的IN-。
工作模式2:CM[2:0]=010。双比较器,使用内部参考电压Vref作为比较器C1/C2的IN+输入端,比较器C1/C2的IN-由CIS控制,当CIS=0时比较器C1/C2的IN-输入分别接RA0/RA1引脚,当CIS=1时比较器C1/C2的IN-输入端分别接RA3/RA2引脚。
工作模式3:CM[2:0]=011。双比较器,RA2引脚接比较器C1/C2的IN+输入端,RA0/RA1引脚分别接比较器C1/C2的IN-输入端。
工作模式4:CM[2:0]=100。双独立的比较器,RA0/RA3引脚分别为比较器C1的IN-/IN+输入,RA1/RA2引脚分别为比较器C2的IN-/IN+输入。
工作模式5:CM[2:0]=101。单比较器,比较器C1关闭,比较器C2的输入IN-/IN+分别接RA1/RA2引脚,RA0/RA3为GPIO。
工作模式6:CM[2:0]=110。双比较器,RA2引脚用作比较器C1/C2的IN+共同输入端,RA0/RA1引脚分别作为比较器C1/C2的IN-输入。此模式下,比较器C1/C2输出除了反映在C1OUT/C2OUT位上外,还分别通过RA3/RA4引脚输出比较器C1/C2的比较结果。RA4是开漏输出,需要接一个上拉电阻。
工作模式7:CM[2:0]=111。比较器关闭。
示例:配置比较器模块必需的步骤。配置RA3/RA4为数字输出,RA0/RA1配置为比较器的IN-,RA2配置为比较器的IN+输入。
CLRF FLAG_REG ;清标志寄存器
CLRF PORTA ;清RA口
MOVLW 0x03 ;
MOVWF CMCON ;设置比较器的模式CM[2:0]=011
BSF STATUS,RP0 ;选择寄存器区BANK1
MOVLW 0x07 ;
MOVWF TRISA ;设置RA口的输入输出
BSF PIE1,CMIE ;比较器的中断使能
BCF STATUS,RP0 ;选择寄存器区BANK0
CALL DELAY10 ;调用延时子程序
BTFSS PIR1,CMIF ;查询比较器中断
GOTO $-1 ;没有中断标志继续查询
3)参考电压模块:
参考电压模块是由一个16级梯形电阻网络组成,提供了可选择的参考电压。将梯形电阻网络分段来提供两个不同范围的Vref,并且在不需要使用参考电压时可以将其关闭以降低功耗。与参考电压相关的寄存器如表:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
9FH |
VRCON |
VRCON |
VROE |
VRR |
- |
VR3 |
VR2 |
VR1 |
VR0 |
1FH |
CMCON |
C2OUT |
C1OUT |
C2INV |
C1INV |
CIS |
CM2 |
CM1 |
CM0 |
85H |
TRISA |
TRISA7 |
TRISA6 |
TRISA5 |
TRISA4 |
TRISA3 |
TRISA2 |
TRISA1 |
TRISA0 |
VRCON是参考电压模块的控制寄存器。其中VR[3:0]为Vref值选择位,0≤VR<15,
当VRR=1时,Vref=(VR/24)x Vdd
当VRR=0时,Vref=Vdd/4 +(VR/32)x Vdd
VRR为Vref范围选择位,1--低参考电压范围,0--高参考电压范围。VROE为Vref输出使能位,1--Vref在RA2引脚输出,0--Vref断开。VREN为Vref使能位,1--Vref电路上电,0-- Vref电路断电。
由于结构上的限制,参考电压模块不能实现从Vss到Vdd的全范围输出,只能分为高低两个范围,在每个范围内均可输出16种不同的电压值。由于参考电压是由Vdd产生的,因此Vref输出会随Vdd的波动而变化。
如果因中断或WDT超时将器件从休眠模式下唤醒,VRCON寄存器内容不受影响。为了使休眠模式下的电流消耗达到最小,应关闭参考电压模块。
示例:Vdd为5.0V时获得1.25V电压输出。
MOVLW 02H ;
MOVWF CMCON ;双比较器,使用内部参考电压
BSF STATUS,5 ;选择BANK1
MOVLW 07H ;
MOVWF TRISA ;置RA[3:0]为输入状态
MOVLW A6H ;使能Vref,VRR=1,VR[3:0]=6
MOVWF VRCON ;Vref=6/24X5=1.25V
BCF STATUS,5 ;
CALL DELAY10 ;延时10us,参考电压模块改变输出时需要稳定时间
4)CCP模块:
CCP,即捕捉/比较/PWM模块,包含一个16位寄存器,可作为16位捕捉寄存器、16位比较寄存器或PWM主/从占空比寄存器。捕捉/比较使用定时/计数器1,PWM使用定时/计数器2。
与捕捉、比较和TMR1相关的寄存器:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
|||||
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
|||||
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
|||||
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
|||||
86H,186H |
TRISB |
PORTB数据方向寄存器 |
||||||||||||
0EH |
TMR1L |
16位TMR1寄存器低字节寄存器 |
||||||||||||
0FH |
TMR1H |
16位TMR1寄存器高字节寄存器 |
||||||||||||
10H |
T1CON |
- |
- |
T1CKPS1 |
T1CKPS0 |
T1OSCEN |
T1SYNC |
TMR1CS |
TMR1ON |
|||||
15H |
CCPR1L |
捕捉/比较/PWM寄存器1(LSB) |
||||||||||||
16H |
CCPR1H |
捕捉/比较/PWM寄存器2(MSB) |
||||||||||||
17H |
CCP1CON |
- |
- |
CCP1X |
CCP1Y |
CCP1M3 |
CCP1M2 |
CCP1M1 |
CCP1M0 |
CCP1CON为捕捉/比较/PWM控制寄存器。其中CCP1M[3:0]为方式选择位,0000--关闭,0100--捕捉模式(下降沿发生),0101--捕捉模式(上升沿发生),0110--捕捉模式(每4个上升沿发生),0111--捕捉模式(每16个上升沿发生),1000--比较模式(相符时置位输出位),1001 --比较模式(相符时清零输出位),1010--比较模式(相符时产生软件中断),1011--比较模式(触发特殊事件,CCP1复位TMR1),11xx--PWM模式。CCP1X/CCP1Y,捕捉/比较模式下未使用,在PWM模式下是PWM占空比的两个LSB,高位在CCPRxL中。
捕捉模式:捕捉模式下,当RB3/CCP1管脚上出现相应事件后,CCPR1H/CCPR1L能捕捉到TMR1的16位值。这些事件有4种,分别是每个下降沿、每个上升沿、每4个上升沿、每16个上升沿,通过CCP1M[3:0]来设定。当捕捉到特定事件时,中断标志位CCP1IF被置位,此标志位可由软件来清除。如果CCPR1寄存器被读之前又产生另一个捕捉事件,旧捕捉值将丢失。
在捕捉模式下,应通过置位TRISB[3]位将RB3/CCP1引脚配置为输入。(如果RB3/CCP1引脚配置为输出,那么对该端口的写操作可能引发一个捕捉事件。)要使CCP模块使用捕捉功能,TMR1必须工作在定时器或同步计数器模式,异步计数器模式下可能无法进行捕捉。
当捕捉模式改变时,可能会产生错误的捕捉中断。用户应该保持CCP1IE位为零以避免产生错误中断,而且应该在工作模式发生任何改变之后清零标志位CCP1IF。
通过设置CCP1M[3:0]可以选择4种预分频比。只要CCP模块被关闭或者CCP模块不工作在捕捉模式,就将预分频器的计数器清零,这就意味着任何复位都可以将预分频器计数器清零。从一个捕捉预分频比切换到另一个捕捉预分频比可能产生中断,而且不会将预分频器的计数器清零,因此第1个捕捉可能是从一个非零的预分频比开始的。
示例:切换捕捉预分频比建议的方法,可使预分频器的计数器清零且不会产生错误中断。
CLRF CCP1CON ;清除捕捉/比较/PWM模式控制寄存器
MOVLW NEW_CAPT_PS ;送常数
MOVWF CCP1CON ;重设捕捉/比较/PWM模式控制寄存器
比较模式:比较模式下,始终用16位CCPR1寄存器的值与TMR1寄存器的值相比较,当二者相符时,RB3/CCP1将根据CCP1M[3:0]的设置输出高电平/低电平或保持不变,同时中断标志位CCP1IF置位。
用户必须通过清零TRISB[3]位将RB3/CCP1引脚配置为输出。清零CCP1CON寄存器将强制RB3/CCP1比较输出锁存到缺省低电平。CCP使用比较模式,TMR1也必须工作在定时器或同步计数器模式,在异步计数器模式下可能无法进行比较操作。
CCP1M[3:0]=1010,比较符合不会引起CCP1引脚上电平的变化,只会产生CCP中断。CCP1M [3:0]=1011,比较符合将产生一个内部硬件触发信号引起TMR1寄存器的复位,使CCPR1寄存器有效地成为TMR1的16位可编程周期寄存器。当TMR1H/TMR1L寄存器与CCPR1H/CCPR1L寄存器相符时,CCP立即产生特殊事件触发输出,直到TMR1时钟的下一个上升沿,TMR1H/ TMR1L寄存器才被复位,这使CCPR1寄存器实际上等同于TMR1的16位周期控制寄存器。如果使能了A/D模块,特殊事件触发还可以启动A/D转换。
PWM模式:在脉宽调制模式下,CCP1引脚产生的PWM输出可达10位分辨率。由于CCP1引脚与PORTB数据锁存器复用,必须清零TRISB[3]位,将CCP1引脚作为输出引脚。一个PWM输出由一个时基(周期)和一段输出保持高电平的时间(占空比)确定。
与PWM和TMR2相关的寄存器如表:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
||||
0BH,8BH,10BH,18BH |
INTCON |
GIE |
PEIE |
T0IE |
INTE |
RBIE |
T0IF |
INTF |
RBIF |
||||
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXIF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
||||
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXIE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
||||
86H,186H |
TRISB |
PORTB数据方向寄存器 |
|||||||||||
11H |
TMR2 |
TMR2模块寄存器 |
|||||||||||
92H |
PR2 |
TMR2模块设定寄存器 |
|||||||||||
12H |
T2CON |
- |
TOUTPS3~TOUTPS0 |
TMR2ON |
T2CKPS1 |
T2CKPS0 |
|||||||
15H |
CCPR1L |
捕捉/比较/PWM寄存器1(LSB) |
|||||||||||
16H |
CCPR1H |
捕捉/比较/PWM寄存器2(MSB) |
|||||||||||
17H |
CCP1CON |
- |
- |
CCP1X |
CCP1Y |
CCP1M3 |
CCP1M2 |
CCP1M1 |
CCP1M0 |
PWM周期可以通过写PR2寄存器来指定,计算公式为:
PWM周期=[(PR2)+1]×4×Tosc×TMR2预分频值 (频率为周期的倒数)
当TMR2等于PR2时,在下一个递增计数周期中引起3个事件:TMR2清零,CCP1引脚置位(如果占空比为0%则不置位),PWM占空比从CCPR1L锁存到CCPR1H。
PWM占空比可通过写CCPR1L寄存器和CCP1CON[5:4]位来确定,最高分辨率可达10位,其中高8位包含在CCPR1L中,而低2位是CCP1CON[5:4]。计算占空比公式为:
PWM占空比=(CCPR1L:CCP1CON[D5:D4])×Tosc×(TMR2预分频器)
可以在任何时候写入CCPR1L和CCP1CON[5:4],直到PR2和TMR2中的值相符(即当周期结束时),占空比的值才被锁存到CCPR1H。在PWM模式下,CCPR1H是只读寄存器。
PWM输出的配置步骤:通过写PR2寄存器设置PWM周期,通过写CCPR1L寄存器和CCP1CON [5:4]位来设置PWM占空比,通过清零TRISB[3]位将CCP1引脚配置为输出,通过写T2CON设置TMR2预分频比并使能TMR2。20MHz时PWM频率与分辨率示例如表:
PWM频率 |
1.22kHz |
4.88kHz |
19.53kHz |
78.12kHz |
156.3kHz |
208.3kHz |
定时器预分频比(1,4,16) |
16 |
4 |
1 |
1 |
1 |
1 |
PR2值 |
0xFF |
0xFF |
0xFF |
0x3F |
0x1F |
0x17 |
最大分辨率(位) |
10 |
1 |
1 |
8 |
7 |
6 |
注:TMR2后分频器对于确定PWM频率不起作用,但可以利用后分频器来产生频率与PWM输出不同的特定波形。
5)异步收发器模块USART:
USART是一种串行通信接口,可以配置为全双工异步系统,使之能与CRT终端和个人计算机等外设进行通信,也可配置为半双工同步系统,使之能与A/D或D/A以及串行EEPROM等外设进行通信。与异步通信相关的寄存器:
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
0CH |
PIR1 |
EEIF |
CMIF |
RCIF |
TXRF |
- |
CCP1IF |
TMR2IF |
TMR1IF |
18H |
RCSTA |
SPEN |
RX9 |
SREN |
CREN |
ADEN |
FERR |
OERR |
RX9D |
19H |
TXREG |
USART发送数据寄存器 |
|||||||
1AH |
RCREG |
USART接收数据寄存器 |
|||||||
8CH |
PIE1 |
EEIE |
CMIE |
RCIE |
TXRE |
- |
CCP1IE |
TMR2IE |
TMR1IE |
98H |
TXSTA |
CSRC |
TX9 |
TXEN |
SYNC |
- |
BRGH |
TRMT |
TX9D |
99H |
SPBRG |
波特率发生器寄存器 |
TXSTA为发送状态寄存器。CSRC为时钟源选择位,1--主模式(内部BRG产生时钟信号),0--从模式(外部时钟源提供时钟),异步模式时忽略。TX9,9位发送使能位,1--选择9位发送,0--选择8位发送。TXEN为发送使能位,1--使能发送,0--禁止发送。SYNC是模式选择位,1--同步模式,0--异步模式。BRGH为高速波特率选择位,1--高速,0--低速,异步模式时使用,同步模式未使用。TRMT为发送移位寄存器状态位,1--TSR空,0--TSR满。TX9D为发送数据的第9位(可作为奇偶校验位)。
RCSTA为接收状态寄存器。SPEN为串行端口使能位,1--使能串行端口,0--禁止串行端口。RX9,9位接收使能位,1--选择9位接收,0--选择8位接收。SREN为单字节接收使能位,1--使能单字节接收,0--禁止单字节接收,同步主模式时使用,接收完成后清零,异步模式时忽略。CREN为连续接收使能位,异步模式下,1--允许连续接收,0--禁止连续接收;异步模式时,1--使能连续接收直到CREN使能位被清零(比SREN优先级高),0--禁止连续接收。ADEN为地址检测使能位,9位同步模式时,1--使能地址检测(R[8]置位时允许中断并装入接收缓冲器),0--禁止地址检测(已接收所有字节,第9位可作为奇偶检验位),8位异步模式时未用,同步模式时未用。FERR为帧错误标志位,1--帧错误(读RCREG寄存器可更新该位并可接收下一个有效字节),0--无帧错误。OERR为溢出错误标志位,1--有溢出错误(清零CREN位可将此位清零),0--无溢出错误。RX9D为接收数据的第9位(可作为奇偶校验位)。
要把RB2/TX/CK和RB1/RX/DT引脚配置为USART使用,必须置位SPEN(RCSTA[7]和TRISB[2:1])。
异步模式下,USART使用标准的非归零码NRZ格式(1个起始位,8个或9个数据位,1个停止位),最常用的数据格式为8位,首先发送和接收LSB。USART的发生器和接收器在功能上是独立的,但采用相同的数据格式和波特率。USART硬件不支持奇偶校验,但可由软件实现。休眠模式下,异步模式会停止工作。通过清零SYNC(TXSTA[4])选择异步工作模式。
异步发送器的核心是发送移位寄存器TSR,移位寄存器从读/写发送缓冲器TXREG中获取数据,TXREG寄存器要用软件装入数据。在前一次装入数据的停止位发送完成前,不会向TSR寄存器装入数据,一旦停止位发送完毕,TSR就会自动装入TXREG中的新数据(如果TXREG中有数据)。一旦TXREG寄存器向TSR寄存器传输完数据,TXREG就为空,同时标志位TXIF置位,可以通过置位或清零TXIE来使能或禁止中断。不管使能位TXIE的状态如何,标志位TXIF都将置位,且无法用软件清零,只有向TXREG装入新数据才能复位。标志位TXIF表示TXREG寄存器的状态,TRMT(TXSTA[1])则表示TSR寄存器的状态。TRMT是只读位,当TSR寄存器为空时该位置位,因为没有与此位相关的中断逻辑,用户必须查询此位以判断TSR寄存器是否为空。用户不能访问TSR寄存器。当TXEN置位时,TXIF置位。
配置异步发送模式时的步骤:TRISB[1]置位,TRISB[2]清零,将引脚RB1/RX/DT设为输入,将RB2/TX/CK设为输出;用正确的波特率初始化SPBRG寄存器,如果需要高速波特率,应将BRGH置位;通过将SYNC位清零并将SPEN置位,使能异步串行口;如果需要中断,应置位TXIF;如果需要发送9位数据,应置位TX9;通过将TXEN置位使能发送,此操作同时也会将TXIF位置位;如果选择发送9位数据,应将第9位数据装入TX9D位;将数据装入TXREG寄存器并开始发送。
选择异步模式后,将CREN置位,将使能接收。接收器的核心部件是接收寄存器RSR。当采样到停止位后,RSR中接收到的数据被送到RCREG寄存器(如果RCREG为空)。发送完成后,标志位RCIF会置位,通过置位RCIE(PIEI[5])可以允许中断,只读位RCIF由硬件清零。在RCREG寄存器内的数据已被读走或RCREG寄存器为空时,RCIF会被硬件清零。RCREG是双缓冲寄存器(两级深度的FIFO),因此可以在读走数据之前让系统接收两个字节的数据并传送到RCREG FIFO,然后第三字节开始移位到RSR寄存器。但在检测到第三字节的停止位后,如果RCREG寄存器仍然是满的,则溢出错误标志位OERR会置位RSR寄存器中的数据将会丢失。
通过读两次RCREG寄存器来获得FIFO中的两个字节。溢出标志位OERR必须用软件清零,这可以通过复位接收逻辑(将CREN位清零后再置位)实现。如果OERR位被置位,则禁止将RSR寄存器中的数据传送到RCREG寄存器,因此如果OERR位已置位,则必须将它清零。如果检测到停止位为零,则帧出错标志位FERR将被置位。FERR位和接收到的第9位以与接收数据相同的方式被缓冲。读RCREG会将新值装入RX9D和FERR位,因此为了避免丢失RX9D和FERR位的原值,用户必须在读RCREG寄存器前读RCSTA寄存器。
配置异步接收模式时的步骤:TRISB[1]置位,TRISB[2]清零,将引脚RB1/RX/DT设为输入,将RB2/TX/CK设为输出;用正确的波特率初始化SPBRG寄存器,如果需要高速波特率,应将BRGH置位;通过将SYNC位清零并将SPEN置位,使能异步串行口;如果需要中断,应置位RCIE;如果需要接收9位数据,应置位RX9;通过将CREN置位使能接收;当接收完成时,RCIF将置位,此时如果使能RCIE位将会产生一个中断;读RCSTA寄存器获取第9位数据(如果使能),并判断在接收操作中是否发生错误;通过读RCREG寄存器来读取接收到的8位数据;如果发生错误,通过将使能位CREN清零以清除错误。
波特率发生器BRG:BRG是一个专用的8位波特率发生器,支持USART的同步模式和异步模式,用SPBRG寄存器控制周期,异步模式下BRGH(TXSTA[2])位也用于控制波特率。
SYNC |
BRGH=0(低速) |
BRGH=1(高速) |
0 |
(异步)波特率=Fosc/[64(X+1)] |
波特率=Fosc/[16(X+1)] |
1 |
(同步)波特率=Fosc/[4(X+1)] |
NA |
向SPBRG寄存器写入一个新值将导致BRG定时器复位(或清零),这可以确保BRG不必等待定时器溢出再输出新波特率。
示例:波特率误差的计算方法:工作条件Fosc=16MHz,目标波特率9600,异步,低速
根据公式:波特率=Fosc/[64(X+1)],即 9600=16000000/[64(X+1)],得X=25.042≈25
计算波特率=16000000/[64(25+1)]=9615
误差=(计算波特率-目标波特率)/目标波特率=(9615-9600)/9600=0.16%
对于低波特率时钟,使用高波特率公式,在某些情况下会降低波特率误差。
6)A/D转换模块:
PIC16F873系列单片机具有A/D转换功能,有5~8个模拟输入通道。模拟输入对一个采样保持电容器充电,其输出是A/D转换器的输入。A/D转换器采用逐次逼近法将这一模拟电平产生数字转换结果,转换结果为10位。A/D转换能够在休眠方式下工作,这时的转换时钟必须来源于A/D转换器内部的RC振荡器。模拟参考电压(正电源电压和负电源电压)可通过软件选择为器件的电源电压或AN3/Vref+和AN2/Vref-引脚上的电平。
地址 |
名称 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
1EH |
ADRESH |
A/D转换结果寄存器高位 |
|||||||
9EH |
ADRESL |
A/D转换结果寄存器低位 |
|||||||
1FH |
ADCON0 |
ADCS1 |
ADCS0 |
CHS2 |
CHS1 |
CHS0 |
GO/DONE |
- |
ADON |
9FH |
ADCON1 |
ADFM |
- |
- |
- |
PCFG3 |
PCFG2 |
PCFG1 |
PCHG0 |
ADCON0是A/D控制寄存器0,控制/D模块的操作。ADCS1/0为时钟选择位,00--采样率Fosc/2,01--采样率Fosc/8,10--采样率Fosc/32,11--采样率Frc(来自A/D模块内部RC振荡器)。CHS[2:0]是模拟通道选择位,000--通道0(RA0/AN0),001--通道1(RA1/AN1),......,100--通道4(RA5/AN4),101--通道5(RE0/AN5),110--通道6(RE1/AN6),111--通道7(RE2/AN7)。GO/DONE为转换状态位,当ADON=1时,1--转换正在进行(该位置位启动转换,转换结束后硬件自动清零),0--未进行A/D转换。ADON为A/D转换开启位,1--转换器工作,0--转换器关闭。
ADCON1是A/D控制寄存器1,对端口的引脚功能进行配置。ADFM为A/D转换结果对齐格式选择,1--右对齐(ADRESH寄存器的高6位读为0),0--左对齐(ADRESL寄存器的低6位读为0)。PCFG[3:0]为端口配置控制位,见下表:
PCFG[3:0] |
AN7 |
AN6 |
AN5 |
AN4 |
AN3 |
AN2 |
AN1 |
AN0 |
Vref+ |
Vref- |
0000 |
A |
A |
A |
A |
A |
A |
A |
A |
Vdd |
Vss |
0001 |
A |
A |
A |
A |
Vref+ |
A |
A |
A |
AN3 |
Vss |
0010 |
D |
D |
D |
A |
A |
A |
A |
A |
Vdd |
Vss |
0011 |
D |
D |
D |
A |
Vref+ |
A |
A |
A |
AN3 |
Vss |
0100 |
D |
D |
D |
D |
A |
D |
A |
A |
Vdd |
Vss |
0101 |
D |
D |
D |
D |
Vref+ |
D |
A |
A |
AN3 |
Vss |
011X |
D |
D |
D |
D |
D |
D |
D |
D |
- |
- |
1000 |
A |
A |
A |
A |
Vref+ |
Vref- |
A |
A |
AN3 |
AN2 |
1001 |
D |
D |
A |
A |
A |
A |
A |
A |
Vdd |
Vss |
1010 |
D |
D |
A |
A |
Vref+ |
Vref- |
A |
A |
AN3 |
Vss |
1011 |
D |
D |
D |
A |
Vref+ |
Vref- |
A |
A |
AN3 |
AN2 |
1100 |
D |
D |
D |
A |
Vref+ |
Vref- |
A |
A |
AN3 |
AN2 |
1101 |
D |
D |
D |
D |
Vref+ |
Vref- |
A |
A |
AN3 |
AN2 |
1110 |
D |
D |
D |
D |
D |
D |
D |
A |
Vdd |
Vss |
1111 |
D |
D |
D |
D |
Vref+ |
Vref- |
D |
A |
AN3 |
AN2 |
表中,A表示模拟输入模式,D表示数字I/O模式。(部分芯片没有后3个通道)
当A/D转换完成后,10位的转换结果存于ADRESH/ADRESL寄存器中,GO/DONE被自动清零,同时中断标志位ADIF(RIR1[6])被自动置1。A/D转换结果寄存器ADRESH/ADRESL是16位宽,模块提供了左对齐或右对齐的方式存放10位转换结果,多余位填入0。当A/D被禁止时,这两个寄存器可用作两个通用的8位寄存器。
A/D转换配置使用的步骤:模拟量的相应引脚设置为输入,即相应TRISA寄存器的位设为1;配置ADCON1,设置模拟输入通道/参考电压/GPIO;配置ADCON0,选择输入通道/转换时钟,打开A/D模块;需要时设A/D中断,ADIF清零,ADIE置1,GIE置1;等待所需的采集时间;启动A/D转换,即将GO/DONE置1;等待A/D转换完成,查询GO/DONE位是否被清零或ADIF位被置1,设中断时等待A/D中断;读取A/D结果寄存器,需要时将ADIF位清零。
每一位A/D转换时间定义为Tad,完成一次10位A/D转换共需要11.5个Tad。A/D转换的时钟可用软件进行选择,有4种:2Tosc、8Tosc、32Tosc、A/D内部RC振荡器。为了确保A/D转换正确,A/D转换时间Tad必须不小于1.6us。
A/D模块可在休眠期间运行,这需要把A/D的时钟源设置成RC方式,然后将GO/DONE位置1,然后执行SLEEP指令,避免了转换时受到其他内部数字开关的噪声影响。A/D转换完成后,GO/DONE位清零,转换结果送入ADREG寄存器。如果A/D中断被使能,器件将从休眠中被唤醒。
示例:A/D转换初始化程序:AN0通道输入模拟量,其他为数字量通道
BSF STATUS,RP0 ;选择寄存器区BANK1
MOVVW 0FH ;
MOVW ADCON1 ;将RA0设置为模拟量,其他的为数字量
BSF PIE1,ADIE ;A/D转换的中断使能
BCF STATUS,RP0 ;选择寄存器BANK0
MOVLW 0xC1 ;
MOVWF ADCON0 ;内部时钟,A/D转换启动,选择0通道
BCF PIR1,ADIF ;清除中断标志位
BSF INTCON,PEIE ;外部中断使能
BSF INTCON,GIE ;总的中断使能
BSF ADCON0,GO ;启动A/D转换
......
INT_S
BCF PIR1,ADIF ;清除中断标志位
MOVF ADRESH,0 ;
MOVWF REG1 ;将A/D转换的高位存入REG1
MOVF ADRESL,0 ;
MOVWF REG0 ;将A/D转换的低位存入REG0
RETFIE
在转换期间将GO/DONE位清零将中止当前A/D转换,这时结果寄存器中的内容不会被部分完成的A/D转换样本所更新,仍保持上一次转换完成后的结果(或上一次写入的值)。A/D转换被中止后,在下一次采集开始前,需要等待2Tad的时间,等待2Tad之后采集将在所选通道上自动开始。由于所需采集时间的要求,不应在打开A/D模块的同一指令中将GO/DONE位置1.