第一章PIC16C5X硬件结构第一节PIC16C5X主要功能特点·采用精简指令集(RISC),仅33条指令。指令字长12位,全部指令都是单字节指令。除涉及PC值改变的指令外(如跳转指令等),其余指令都是单周期指令。·工作频率为DC~20MHZ。·系统为哈佛结构。数据总线和指令总线各自独立分开,数据总线宽度为8位,指令总线宽度为12位。·内部程序存储器(ROM)从384~2K字节不等。内部寄存器组(RAM)有25~72个。·7个特殊功能寄存器。·2级子程序堆栈。·工作电源-商用级:2.5V~6.25V-工业级:2.5V~6.25V-军工级:2.5V~6.0V·内部自振式看门狗(WDT)·低功耗模式(Sleep),耗电小于10uA。·内部复位电路·内带一个8位定时器/计数器(RTCC)·具备保密位。保密熔丝可在程序烧写时选择将其熔断,则程序不能被读出拷贝。·提供四种可选振荡方式-低成本的阻容(RC)振荡-RC-标准晶体/陶瓷振荡-XT-高速晶体/陶瓷振荡-HS-低功耗,低频晶体振荡─LP·12~20根双向可独立编程I/O口。每根I/O口都可由程序来编程决定其输入/输出方向。·低功耗2mA@5V,4MHz15uA@3V,32KHz3uA低功耗模式@3V,0°C~70°C第二节PIC16C5X型号介绍及引脚介绍PIC16C5X有五种型号,见下表:PIC16C5X管脚图如下:图1.1PIC16C5X管脚图表1.2描述了各引脚的功能:注:RTCC设置成内部定时器时(由程序设定),这时应将RTCC端接VSS或VDD,以避免干扰。采用RC振荡时,OSC2端输出一OSC1的4分频信号。第三节PIC16C5X内部结构PIC16C5X在一个芯片上集成了一个8位算术逻辑单元ALU和工作寄存器(W);384~2K的12位程序存储器(ROM);32~80个8位数据寄存器(RAM);12~20个I/O口端;8位计数器及预分频器;时钟、复位、及看门狗计数器等。内部结构如图1.2所示:图1.2PIC16C5X内部结构从图中可以看到,PIC16C5X有个特点,就是把数据存储器RAM当作寄存器来寻址使用以方便编程。寄存器组按功能分成二部分,即特殊寄存器组和通用寄存器组。特殊寄存器组包括实时时钟计数器RTCC,程序计数器PC,状态寄存器Status,I/O口寄存器以及存储体选择寄存器FSR。这些寄存器稍后我们还要详细论述。PIC总线结构采取数据线(8位)和指令线(12位)独立分离的哈佛(Harvard)结构。这样可使单片机的指令速度得到提高。当一条指令在ALU中执行时,下一条指令已经被取出放到指令寄存器等待执行了。算术逻辑单元ALU和工作寄存器(W)承担算术逻辑操作任务。PIC16C5X提供二级堆栈(Stack),所以子程序调用只有二层。使用时一定要注意这点,否则程序运行将失去控制。第四节程序存储器及堆栈PIC16C5X内部有384~2K的只读程序存贮器,下面论述其结构和堆栈。§1.4.1程序存储器结构PIC16C5X程序存储器结构如图1.3所示:图1.2PIC16C5X内部结构从上图可看出,PIC程序存储器采用分页结构,每页长0.5K。因此对于PIC16C52程序存储器在1页之内,而对于PIC16C54和PIC15C55程序存储器容量为1页,PIC16C56和PIC16C57的容量则分别为2页和4页。页面地址由状态寄存器f3的第5位和第6位(PA0、PA1)确定。程序转移时,在本页内可直接进行;在需跨页跳转时(GOTO、CALL指令),则必须根据将要跳转去的页面,把f3中的PA0、PA1位置成相应的值。具体请参考f3寄存器描述及§2.7.2程序设计基础的程序技巧例子。§1.4.2堆栈PIC16C5X设有二层堆栈,堆栈1和堆栈2,供子程序调用。涉及堆栈操作的指令有二条。1、CALL--在主程序中第一次执行CALL指令时,将PC值加1后推入堆栈1,堆栈1原有的内容则被推入堆栈2中。这时子程序中还可再做一次子程序嵌套,即再执行一次CALL指令。如果子程序调用多于二层时,堆栈中只存放最近的二个返回地址。当执行一条CALL指令时,状态寄存器f3中的将页面寻址位PA1、PA0将被置入到PC的最高二位(第11位和第10位),而PC的第9位总是被置为0,如图1.3所示。所以这时PC值将是这意味着在PIC16C5X中,子程序起始地址只能放在每个程序存储页面的上半页,即低地址的那一半(000-0FF、200-2FF、400-4FF、600-6FF)。注意,这里指的是子程序的起始地址,即子程序头。而子程序体是可以延伸到下半页去的。对于PIC16C56和PIC16C57,由于程序空间分别为1K和2K,可能存在跨页面子程序调用。所以调用子程序前必须先把f3中的PA0、PA1设置成该子程序所在的页面地址。返回后再将其恢复成当前的页面值。当然如果这时子程序是在同一页面,则可省去这一过程。2、RETLW--该指令把栈顶(堆栈1)的值写入PC,同时还把堆栈2的值拷贝到堆栈1去。子程序总是返回到调用它时所在的地方,不管它是处在什么页面,也不管f3寄存器中的PA0、PA1这时是指在什么页面。但是执行RETLW(子程序返回)指令并不会改变f3中PA0、PA1的值,所以当你从一次跨页面的子程序调用返回时,不要忘了恢复f3中的原先的PA0和PA1值。请参考上面关于CALL指令的叙述。由于堆栈和PC的宽度是相同的,所以你可以在程序的任何地方执行一条CALL指令来调用子程序。但是对于跨页面的调用,你要小心处理f3中的页面地址位PA0和PA1,请参考第二章指令详解中的CALL实例。第五节数据存储器PIC16C5X把数据存储器RAM都当作寄存器来使用以使寻址简单明洁,它们功能上可分为操作寄存器、I/O寄存器、通用寄存器和特殊功用寄存器。它们的组织结构如图1.4所示:这些寄存器用代号F0~F79来表示。F0~F4是操作寄存器,F5-F7是I/O寄存器,其余为通用寄存器。特殊功用寄存器地址对用户不透明。§1.5.1操作寄存器1、F0间址寄存器寻址F0实际上意味着间址寻址。实际地址为寄存器选择寄存器F4的内容。例:MOVLW10MOVWFf4;10→f4MOVLW55MOVWFf0;55→f102、F1实时时钟/计数寄存器(RTCC)此寄存器是一个8位计数器。和其他寄存器一样可由程序进行读写操作。它用于对外加在RTCC引脚上的脉冲计数,或对内部时钟计数(起定时器作用)。图1.5RTCC方块图上图中可看出RTCC工作状态由OPTION寄存器控制(参见§1.5.4),其中OPTION寄存器的RTS位用来选择RTCC的计数信号源,当RTS为1时,信号源为内部时钟,RTS为0时,信号源为来自RTCC引脚的外部信号。OPTION寄存器的PSA位控制预分频器(Prescaler)分配对象,当PSA位为1,8位可编程预分配给RTCC,即外部或内部信号经过预分频器分频后再输出给RTCC。预分频器的分频比率由OPTION内的PS0~PS2决定。这时涉及写f1(RTCC)寄存器的指令均同时将预分频器清零。但要注意OPTION寄存器内容仍保持不变,即分配对象、分频比率等均不变。OPTION的RTE位用于选择外部计数脉冲触发沿。当RTE为1时为下降沿触发,为0时为上升沿触发。RTCC计数器采用递增方式计数,当计数至FFH时,在下一个计数发生后,将自动复零,重新开始计数,以此一直循环下去。RTCC对其输入脉冲信号的响应延迟时间为2个机器周期,不论输入脉冲是内部时钟、外部信号或是预分频器的输出。响应时序见图1.6。RTCC对外部信号的采样周期为2个振荡周期。因此当不用预分频器时,外加在RTCC引脚上的脉冲宽度不得小于2个振荡周期,即1/2指令周期。同理,当使用预分频器时,预分频器的输出脉冲周期不得小于指令周期,因此预分频器最大输入频率可达N.fosc/4,N为预分频器的分频比,但不得大于50MHZ。当RTCC使用内部时钟信号时,如果没有预分频器,则RTCC值随指令节拍增1。当一个值写入RTCC时,接下来的二个指令节拍RTCC的值不会改变,从第三个指令节拍才开始递增,见下图。图1.6ARTCC时序图:内部时钟/无预分频器图1.6BRTCC时序图:内部时钟/预分频比1:2应注意的是尽管PIC对外部加于RTCC信号端上的信号宽度没有很严格的要求,但是如果高电平或低电平的维持时间太短,也有可能使RTCC检测不到这个信号。一般要求信号宽度要大于是10nS。3、F2程序计数器(PC)程序计数器PC可寻址最多2K的程序存储器。表1.3列出了PIC16C5X各种型号的PC长度和堆栈的长度。表1.3PC及堆栈的宽度单片机一复位(RESET),F2的值全置为1。除非执行地址跳转指令,否则当执行一条指令后,F2(PC)值会动加1指向下一条指令。下面这些指令可能改变PC的值:a、GOTO指令。它可以直接写(改变)PC的低9位。对于PIC16C56/57/58,状态寄存器F3的PA1、PAO两位将置入PC的最高二位。所示GOTO指令可以跳转到程序存储器的任何地方。b、CALL指令。它可以直接写PC低8位,同时将PC的第9位清零。对于PIC16C56/57/58,状态寄存器F3的PA1、PAO两位将置入PC的最高二位(第10、11位)。c、RETLW指令。它把栈项(堆栈1)的值写入PC。d、MOVWFF2指令。它把W寄存器的内容置入PC。e、ADDWFF2指令。它把PC值加1后再和W寄存器的值相加,结果写入PC。在以上b、d和e中,PC的第9位总是被清为零。所以用这三条指令来产生程序跳转时,要把子程序或分支程序放在每页的上部地址(分别为000-0FF、200-2FF、400-4FF、600-6FF)。4、F3状态寄存器(STATUS)如图1.7所示F3包含了ALU的算术状态、RESET状态、程序存储器页面地址等。F3中除PD和TO两位外,其他的位都可由指令来设置或清零。注意,当你执行一条欲改变F3寄存器的指令后,F3中的情况可能出乎你的意料。例:CLRFF3;清F3为零你得到的结果是F3=000UU100(U为未变)而不是想像中的全零。UU两位是PD和TO,它们维持不变,而2位由于清零操作被置成1。所以如果你要想改变F3的内容,建议你使用BCF、BSF和MOVWF这三条指令,因为它们的执行不影响其他状态位。例:MOVLW0;0→WMOVWFF3;把F3除PD和TO以外的位全部清零,则你可得到F3=000UU000。有关各条指令对状态位的影响请看第二章介绍。在加法运算(ADDWF)时,C是进位位。在减法运算(SUBWF)时,C是借位的反(Borrow)。例:CLRFF10;F10=0MOVLW1;1→WSUBWFF10;F10-W=0-1=FFH→F10C=0:运算结果为负例:MOVLW1;1→WMOVWFF10;F10=1CLRW;W=0SUBWFF10;F10-W=1-0=1→F10C=1:运算结果为正PD和TO两位可用来判断RESET的原因。例如判断RESET是由芯片上电引起的,或是由看门狗WDT计时溢出引起的,或是复位端加低电平引起的,或是由WDT唤醒SLEEP引起的。表1.4列出了影响TO、PD位的事件。表1.5列出了在各种RESET后的TO、PD位状态。判断RESET从何处引起有时是很必要的。例如在对系统初始化时,经常需判断这次复位是否是上电引起的。如果不是上电复位,则不再进行初始化。页面选择位PA1、PA0的作用前面已描述过,RESET时清PA0-PA2位为零,所以复位后程序区页面自动选择在0页。5、F4寄存器选择寄存器(FSR)a、PIC16C52/54/55/56F4的0-4位在间接寻址中用来选择32个数据寄存器。5-7位为只读位,并恒为1。请参考F0寄存器描述。b、PIC16C57/58FSR6:5位用来选择当前数据寄存器体(Bank)。PIC16C57有80个数据寄存器,如图1.4所示。80个寄存器分为4个体(Bank0~Ban