使用C语言开发单片机系统软件的最大优点是代码编写效率高、软件调试直观、维护和升级方便、代码复用率高。 因此,C语言编程越来越多地应用于微控制器系统设计中。 PIC单片机的软件开发也可以用C语言来实现。
Microchip尚未开发出自己的用于PIC单片机的C语言编译器,但其他公司已经开发了许多支持PIC单片机的C语言编译器。 常见的有Hitech、CCS、IAR、Bytecraft等公司。 最常用的是Hitech的PICC编译器。 稳定可靠,编译生成的代码效率高。 它受到使用 PIC 微控制器的开发人员的广泛认可。
Hitech-PICC编译器基本符合ANSI C标准,但不支持函数的递归调用。 主要原因是由于PIC单片机特殊的堆栈结构。 PIC单片机的堆栈是用硬件实现的,其深度与芯片固定,无法实现需要大量堆栈操作的递归算法。 生成的代码非常高效,并得到了使用 PIC 微控制器的开发人员的广泛认可。
2.在MpLab中配置PIC C编译环境并进行项目开发
为了方便PICC编译器的编译环境设置,首先应在MPLAB IDE集成开发环境中创建PICC C编译器工程。
1. 启动MPLAB IDE7.00集成开发环境窗口。 在集成开发环境中选择Project->New菜单项,打开如下所示的新建工程对话框,在此对话框中设置工程名称和工程路径。
在项目名称文本框中输入项目名称led,在项目路径文本框中输入项目路径D:led,或者单击浏览按钮选择项目名称的保存路径。
2、设备选择,操作流程如下。 首先打开MPLAB集成开发环境中的Configure菜单,然后点击Select Device菜单项,弹出如下图所示的器件选择对话框。 这里可以选择PICl6F877A作为开发芯片。
3. 设置项目
创建工程并选择设备后,就可以设置工程的编译环境了。 首先,设置语言组件。
在Active Toolsuite下拉列表框中选择HI-TECH PICC Toolsuite作为开发工具组件,然后在Toolsuite Contents列表框中选择PICCCompiler项,如下图所示。
3. PICC 的基本编程 3.1 PICC 中的基本变量类型
PICC支持的基本变量类型如下表所示:
3.2 PICC 中的高级变量
基于上表的基本变量,除了位类型的位变量外,PICC全面支持数组、结构体、联合体等复杂的高级变量,与标准C语言支持的高级变量类型没有什么区别。 例如:
大批:
unsigned int data[10];
结构:
struct commInData {
unsigned char inBuff[8];
unsigned char getPtr, putPtr;
};
财团:
union int_Byte {
unsigned char c[2];
unsigned int i;
};
3.3 PICC 对数据寄存器组的管理 当对PIC 单片机进行编程时,单片机数据寄存器组由编程器进行管理。 因此,在定义变量时,必须决定这些变量放在哪个bank中。默认情况下,定义的变量将位于bank0中,例如下面定义的变量:
unsigned char buffer[32];
bit flag1,flag2;
float val[8];
上述变量分布在bank0中。 在其他bank中定义的变量必须前面加上相应的bank序列号,例如:
bank1 unsigned char buffer[32]; //变量定位在bank1 中
bank2 bit flag1,flag2; //变量定位在bank2 中
bank3 float val[8]; //变量定位在bank3 中
3.4 易失性修饰符PICC中还有一个特殊的变量修饰符“易失性”,它用来表示一个变量的值会随机改变,即使程序没有故意给它赋值。
在单片机中,用作输入的IO口的内容会随意改变; 许多特殊功能寄存器的值也会随着指令的运行而动态变化。 该类型的所有变量都必须显式定义为“易失性”,例如:
volatile unsigned char STATUS @ 0x03;
volatile bit commFlag;
3.5 标准库函数 PICC 提供了比较完善的C 标准库函数支持,包括数学运算函数和字符串运算函数。 在程序中使用这些现成的库函数时,需要注意的是入口参数必须在bank0中。
如果需要使用数学函数,使用“#include”包含头文件; 如果要使用字符串操作函数,则需要包含“#include”头文件。 这些头文件中提供了函数类型的声明。 直接查看这些头文件就可以知道PICC提供了哪些标准库函数。
在单片机程序中使用C语言中的格式化输出函数“printf/sprintf”必须特别小心。 printf/sprintf是一个非常大的函数,一旦使用,你的程序代码长度就会增加很多。
4.C与汇编混合编程
用C语言开发微控制器应用程序时经常使用汇编语句。 例如,单片机的一些特殊指令操作在标准C语言语法中没有直接对应的描述,如PIC单片机的清看门狗指令“clrwdt”和睡眠指令“sleep”。 这样,一个项目中就会出现C和汇编的混合编程。 这里我们讨论混合编程的一些基本方法和技巧。
直接在C原程序中嵌入汇编指令是最直接、最简单的方法。 如果只需要嵌入一些汇编指令,PICC提供了类似函数的语句:
asm(“clrwdt”);
任何 PIC 标准汇编指令都可以用双引号编写。 例如:
for (;;) {
asm("clrwdt"); //清看门狗
asm("sleep"); //休眠
asm(“nop”); //空操作延时
}
如果需要编写连续的汇编指令,PICC 支持另一种语法描述:指令部分以“#asm”开始,以“#endasm”结束。
例如,以下嵌入式汇编指令清除 0x20~0x7F 之间的所有 RAM:
#asm
movlw 0x20
movwf _FSR
clrf _INDF
incf _FSR, f
btfss _FSR,7
goto $-3
#endasm