
PICCC语言基础和特点.ppt
114页► Down◄ Up◙MainReturn*► Down◄ Up◙MainReturn◆基于 PICC 编译环境编写 PIC 单片机C 程序的基本方式和标准 C 程序类似,程 序一般由以下几个主要部分组成: ★在程序的最前面用#include 预处理指令 引用包含头文件,其中必须包含一个编 译器提供的“pic.h”文件,实现单片机内 特殊寄存器和其它特殊符号的声明;2.1 PIC2.1 PIC单片机的单片机的C C语言源程序基本框架语言源程序基本框架 *► Down◄ Up◙MainReturn★用“_ _CONFIG”预处理指令定义芯片 的配置位; ★声明本模块内被调用的所有函数的类 型,PICC 将对所调用的函数进行严格 的类型匹配检查; ★定义全局变量或符号替换; ★实现函数(子程序),特别注意 main 函数必须是一个没有返回的死循环► Down◄ Up◙MainReturn下面的例子为一个C源程序的范例: #include //包含单片机内部资源预定义 #include “pc68.h” //包含自定义头文件 _ _CONFIG (HS //定义芯片工作时的配置位 *► Down◄ Up◙MainReturnvoid SetSFR(void); void Clock(void); void KeyScan(void); void Measure(void); void LCD_Test(void); void LCD_Disp(unsigned char);//声明本模块中所调用的函数类型 *► Down◄ Up◙MainReturnunsigned char second, minute, hour; bit flag1,flag2; //定义变量 void main(void) //函数和子程序 {SetSFR( ); PORTC = 0x00; TMR1H += TMR1H_CONST; LED1 = LED_OFF; LCD_Test( );*► Down◄ Up◙MainReturnwhile(1) { asm(“clrwdt”); //清看门狗 Clock(); //更新时钟 KeyScan(); //扫描键盘 Measure(); //数据测量 SetSFR(); //刷新特殊功能寄存器 } } / /程序工作主循环*► Down◄ Up◙MainReturn※※注意注意::★PICC不支持C++,这对于习惯了C++ 的同学还得翻翻C 语言的书。
★我们在源程序一开始使用了“#include”实 现了相关单片机的一些预定义符号的直 接引用,但没有具体指明是哪一个型号 ► Down◄ Up◙MainReturn★实际上,“pic.h”头文件是很多头文件的 集合,是一个简单的管理工具(条件判 别),它会按照MPLAB-IDE所选择的特 定型号的单片机,把真正对应的头文件 包含进来 ★也就是说:C 编译器在pic.h 中根据你的 芯片自动载入相应的其它头文件,这点 比汇编好用► Down◄ Up◙MainReturn调用真正头文件调用真正头文件头文件 用记事本打开*► Down◄ Up◙MainReturn★载入的头文件中其实是声明芯片的寄存 器和一些函数,摘抄一个片段:例如:◆static volatile unsigned char TMR0 @ 0x01; ◆static volatile unsigned char PCL @ 0x02; ◆static volatile unsigned char STATUS @ 0x03; *► Down◄ Up◙MainReturn★可以看出和汇编的头文件中定义寄存器 是差不多的如下: ◆TMR0 EQU 0X01; ◆PCL EQU 0X02; ◆STATUS EQU 0X03; ★都是把无聊的地址定义为大家公认的名 字。
► Down◄ Up◙MainReturn2.2.1 PICC 中的基本变量类型 ◆PICC编辑器支持基本的1,2及4B数 据所有多字节数据遵循Little-endian 标准,多字节变量的低字节放在存储 空间的低地址,高字节放在高地址 ◆下表中列出了PICC支持的数据类型及 对应的大小和数学表达:2.2 PICC2.2 PICC中的变量定义中的变量定义*► Down◄ Up◙MainReturn★Little-endian和Big-endian是表示计算机字 节顺序的两种格式★简单的说,Little-endian把低字节存放在 内存的低位;而Big-endian将低字节存放 在内存的高位★现在主流的CPU,Intel系列的是采用的 Little-endian的格式存放数据,而Motorola 系列的CPU采用的是Big-endian *► Down◄ Up◙MainReturn表2-1 PICC 的基本变量类型*► Down◄ Up◙MainReturn2.2.2 PICC 中的高级变量 ◆基于表2-1的基本变量,除了bit型位变量 外,PICC 完全支持数组、结构和联合等 复合型高级变量,这和标准的C语言所支 持的高级变量类型没有什么区别。
◆例如:联合:union int_Byte { unsigned char c[2]; unsigned int i; } ;*► Down◄ Up◙MainReturn数组:unsigned int data[10];结构:struct commInData { unsigned char inBuff[8]; unsigned char getPtr, putPtr; } ; *► Down◄ Up◙MainReturn◆为了使编译器产生最高效的机器码, PICC把单片机中数据寄存器的bank问 题交由编程员自己管理,因此在定义用 户变量时你必须自己决定这些变量具体 放在哪一个bank中2.2.3 2.2.3 PICCPICC对数据寄存器对数据寄存器bankbank的管理的管理 *► Down◄ Up◙MainReturn◆如果没有特别指明,所定义的变量将 被定位在bank0,例如下面所定义的这些变量:◆unsigned char buffer[32];◆bit flag1,flag2; ◆float val[8]; *► Down◄ Up◙MainReturn◆除了bank0内的变量声明时不需特殊处 理外,定义在其它bank内的变量前面必 须加上相应的bank序号,例如: ◆bank1 unsigned char buffer[32]; //变量定位在bank1中 ◆bank2 bit flag1,flag2; //变量定位在bank2中 ◆bank3 bit float val[8]; //变量定位在bank3中 *► Down◄ Up◙MainReturn※※注意事项:注意事项:★中档系列PIC单片机数据寄存器的一个 bank大小为128字节,刨去前面若干字节 的特殊功能寄存器区域,在C语言中某一 bank内定义的变量字节总数不能超过可 用RAM字节数。
★如果超过bank容量,在最后链接时会报 错,大致信息如下:*► Down◄ Up◙MainReturn*► Down◄ Up◙MainReturn★Error[000] : Can't find 0x12C words for psect rbss_1 in segment BANK1 ★链接器告诉你总共有0x12C(300)个字 节准备放到bank1中但bank1容量不够 显然,只有把一部分原本定位在bank1 中的变量改放到其它bank中才能解决此 问题 *► Down◄ Up◙MainReturn◆虽然变量所在的bank定位必须由编程 员自己决定,但在编写源程序时进行变 量存取操作前无需再特意编写设定bank 的指令,C编译器会根据所操作的对象 自动生成对应bank设定的汇编指令;◆为避免频繁的bank切换以提高代码效 率,尽量把实现同一任务的变量定位在 同一个bank内;*► Down◄ Up◙MainReturn数据寄存器怎么附值?数据寄存器怎么附值?◆如对 TMR0 附值,汇编中:◆MOVLW 200;◆MOVWF TMR0;◆当然得保证当前bank在0或2,不然会出 错(如在bank1或3)。
► Down◄ Up◙MainReturn◆C语言中:◆TMR0=200;◆无论在任何bank都不会出错,可以看出 来C是很直接了当的并且最大好处是操 作一个寄存器时候,不用考虑bank的问 题,一切由C编译器自动完成► Down◄ Up◙MainReturn2.2.4 PICC 2.2.4 PICC 中的局部变量中的局部变量◆PICC把所有函数内部定义的auto型局 部变量放在bank0为节约宝贵的存储 空间,它采用了一种被叫做“静态覆盖” 的技术来实现局部变量的地址分配► Down◄ Up◙MainReturn◆其大致的原理是:在编译器编译源代码时扫描整个程序中函数调用的嵌套 关系和层次,算出每个函数中的局部 变量字节数;◆然后为每个局部变量分配一个固定的地址,且按调用嵌套的层次关系各变 量的地址可以相互重叠► Down◄ Up◙MainReturn◆利用这一技术后所有的动态局部变量都 可以按已知的固定地址进行直接寻址, 但这时不能出现函数递归调用PICC在 编译时会严格检查递归调用问题并认为 这是一个严重错误而立即终止编译过程 ◆所有的局部变量将占用bank0的存储空 间,因此用户自己定位在bank0内的变 量字节数将受到一定的限制,在实际使 用时需注意。
► Down◄ Up◙MainReturn2.2.5 PICC2.2.5 PICC中的位变量中的位变量◆ bit型位变量只能是全局的或静态的◆PICC将把定位在同一bank内的8个位变 量合并成一个字节存放于一个固定地址 ◆PIC单片机的位操作指令是非常高效的 因此,PICC在编译源代码时只要有可能 ,对普通变量的操作也将以最简单的位操 作指令来实现► Down◄ Up◙MainReturn◆假设一个字节变量tmp最后被定位在 地址 0x20,那么:◆tmp∣=0x80 =>bsf 0x20,7◆tmp unsigned b1: 1; unsigned b2: 1; unsigned b3: 1; unsigned b4: 1; unsigned b5: 1; unsigned : 2; //最高两位保留 } oneBit; unsigned char allBits; } myFlag; *► Down◄ Up◙MainReturn◆需要存取其中某一位时可以: myFlag.oneBit.b3=1; //b3 位置 1 ◆一次性将全部位清零时可以 : myFlag.allBits=0; //全部位变量清 0 *► Down◄ Up◙MainReturn如何进行位操作?如何进行位操作?◆汇编中的位操作是很容易的。
在PICC 中更简单C的头文件中已经对所有可 能需要位操作的寄存器的每一位都有定 义名称: ◆如:PORTA的每一个I/O口定义为: RA0、RA1、RA2、RA3、RA4、 RA5 、RA6 、RA7 ► Down◄ Up◙MainReturn◆可以对其直接进行运算和附值如:RA0=0;RA2=1;◆在汇编中是:BCF PORTA,0;BSF PORTA,2;◆可以看出两者是大同小异的,只是C中 不需要考虑bank的问题► Down◄ Up◙MainReturn◆PICC中描述浮点数是以IEEE-754标准 格式实现的此标准下定义的浮点数为 32位长,在单片机中要用4个字节存储 ◆为了节约单片机的数据空间和程序空 间,PICC专门提供了一种长。
