PIC单片机的C语言编程.docx
《PIC单片机的C语言编程.docx》由会员分享,可在线阅读,更多相关《PIC单片机的C语言编程.docx(73页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、PIC单片机C语言编程讲义奥科电子作室(内部资料)2006年元月第一版第1章PIC单片机的C语言编程1.1 pic单片机c语言编程简介用C语言来开发单片机系统软件最大的好处是编写代码效率髙、软件调试直观、维护 升级方便、代码的重复利用率高、便于跨平台的代码移植等等,因此c语言编程在单片机 系统设计中已得到越来越广泛的运用。针对PIC单片机的软件开发,同样可以用C语言实 现。但在单片机上用C语言写程序和在PC机上写程序绝对不能简单等同。现在的PC机资 源十分丰富,运算能力强大,因此程序员在写PC机的应用程序时几乎不用关心编译后的可 执行代码在运行过程中需要占用多少系统资源,也基本不用担心运行效率
2、有多高。写单片机 的C程序最关键的一点是单片机内的资源非常有限,控制的实时性要求又很高,因此,如 果没有对单片机体系结构和硬件资源作详尽的了解,以笔者的愚见认为是无法写出高质量实 用的C语言程序。这就是为什么前面所有章节中的的示范代码全部用基础的汇编指令实现 的原因,希望籍此能使读者对PIC单片机的指令体系和硬件资源有深入了解,在这基础之 上再来讨论C语言编程,就有水到渠成的感觉。本讲稿围绕中档系列PIC单片机来展开讨论,Microchip公司自己没有针对中低档系列 PIC单片机的C语言编译器,但很多专业的第三方公司有众多支持PIC单片机的C语言编译 器提供,常见的有Hitech、CCS、IA
3、R、Bytecraft等公司。其中笔者最常用的是Hitech公司 的PICC编译器,它稳定可靠,编译生成的代码效率高,在用PIC单片机进行系统设计和开 发的工程师群体中得到广泛认可。其正式完全版软件需要购置,但在其网站上有限时的试用 版供用户评估。另外,Hitech公司针对广大PIC的业余爱好者和初学者还提供了完全免费 的学习版PICC-Lite编译器套件,它的使用方式和完全版相同,只是支持的PIC单片机型号 限制在PIC16F84、PIC16F877和PIC16F628等几款。这几款Flash型的单片机因其所具备的 丰富的片上资源而最适用于单片机学习入门,因此笔者建议感兴趣的读者可从PICC
4、-Lite入 手掌握PIC单片机的C语言编程。在此列出几个主要的针对PIC単片机的C编译器相关连接网址,供读者参考:Hitech-PICC: IAR: CCS : ByteCraft: 本章将介绍Hitech-PICC编译器的些基本概念,由于篇幅所限将不涉及C语言的标准 语法和基础知识介绍,因为在这些方面都有大量的书籍可以参考。重点突出针对PIC单片 机的特点而所需要特别注意的地方。1.2 Hitech-PICC 编译器PICC基本上符合ANSI标准,除了一点:它不支持函数的递归调用。其主要原因是因 为PIC单片机特殊的堆栈结构。在前面介绍PIC单片机架构时已经详细说明了PIC单片机 中的堆栈
5、是硬件实现的,其深度已随芯片而固定,无法实现需要大量堆栈操作的递归算法; 另外在PIC单片机中实现软件堆栈的效率也不是很高,为此,PICC编译器采用一种叫做“静 态覆盖”的技术以实现对c语言函数中的局部变量分配固定的地址空间。经这样处理后产 生出的机器代码效率很高,按笔者实际使用的体会,当代码量超过4K字后,C语言编译出 的代码长度和全部用汇编代码实现时的差别已经不是很大(10%),当然前提是在整个C 代码编写过程中须时时处处注意所编写语句的效率,而如果没有对PIC单片机的内核结构、 各功能模块及其汇编指令深入了解,要做到这点是很难的。1.3 MPLAB-IDE 内挂接PICCPICC编译器可
6、以直接挂接在MPLAB-IDE集成开发平台下,实现一体化的编译连接和 原代码调试。使用MPLAB-IDE内的调试工具E200、ICD2和软件模拟器都可以实现原 代码级的程序调试,非常方便。首先必须在你的计算机中安装PICC编译器,无论是完全版还是学习版都可以和 MPLAB-IDE挂接。安装成功后可以进入IDE,选择菜单项Project Set Language ToolLocations,打开语言工具挂接设置对话框,如图所示:在对话框中选择“HI-TECH PICC Toolsuite栏,展开可执行文件组Executable后,列出了将被MPLAB-IDE后台调用的 编译器所用到的所有可执行文
7、件,其中有汇编编译器“ PICC Assembler、C原程序编译器 PICC Compiler和连接定位程序“PICC Linker”。同时在此列表中还显示了对应的可执 行程序名,请注意在这里都是“ PICC.EXE”。用鼠标分别点击选中这三项可执行文件,观 察对话框下面“Location” 栏中显示的文件路径,用“Browse.”按纽,从计算机中已经 安装的PICC编译器文件夹中选择PICC.EXE文件。实际上PICC.EXE只是个调度管理程 序,它会按照所输入的文件扩展名自动调用对应的编译器和连接器,用户要注意的是C语 言原程序扩展名用“.c”,汇编原程序用“.as”即可。工具挂接完成后
8、,在建立项目时可以 选择语言工具为“HI-TECH PICC”,具体步骤可以参阅第三章3.1.3节,此处不再重复。项 目建立完成后可以加入C或汇编原程序,也可以加入已有的库文件或已经编译的目标文件。 最常见的是只加入C原程序。用C语言编程的好处是可以实现模块化编程。程序编写者应 尽量把相互独立的控制任务用多个独立的C原程序文件实现,如果程序量较大,一般不要 把所有的代码写在个文件内。图2列出的是笔者建立的个项目中所有C原程序模块, 其中主控、数值计算、12c总线操作、命令按键处理和液晶显示驱动等不同的功能分别在不 同的独立的原程序模块中实现。1.1 PC68. acvEl 68-Stra Fl
9、lt hM 68.cel c C rC66JZT cCHt4er File*rcw hObject File*Ubrtry Fllei1.4 PIC单片机的C语言原程序基本框架基于PICC编译环境编写PIC单片机程序的基本方式和标准C程序类似,程序一般由以 下几个主要部分组成:在程序的最前面用#include预处理指令引用包含头文件,其中必须包含一个编译器提供 的“pic.h”文件,实现单片机内特殊寄存器和其它特殊符号的声明:用“_CONFIG”预处理指令定义芯片的配置位;声明本模块内被调用的所有函数的类型,PICC将对所调用的函数进行严格的类型匹配检 查:定义全局变量或符号替换;实现函数(子
10、程序),特别注意main函数必须是个没有返回的死循环。下面的例1-1为个C原程序的范例,供大家参考。include 包含单片机内部资源预定义include “pc68. h” 包含自定义头文件定义芯片工作时的配置位一CONFIG ( HS & PROTECT & PWRTEN & BOREN & TOTDI S);声明本模块中所调用的函数类型void Set SFR( voi d);void Cl oc k( voi d);void KeyScan(voi d);void Nfeasure(voi d);voi d LCD.Test(voi d);void LCD_ Di sp( unsi g
11、ned char);/定义变量uns i gned char second, mi nut e . hour;bi t flagl, flag2;I!函数和子程序图I-2C语言多模块编程void ma i n ( voi d)ISe t SFR();PORTC = 0x00;TMR1 H += TMRIH_CONST;LEDILED.OFF;LCD_Tc s ();/程序工作主循环while( 1) (a s n( u c I r wd t n); /清看门狗Cl ock(); /更新时钟KeyScan(); /扫描键盘Nfe a s u r e ( ); / Z数据测量SetSFR( );
12、/刷新特殊功能寄存器11例1-1C语言原程序框架举例1.5 PICC中的变量定义1.5.1 PICC中的基本变量类型PICC支持的基本变量类型见表1-1:类型-(位数)3-送bit1布尔型位変量,。或1两时取值char8符号或无符号字符変PKC缺省认定char里麦无符.I编f逸项改対写字节以通unsigned char8无符号字符变量short16有符号整型致unsigned short16无符号整型数int16有符号整型数unsigned int16无符号整型数long32有符号长整璽数unsigned long32无符号长整型数float24浮点数double24 或 32浮点数,PKC缺
13、省认定double型变为24位长,但可以改変编译选项改成32位表L I PICC的基本变量类型PICC遵循Liule-endian标准,多字节变量的低字节放在存储空间的低地址,高字节放在高 地址。1.5.2 PICC中的髙级变量基于表1-1的基本变量,除了bit型位变量外,PICC完全支持数组、结构和联合等复合型 髙级变量,这和标准的C语言所支持的高级变量类型没有什么区别。例如:数组:uns i gned i nt dat a | 10;结构:struct c omml n Da l a u n s i gned char i n Bu f f(8;uns i gned char ge t P
14、lr, put Pt r;;联合:uni on i ni _Byt e (uns i gned char c2;u n s i g n e d i n I i ;;例1-2C语言髙级变量举例1.5.3 PICC对数据寄存器bank的管理为了使编译器产生最高效的机器码,PICC把单片机中数据寄存器的bank问题交由编 程员自己管理,因此在定义用户变量时你必须自己决定这些变量具体放在哪个bank中。 如果没有特别指明,所定义的变量将被定位在bank。,例如下面所定义的这些变量:unsigned char buffer(32;bi t f I ag I, f 1 ag2;float vaI I 8;
15、除了bank。内的变量声明时不需特殊处理外,定义在其它bank内的变量前面必须加上 相应的bank序号,例如:bank! unsigned char buf f er 32 : /变量定位在bank I 中bank2 bi t f 1 agl, f I ag2I ”变量定位在 bank2 中bank3 fl oat val 8; “变量定位在 bank3 中中档系列PIC单片机数据寄存器的个bank大小为128字节,刨去前面若干字节的特 殊功能寄存器区域,在C语言中某bank内定义的变量字节总数不能超过可用RAM字节 数。如果超过bank容量,在最后连接时会报错,大致信息如下:Er r or
16、0001 : Ca n t find Ox 1 2C words for ps e c t r b s s _ 1 i n s e g me n t BANK1连接器告诉你总共有0xl2C (300)个字节准备放到bankl中但bankl容量不够。显然, 只有把一部分原本定位在bankl中的变量改放到其它bank中才能解决此问题。虽然变量所 在的bank定位必须由编程员自己决定,但在编写原程序时进行变量存取操作前无需再特意 编写设定bank的指令。C编译器会根据所操作的对象自动生成对应bank设定的汇编指令。 为避免频繁的bank切换以提高代码效率,尽量把实现同一任务的变量定位在同一个bank
17、 内;对不同bank内的变量进行读写操作时也尽量把位于相同bank内的变量归并在一起进行 连续操作。1.5.4 PICC中的局部变量PICC把所有函数内部定义的auto型局部变量放在bankO。为节约宝贵的存储空间,它 采用了一种被叫做“静态覆盖”的技术来实现局部变量的地址分配。其大致的原理是在编译 器编译原代码时扫描整个程序中函数调用的嵌套关系和层次,算出每个函数中的局部变量字 节数,然后为每个局部变量分配个固定的地址,且按调用嵌套的层次关系各变量的地址可 以相互重叠。利用这技术后所有的动态局部变量都可以按已知的固定地址地进行直接寻 址,fflPIC汇编指令实现的效率最高,但这时不能出现函数
18、递归调用。PICC在编译时会严 格检查递归调用的问题并认为这是个严重错误而立即终止编译过程。既然所有的局部变量将占用bankO的存储空间,因此用户自己定位在bankO内的变量字 节数将受到一定的限制,在实际使用时需注意。1.5.5 PICC中的位变量bit型位变量只能是全局的或静态的。PICC将把定位在同一bank内的8个位变量合并 成一个字节存放于个固定地址。因此所有针对位变量的操作将直接使用PIC单片机的位 操作汇编指令高效实现。基于此,位变量不能是局部自动型变量,也无法将其组合成复合型 高级变量。PICC对整个数据存储空间实行位编址,0x000单元的第位是位地址0x0000,以此后 推,
19、每个字节有8个位地址。编制位地址的意义纯粹是为了编译器最后产生汇编级位操作指 令而用,对编程人员来说基本可以不管。但若能了解位变量的位地址编址方式就可以在最后 程序调试时方便地査找自己所定义的位变量,如果个位变量flagl被编址为0x123,那么 实际的存储空间位于:字节地址=0x123/8 = 0x24位偏移=0x1 23艇=3即flagl位变量位于地址为0x24字节的第3位。在程序调试时如果要观察flagl的变 化,必须观察地址为0x24的字节而不是0x123。PIC单片机的位操作指令是非常高效的。 因此,PICC在编译原代码时只要有可能,对普通变量的操作也将以最简单的位操作指令来 实现。
20、假设个字节变量tmp最后被定位在地址0x20,那么t mp I = 0x80 = bs f 0x20,7t mp &= Oxf 7 = be f 0x20,3i f (imp&Oxfe) = b( fsc 0x20. 0即所有只对变量中某一位操作的c语句代码将被直接编译成汇编的位操作指令。虽然 编程时可以不用太关心,但如果能了解编译器是如何工作的,那将有助于引导我们写出高效 简介的C语言原程序。在有些应用中需要将一组位变量放在同一个字节中以便需要时一次 性地进行读写,这功能可以通过定义个位域结构和一个字节变量的联合来实现,例如: union (struct unsigned b0: I;uns
21、 i gne d b 1: 1;unsigned b 2: I;unsigned b3: 1;unsigned b 4: I;uns i gne d b5: I;uns i gne d : 2; /最高两位保留)one Bi (;uns i gned char a 1 I Bi t s;)my FI a g;例1-3定义位变量于同字节需要存取其中某一位时可以myFI ag. oneBi t . b3 = l; / / b3 位置 1一次性将全部位清零时可以myFI ag. al I Bi t s=0; / / 全部位变量清当程序中把非位变量进行强制类型转换成位变量时,要注意编译器只对普通变量的
22、最低 位做判别:如果最低位是,则转换成位变量:如果最低位是1,则转换成位变量1。而标准 的ANS1-C做法是判整个变量值是否为0。另外,函数可以返回一个位变量,实际上此返回 的位变量将存放于单片机的进位位中带出返回。1.5.6 PICC中的浮点数PICC中描述浮点数是以1EEE-754标准格式实现的。此标准下定义的浮点数为32位 长,在单片机中要用4个字节存储。为了节约单片机的数据空间和程序空间,PICC专门提 供了一种长度为24位的截短型浮点数,它损失了浮点数的一点精度,但浮点运算的效率得 以提高。在程序中定义的float型标准浮点数的长度固定为24位,双精度double型浮点数 一般也是2
23、4位长,但可以在程序编译选项中选择double型浮点数为32位,以提高计算的 精度。一般控制系统中关心的是单片机的运行效率,因此在精度能够满足的前提下尽量选择 24位的浮点数运算。1.5.7 PICC中变量的绝对定位首先必须强调,在用C语言写程序时变量一般由编译器和连接器最后定位,在写程序 之时无需知道所定义的变量具体被放在哪个地址(除了bank必须声明)。真正需要绝对定 位的只是单片机中的那些特殊功能寄存器,而这些寄存器的地址定位在PICC编译环境所提 供的头文件中已经实现,无需用户操心。编程员所要了解的也就是P1CC是如何定义这些特 殊功能寄存器和其中的相关控制位的名称。好在PICC的定义
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PIC 单片机 语言 编程
限制150内