PIC编程说明
- 格式:doc
- 大小:35.50 KB
- 文档页数:5
PIC编程说明
在编程过程中由于一个端口可能有多个功能,所以在初始化时应该详细设置所以的端口的功能,当使用一种功能时应该将其他功能关闭,否则端口的功能将不能正常工作。
汇编:
C语言:-------picc
1、在用C语言编程之前,得确定用户用的是哪个辅助C编译器(因为MPLAB IDE不提供C编译器,不过在8.33版本有捆绑了PICC的C编译器用户可以直接选用)。注意设置连接编译器的路径。
2 在程序的最前面用#include 预处理指令引用包含头文件,其中必须包含一个编译器
提供的“pic.h”文件(在picc18里为:pic18.h),实现单片机内特殊寄存器和其它特殊符号的声明;
3 用“__CONFIG”预处理指令定义芯片的配置位;
4 声明本模块内被调用的所有函数的类型,PICC 将对所调用的函数进行严格的类型
匹配检查;
5 定义全局变量或符号替换;
6 实现函数(子程序),特别注意main 函数必须是一个没有返回的死循环。
现提供个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(); //刷新特殊功能寄存器
}
}
为了使编译器产生最高效的机器码,PICC 把单片机中数据寄存器的bank 问题交由编程员自己管理,因此在定义用户变量时你必须自己决定这些变量具体放在哪一个bank 中。如果没有特别指明,所定义的变量将被定位在bank0,除了 bank0
内的变量声明时不需特殊处理外,定义在其它bank 内的变量前面必须加上。相应的bank 序号,例如:
bank1 unsigned char buffer[32]; //变量定位在bank1 中,中档系列
PIC 单片机数据寄存器的一个bank 大小为128 字节,刨去前面若干字节的特殊功能寄存器区域,在C 语言中某一bank 内定义的变量字节总数不能超过可用RAM 字节数。如果超过bank 容量,在最后连接时会报错,大致信息如下:
Error[000] : Can't find 0x12C words for psect rbss_1 in segment BANK1
连接器告诉你总共有 0x12C(300)个字节准备放到bank1 中但bank1 容量不够。显然,只有把一部分原本定位在bank1 中的变量改放到其它bank 中才能解决此问题。
C 和汇编混合编程
在 C 原程序中直接嵌入汇编指令是最直接最容易的方法。如果只需要嵌入少量几条的汇编指令,PICC 提供了一个类似于函数的语句:
asm(“clrwdt”); 双引号中可以编写任何一条 PIC 的标准汇编指令。如果需要编写一段连续的汇编指令,PICC 支持另外一种语法描述:用“#asm”开始汇
编指令段,用“#endasm”结束。例如下面的一段嵌入汇编指令实现了将0x20~0x7F
间的
RAM 全部清零:
#asm
movlw 0x20
movwf _FSR
clrf _INDF
incf _FSR,f
btfss _FSR,7
goto $-3
#endasm
中断函数的实现
PICC 可以实现C 语言的中断服务程序。中断服务程序有一个特殊的定义方法:void interrupt ISR(void); 中断函数可以被放置在原程序的任意位置。因为已有关键词“interrupt”声明,PICC 在最后进行代码连接时会自动将其定位到0x0004 中断入口处,实现中断服务响应。编译器也会实现中断函数的返回指令“retfie”。一个简单的中断服务示范函数如下:void interrupt ISR(void)
//中断服务程序
{
if (T0IE && T0IF) //判TMR0 中断
{
T0IF = 0; //清除TMR0 中断标志 //在此加入TMR0 中断服务
}
if (TMR1IE && TMR1IF) //判TMR1 中断
{
TMR1IF = 0; //清除TMR1 中断标志
//在此加入TMR1 中断服务
}
} //中断结束并返回
PICC 会自动加入代码实现中断现场的保护,并在中断结束时自动恢复现场,所以编程员无需象编写汇编程序那样加入中断现场保护和恢复的额外指令语句。但如果在中断服务程序中需要修改某些全局变量时,是否需要保护这些变量的初值将由编程员自己决定和实施。中档系列 PIC 单片机的中断入口只有一个,因此整个程序中只能有一个中断服务函数。
高中断的声明和PICC一致,用关键字interrupt。低中断的声明用interrupt
low_priority。声明了低中断处理函数,并不会把什么中断自动变为低中断,每个中断的高低,还是由程序的代码中修改。PIC18 MCU在发生中断时,只将PC压入堆栈。其他的变量保护需要由软件完成。PICC18会自动检测需要保存的变量,在软件上做保存。如果中断中调用了某个函数,而这个函数定义在中断函数之前,那么编译器将适当包保存必要的变量,否则,最坏的情况就是全部可能用到变量都会被保存。
Picc18配置设置:__CONFIG()
在编译器头文件 PIC18.H和PIC18Fxxx中对应有宏定义说明; 注意,前面是两个下划线,这是一个宏__CONFIG()。该宏的定义在系统文件 htc.h中,根据PICC18编译器特性,如果再每个源文件中都使用了#include
模板:
#include
__CONFIG(n, data)
下面是我的程序配置定义:
#include
__CONFIG(1,HS);//
__CONFIG(2,PWRTDIS&BORV42&WDTEN&BOREN);//BORDIS
__CONFIG(3,CCP2RC1); //
__CONFIG(4,LVPDIS&STVRDIS);