您的位置 首页 编程

PIC单片机C言语编程教程(1)

PIC单片机C语言编程简介用C语言来开发单片机系统软件最大的好处是编写代码效率高、软件调试直观、维护升级方便、代码的重复利用

PIC 单片机 C 言语编程简介

C 言语来开发单片机体系软件最大的优点是编写代码功率高、软件调试直观、保护晋级便利、

代码的重复运用率高、便于跨渠道的代码移植等等,因而 C 言语编程在单片机体系规划中已得到越

来越广泛的运用。针对 PIC 单片机的软件开发,相同可以用 C 言语完成。

但在单片机上用 C 言语写程序和在 PC 机上写程序肯定不能简略同等。现在的 PC 机资

源十分丰厚,运算才干强壮,因而程序员在写 PC 机的使用程序时简直不必关怀编译后的可

履行代码在运转进程中需求占用多少体系资源,也根本不必忧虑运转功率有多高。写单片机

C 程序最要害的一点是单片机内的资源十分有限,操控的实时性要求又很高,因而,如

果没有对单片机体系结构和硬件资源作翔实的了解,以笔者的鄙意以为是无法写出高质量实

用的 C 言语程序。这便是为什么前面一切章节中的的演示代码悉数用根底的汇编指令完成

的原因,期望籍此能使读者对 PIC 单片机的指令体系和硬件资源有深化了解,在这根底之

上再来评论 C 言语编程,就有瓜熟蒂落的感觉。

本书环绕中档系列 PIC 单片机来打开评论,Microchip 公司自己没有针对中低档系列 PIC

单片机的 C 言语编译器,但许多专业的第三方公司有很多支撑 PIC 单片机的 C 言语编译器

供给,常见的有 Hitech、CCS、IAR、Bytecraft 等公司。其间笔者最常用的是 Hitech 公司的

PICC 编译器,它安稳牢靠,编译生成的代码功率高,在用 PIC 单片机进行体系规划和开发

的工程师集体中得到广泛认可。其正式彻底版软件需求置办,但在其网站上有限时的试用版

供用户评价。别的,Hitech 公司针对广阔 PIC 的业余爱好者和初学者还供给了彻底免费的学

习版 PICC-Lite 编译器套件,它的运用方法和彻底版相同,仅仅支撑的 PIC 单片机类型约束

在 PIC16F84、PIC16F877 和 PIC16F628 等几款。这几款 Flash 型的单片机因其所具有的丰厚

的片上资源而最适用于单片机学习入门,因而笔者主张感兴趣的读者可从 PICC-Lite 入手掌

握 PIC 单片机的 C 言语编程。

在此列出几个首要的针对 PIC 单片机的 C 编译器相关衔接网址,供读者参看:

Hitech-PICC: www.htsoft.com

IAR:www.iar.com

CCS:www.ccsinfo.com/picc.shtml

ByteCraft:www.bytecraft.com/mpccaps.html

本章将介绍 Hitech-PICC 编译器的一些根本概念,由于篇幅所限将不触及 C 言语的规范

语法和根底知识介绍,由于在这些方面都有很多的书本可以参看。要点杰出针对 PIC 单片

机的特色而所需求特别留意的当地。

11.2

Hitech-PICC 编译器

PICC 根本上契合 ANSI 规范,除了一点:它不支撑函数的递归调用。其首要原因是因

为 PIC 单片机特别的仓库结构。在前面介绍 PIC 单片机架构时现已详细说明晰 PIC 单片机

中的仓库是硬件完成的,其深度已随芯片而固定,无法完成需求很多仓库操作的递归算法;

别的在 PIC 单片机中完成软件仓库的功率也不是很高,为此,PICC 编译器选用一种叫做“静

态掩盖”的技能以完成对 C 言语函数中的部分变量分配固定的地址空间。经这样处理后产

生出的机器代码功率很高,按笔者实践运用的领会,当代码量超越 4K 字后,C 言语编译出

的代码长度和悉数用汇编代码完成时的不同现已不是很大(<10%),当然条件是在整个 C

代码编写进程中须不时处处留意所编写句子的功率,而假如没有对 PIC 单片机的内核结构、

各功用模块及其汇编指令深化了解,要做到这点是很难的。

11.3

MPLAB-IDE 内挂接 PICC

PICC 编译器可以直接挂接在 MPLAB-IDE 集成开发渠道下,完成一体化的编译衔接和

原代码调试。运用 MPLAB-IDE 内的调试东西 ICE2000、ICD2 和软件模拟器都可以完成原

代码级的程序调试,十分便利。

首要有必要在你的核算机中装置PICC编译器,无论是彻底版仍是学习版都可以和

MPLAB-IDE挂接。装置成功后可以进入IDE,挑选菜单项Project Set Language Tool

Locations…,翻开言语东西挂接设置对话框,如图 11-1 所示:

%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/7.jpg” src=”file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/7.jpg” />

图 11-1 MPLAB-IDE 言语东西设置对话框

在对话框中挑选“HI-TECH PICC Toolsuite”栏,打开可履行文件组“Executable”后,

列出了将被 MPLAB-IDE 后台调用的编译器所用到的一切可履行文件,其间有汇编编译器

“PICC Assembler”、C 原程序编译器“PICC Compiler”和衔接定位程序“PICC Linker”。同

时在此列表中还显现了对应的可履行程序名,请留意在这里都是“PICC.EXE”。用鼠标别离

点击选中这三项可履行文件,调查对话框下面“Location”一栏中显现的文件途径,用

“Browse…”按纽,从核算机中现已装置的 PICC 编译器文件夹中挑选 PICC.EXE 文件。实

际上 PICC.EXE 仅仅一个调度办理程序,它会依照所输入的文件扩展名主动调用对应的编译

器和衔接器,用户要留意的是 C 言语原程序扩展名用“.c”,汇编原程序用“.as”即可。

东西挂接完成后,在树立项目时可以挑选言语东西为“HI-TECH PICC”,详细步骤可以

参看第三章 3.1.3 节,此处不再重复。项目树立完成后可以参加 C 或汇编原程序,也可以加

入已有的库文件或现已编译的方针文件。最常见的是只参加 C 原程序。用 C 言语编程的好

处是可以完成模块化编程。程序编写者应尽量把彼此独立的操控使命用多个独立的 C 原程序文件实

现,假如程序量较大,一般不要把一切的代码写在一个文件内。

图 11-2 列出的是笔者树立的一个项目中一切 C 原程序模块,其间主控、数值核算、I2C 总线

作、指令按键处理和液晶显现驱动等不同的功用别离在不同的独立的原程序模块中完成。

%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/8.jpg” src=”file:///F:/data/%C3%83%C2%8F%C3%83%C2%82%C3%83%C2%94%C3%83%C2%98/PIC%C3%82%C2%B5%C3%82%C2%A5%C3%83%C2%86%C3%82%C2%AC%C3%82%C2%BB%C3%83%C2%BAC%C3%83%C2%93%C3%83%C2%AF%C3%83%C2%91%C3%83%C2%94%C3%82%C2%B1%C3%83%C2%A0%3Cwbr%3E%C3%82%C2%B3%C3%83%C2%8C%C3%82%C2%BD%C3%83%C2%8C%C3%82%C2%B3%C3%83%C2%8C.files/8.jpg” />

图 11-2 C 言语多模块编程

11.4 PIC 单片机的 C 言语原程序根本结构

依据 PICC 编译环境编写 PIC 单片机程序的根本方法和规范 C 程序相似,程序一般由以

下几个首要部分组成:

&O1540; 在程序的最前面用#include 预处理指令引证包括头文件,其间有必要包括一个编译器

供给的“pic.h”文件,完成单片机内特别寄存器和其它特别符号的声明;

&O1540; 用“__CONFIG”预处理指令界说芯片的装备位;

&O1540; 声明本模块内被调用的一切函数的类型,PICC 将对所调用的函数进行严厉的类型

匹配查看;

&O1540; 界说大局变量或符号替换;

&O1540; 完成函数(子程序),特别留意 main 函数有必要是一个没有回来的死循环。

下面的例 11-1 为一个 C 原程序的典范,供咱们参看。

#include //包括单片机内部资源预界说

#include “pc68.h” //包括自界说头文件

//界说芯片作业时的装备位

__CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS);

//声明本模块中所调用的函数类型

void SetSFR(void);

void Clock(void);

void KeyScan(void);

void Measure(void);

void LCD_Test(void);

void LCD_Disp(unsigned char);

//界说变量

unsigned char second, minute, hour;

bit flag1,flag2;

//函数和子程序

void main(void)

{

SetSFR();

PORTC = 0x00;

TMR1H += TMR1H_CONST;

LED1 = LED_OFF;

LCD_Test();

//程序作业主循环

while(1) {

asm(“clrwdt”);

Clock();

KeyScan();

Measure();

SetSFR();

}

}

//清看门狗

//更新时钟

//扫描键盘

//数据丈量

//改写特别功用寄存器

11.5

PICC 中的变量界说

例 11-1 C 言语原程序结构举例

11.5.1 PICC 中的根本变量类型

PICC 遵从 Little-endian 规范,多字节变量的低字节放在存储空间的低地址,高字节放

在高地址。

11.5.2 PICC 中的高档变量

依据表 11-1 的根本变量,除了 bit 型位变量外,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;

};

例 11-2 C 言语高档变量举例

11.5.3 PICC 对数据寄存器 bank 的办理

为了使编译器发生最高效的机器码,PICC 把单片机中数据寄存器的 bank 问题交由编程

员自己办理,因而在界说用户变量时你有必要自己决议这些变量详细放在哪一个 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;

bank3 float val[8];

//变量定位在 bank2 中

//变量定位在 bank3 中

中档系列 PIC 单片机数据寄存器的一个 bank 巨细为 128 字节,刨去前面若干字节的特

殊功用寄存器区域,在 C 言语中某一 bank 内界说的变量字节总数不能超越可用 RAM 字节

数。假如超越 bank 容量,在最终衔接时会报错,大致信息如下:

Error[000] : Cant find 0x12C words for psect rbss_1 in segment BANK1

衔接器告知你总共有 0x12C(300)个字节预备放到 bank1 中但 bank1 容量不行。明显,只

有把一部分本来定位在 bank1 中的变量改放到其它 bank 中才干处理此问题。

尽管变量地点的 bank 定位有必要由编程员自己决议,但在编写原程序时进行变量存取操

作前无需再特意编写设定 bank 的指令。C 编译器会依据所操作的目标主动生成对应 bank 设

定的汇编指令。为防止频频的 bank 切换以进步代码功率,尽量把完成同一使命的变量定位

在同一个 bank 内;对不同 bank 内的变量进行读写操作时也尽量把坐落相同 bank 内的变量

归并在一起进行接连操作。

11.5.4 PICC 中的部分变量

PICC 把一切函数内部界说的 auto 型部分变量放在 bank0。为节省名贵的存储空间,它

选用了一种被叫做“静态掩盖”的技能来完成部分变量的地址分配。其大致的原理是在编译

器编译原代码时扫描整个程序中函数调用的嵌套联系和层次,算出每个函数中的部分变量字

节数,然后为每个部分变量分配一个固定的地址,且按调用嵌套的层次联系各变量的地址可

以彼此堆叠。运用这一技能后一切的动态部分变量都可以按已知的固定地址地进行直接寻

址,用 PIC 汇编指令完成的功率最高,但这时不能呈现函数递归调用。PICC 在编译时会严

格查看递归调用的问题并以为这是一个严重错误而当即停止编译进程。

已然一切的部分变量将占用 bank0 的存储空间,因而用户自己定位在 bank0 内的变量字

节数将遭到必定的约束,在实践运用时需留意。

11.5.5 PICC 中的位变量

bit 型位变量只能是大局的或静态的。PICC 将把定位在同一 bank 内的 8 个位变量兼并

成一个字节存放于一个固定地址。因而一切针对位变量的操作将直接运用 PIC 单片机的位

操作汇编指令高效完成。依据此,位变量不能是部分主动型变量,也无法将其组合成复合型

高档变量。

PICC 对整个数据存储空间实施位编址,0x000 单元的第 0 位是位地址 0x0000,以尔后

推,每个字节有 8 个位地址。编制位地址的含义朴实是为了编译器最终发生汇编级位操作指

令而用,对编程人员来说根本可以不论。但若能了解位变量的位地址编址方法就可以在最终

程序调试时便利地查找自己所界说的位变量,假如一个位变量 flag1 被编址为 0x123,那么

实践的存储空间坐落:

字节地址=0x123/8 = 0x24

位偏移 =0x123%8 = 3

即 flag1 位变量坐落地址为 0x24 字节的第 3 位。在程序调试时假如要调查 flag1 的改变,必

须调查地址为 0x24 的字节而不是 0x123。

PIC 单片机的位操作指令是十分高效的。因而,PICC 在编译原代码时只需有或许,对

一般变量的操作也将以最简略的位操作指令来完成。假定一个字节变量 tmp 最终被定位在

地址 0x20,那么

tmp |= 0x80

tmp &= 0xf7

=> bsf

=> bcf

0x20,7

0x20,3

if (tmp&0xfe)

=> btfsc 0x20,0

即一切只对变量中某一位操作的 C 句子代码将被直接编译成汇编的位操作指令。尽管编程

时可以不必太关怀,但假如能了解编译器是怎么作业的,那将有助于引导咱们写出高效简介

的 C 言语原程序。

在有些使用中需求将一组位变量放在同一个字节中以便需求时一次性地进行读写,这一

功用可以经过界说一个位域结构和一个字节变量的联合来完成,例如:

union {

struct {

unsigned b0: 1;

unsigned b1: 1;

unsigned b2: 1;

unsigned b3: 1;

unsigned b4: 1;

unsigned b5: 1;

unsigned : 2; //最高两位保存

} oneBit;

unsigned char allBits;

} myFlag;

例 11-3 界说位变量于同一字节

需求存取其间某一位时可以

myFlag.oneBit.b3=1; //b3 方位 1

一次性将悉数位清零时可以

myFlag.allBits=0; //悉数位变量清 0

当程序中把非位变量进行强制类型转换成位变量时,要留意编译器只对一般变量的最低

位做判别:假如最低位是 0,则转换成位变量 0;假如最低位是 1,则转换成位变量 1。而标

准的 ANSI-C 做法是判整个变量值是否为 0。别的,函数可以回来一个位变量,实践上此返

回的位变量将存放于单片机的进位位中带出回来。

11.5.6 PICC 中的浮点数

PICC 中描绘浮点数是以 IEEE-754 规范格局完成的。此规范下界说的浮点数为 32 位长,

在单片机中要用 4 个字节存储。为了节省单片机的数据空间和程序空间,PICC 专门供给了

一种长度为 24 位的截短型浮点数,它丢失了浮点数的一点精度,但浮点运算的功率得以提

高。在程序中界说的 float 型规范浮点数的长度固定为 24 位,双精度 double 型浮点数一般

也是 24 位长,但可以在程序编译选项中挑选 double 型浮点数为 32 位,以进步核算的精度。

一般操控体系中关怀的是单片机的运转功率,因而在精度可以满意的条件下尽量挑选

24 位的浮点数运算。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/261693.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部