智能车制作

标题: 龙丘推荐必读基础知识: 重要的#pragma声明 [打印本页]

作者: chiusir    时间: 2011-1-2 19:08
标题: 龙丘推荐必读基础知识: 重要的#pragma声明
本帖最后由 chiusir 于 2011-1-2 19:14 编辑

重要的#pragma声明
#pragma声明是基于单片机开发的特点而对标准C语法的一个扩充。它对充分利用单片机内各类有限的资源起到不可或缺的关键作用。下面简单介绍几个最常用的#pragma声明。

1 #pragma DATA_SEG
定义变量所处的数据段。其语法型式为:
#pragma DATA_SEG <属性> 名称
数据段名称可以自己任意命名,但习惯上有些约定的名称,其作用分别为:
 DEFAULT - 缺省的数据段,在08 系列单片机中的地址为0x100 以上。一般的变量定义可以放在这一区域。
 MY_ZEROPAGE - 特指第0页数据段,地址范围0x00-0xff,但实际用户可用的空间不到256 字节,因为前面的一些地址空间已经分配给了片内寄存器。需要频繁或快速存取的变量应该指定放在这一特殊区域,特别是位变量。
数据段名称必须和prm 文件中的数据段配置说明相关连才能真正发挥其定位作用。如果你自己命名的数据段在prm 文件中没有特别说明,那此数据段的性质等同于“DEFAULT”。
数据段的“属性”可以缺省,它主要的目的是告诉编译器此段数据可适用的寻址模式。不同的寻址模式所花的指令数量和运行时间都不同。对于08 系列单片机,关键的是第0页数据段可以用8位地址进行直接快速寻址,故对应此数据段应尽量指明其属性为“__SHORT_SEG”。对于一般数据段没有属性描述,其缺省是
“__FAR_SEG”,将用16位地址间接寻址。
举几个数据段定义的例子加以进一步说明。
#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE //开始0 页数据定义
volatile struct {
unsigned powerOn : 1;
unsigned alarmOn : 1;
unsigned commActive : 1;
unsigned sysError : 1;
} myFlag;
volatile word msCounter;
byte i,j,k;
#pragma DATA_SEG DEFAULT //开始普通数据段定义(结束0 页数据段)byte tmpBuff[16];

2 #pragma CONST_SEG
定义一个常数数据段,必须和变量的const修饰关键词配合使用。其语法型式为:
#pragma CONST_SEG 名称
该数据段下定义的所有数据将被放置在程序只读的ROM 区,也就是08 系列单片机内的Flash 程序空间区。常数段名称可以用户自由定义,但一般都用“DEFAULT”,让连接器按可用的ROM区域自由分配变量位置。举例如下:
#pragma CONST_SEG DEFAULT
const byte prjName[]=”This is a demo”;
FSL 系列单片机开发及C语言编程简介
const word version = 0x0301;
#pragma CONST_SEG DEFAULT
word version = 0x0301; //没有const 该变量将被放置在RAM 区!
#pragma DATA_SEG DEFAULT
const word version = 0x0301; //尽管有const 但该变量将被放置在RAM 区!
3.3.3 #pragma INTO_ROM
功能类似于“CONST_SEG”,和变量修饰词“const”配合使用。但它只定义一个常数变量到ROM区,且只作用于紧接着的下一行定义。例如:
#pragma INTO_ROM
const byte prjName[]=”This is a demo”; //变量将被放置在ROM 区
word verData = 0x0301; //变量将被放置在缺省RAM 区

4 #pragma CODE_SEG
用以定义程序段并赋以特定的段名,语法型式如下:
#pragma CODE_SEG <属性> 名称
一般的程序设计是无需对代码段做特殊处理的。因为所有传统的08 系列单片机其程序空间都不超过64KB(16 位寻址最大范围)且在内存地址中呈线性连续分布。对于项目中所有的代码文件或库文件,连接器会在最后按程序模块出现的先后顺序挨个自动安排所有程序函数在内存中所处的实际位置,用户不必太关心某一个函数的具体位置。但最新推出的几款8 位机程序将超过64KB,这样必须在内存空间中以页面型式映射到首64KB地址范围,其对应的程序段属性要特殊声明。某些特殊的设计需要将不同部分的程序分别定位到不同的地址空间,例如实现程序代码下载自动更新。这样的设计需要把负责应用程序下载更新的驱动代码固定放置在一个保留区域内,而把一般的应用程序放置在另外一个区域以便在需要时整体擦除后更新。这时就需要用“CODE_SEG”来分别指明不同的程序段,但还必须配合prm文件对程序空间进行分配和指派。
代码段的属性一般都用缺省的“__FAR_SEG”,表明所有的函数调用都是长调用(对应汇编指令为JSR)。但C08 和S08 系列单片机支持效率更高的函数短调用(对应汇编指令为BSR),如果你的某一个功能模块含有多个相互调用的小函数且函数调用间距不超过+127 或-128 字节,则可以将这部分代码段声明为短调用属性“__NEAR_SEG”。但实际编程时由于C 代码对应的汇编指令长度不是很容易就能估测得到,所以短调用属性很少使用。
下面以几个实例进一步说明:
//定义缺省的代码段,缺省属性为远调用
#pragma CODE_SEG DEFAULT
void main(void)
FSL 08系列单片机开发及C语言编程简介
{
...
}
//定义名字为FUNC_CODE 的代码段,缺省属性为远调用
#pragma CODE_SEG FUNC_CODE
void MyApp(void)
{
}
//定义远调用的程序段,段名为BOOTLOAD
#pragma CODE_SEG __FAR_SEG BOOTLOAD
void BootLoader(void)
{
}
//定义近调用的程序段,段名为KEYBOARD
#pragma CODE_SEG __NEAR_SEG KEYBOARD
void KeyDebounce(void)
{
...
}
byte KeyCheck(void)
{
...
}
void KeyBoard(void)
{
if (keyCheck()) {
KeyDebounce();
...
}
}

5 #pragma TRAP_PROC
用于定义一个函数为中断服务类型。此类型的函数编译器在将C 代码编译成汇编指令时会在代码前后增加必要的现场保护和恢复汇编代码,同时函数的最后返回用汇编指令“RTI”而不是针对普通函数的“RTS”。例如:
#pragma TRAP_PROC
void SCI1_Int(void) { //定义SCI1的中断服务程序
...
}
注意用“TRAP_PROC”定义的中断服务函数其实际中断矢量地址必须通过prm 文件指派。

6 #pragma MESSAGE
这个声明用以控制编译信息的显示。一般情况下这些编译信息都是有用的,特别是告警和错误信息。但有时我们会按单片机的工作特性编写一些代码,但正常程序编写时这些代码会产生一些告警信息,例如
#pragma MESSAGE DISABLE C4002 //忽略“Result-not-used”告警
//==============================================================
// sci1 1 data receive interrupt service routine
// Assigned for full-duplex communication with Main board
//==============================================================
void interrupt 17 sci11_Receive_ISR(void)
FSL 08系列单片机开发及C语言编程简介
{
SCI1S1; //读一次状态寄存器清除中断标志,会产生C4002 告警
sci1RxFifo[sci1FifoPut] = SCI1D;
sci1FifoPut++;
sci1FifoPut &= (SCI1_RXFIFO_SIZE-1);
}
如果你不想每次都看见编译器给出的这一类信息,可以先确认这一信息的编号,然后用“#pragma MESSAGE”加上“DISABLE” 关键词和信息号将它屏蔽。如果你想特别关注某类信息,可以用“ENABLE”让其永远显示出来。
作者: tldf521    时间: 2011-1-3 22:01
我超级顶啊直接,,刚刚就在为了这个郁闷呢,而且用的就是龙丘的板呵呵
作者: chaoyue    时间: 2011-1-15 22:01
谢谢
作者: chaoyue    时间: 2011-1-15 22:02
谢谢
作者: sncxy    时间: 2011-1-17 00:14
重要的#pragma声明
作者: machuan20082006    时间: 2011-1-18 16:27
先看看
作者: lifenothing    时间: 2011-1-19 16:38
以前还没在意这些呢
多谢了
作者: lovechezu    时间: 2011-1-19 18:33
其他单片机#pragma声明是不是都相似的呀?
作者: chiusir    时间: 2011-1-20 16:27
回复 8# lovechezu


    这个大部分是相似的,关键看编译器是怎么定义的啦
作者: lovechezu    时间: 2011-1-20 17:18
编译器具体指哪些呀?我刚学,不是很明白呀!请教了!
作者: lzsxtree    时间: 2011-2-7 01:58
与LS同求···
作者: zty18945    时间: 2011-2-13 03:41
好东西!
作者: lyyyuna    时间: 2011-2-13 12:54
#pragam是编译器的事,还是看看cw的手册吧
作者: chiusir    时间: 2011-2-13 14:36
编译器具体指哪些呀?我刚学,不是很明白呀!请教了!
lovechezu 发表于 2011-1-20 17:18



    编译器编译器是一种特殊的程序,它可以把以特定编程语言写成的程序变为机器可以运行的机器码。我们把一个程序写好,这时我们利用的环境是文本编辑器。这时我程序把程序称为源程序。在此以后程序员可以运行相应的编译器,通过指定需要编译的文件的名称就可以把相应的源文件(通过一个复杂的过程)转化为机器码了。 [编辑]编译器工作方法首先编译器进行语法分析,也就是要把那些字符串分离出来。然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。最后生成的是目标文件,我们也称为obj文件。再经过链接器的链接就可以生成最后的可执行代码了。有些时候我们需要把多个文件产生的目标文件进行链接,产生最后的代码。我们把一过程称为交叉链接。 一个现代编译器的主要工作流程如下:    * 源程序(source code)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→连接器(链接器,Linker)→可执行程序(executables)工作原理 编译是从源代码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码...

去图书馆查查相关资料吧,太多了...
作者: beandy    时间: 2011-2-17 21:01
学习中
作者: kui13575728208    时间: 2011-2-21 10:43
谢谢 正需要呢
作者: machuan20082006    时间: 2011-2-22 16:35
谢谢
作者: zhubinorange    时间: 2011-2-24 01:55
顶顶顶!太棒了
作者: 星梦追影    时间: 2011-2-25 19:40
刚开始学,看看!
作者: 68327436    时间: 2011-2-26 10:52

作者: 近水楼台    时间: 2011-2-27 11:07
必须顶
作者: gao0708    时间: 2011-3-2 19:37
谢谢
作者: robotong    时间: 2011-3-6 21:59
爱死你了
作者: LEUNG    时间: 2011-3-13 18:10
鼎啊
作者: wukaijie    时间: 2011-3-13 18:12
挣分
作者: vgonlan    时间: 2011-3-28 19:35
学习学习,
作者: tsacy    时间: 2011-3-30 19:24
xie 找了很久啊  !·1 和恶狠狠
作者: 吴必富1    时间: 2011-4-7 07:26
谢了
作者: gujianwei2012    时间: 2011-4-16 10:20
回复 1# chiusir


    谢谢
作者: Stormbreaker    时间: 2011-4-25 10:34
Thank you!
作者: 小罗    时间: 2011-4-26 13:13
顿悟
作者: iloveautomation    时间: 2011-4-28 18:55
谢谢啦
作者: clong_2010    时间: 2011-6-9 23:36
谢谢LZ
作者: zhoutoutou    时间: 2011-7-29 19:24
好东东啊,顶一个
作者: zwluoqi    时间: 2011-7-31 23:25
mark
作者: 272496322    时间: 2011-8-1 19:04
楼主好有眼光 意识到群众中出现的问题了啊 呵呵 感激
作者: KAI990610    时间: 2011-10-19 10:16
谢谢了
作者: kpkplp    时间: 2011-10-19 14:39
谢谢啊
作者: 理工小别    时间: 2011-10-22 12:13
我也不是很懂 尤其是对怎么把程序烧进去 头疼死了
作者: longcha    时间: 2011-10-22 22:58
谢谢!!我也姓龙的
作者: 561609030    时间: 2011-11-1 15:40

作者: kpkplp    时间: 2011-11-7 09:23
谢谢
作者: 是人何装神    时间: 2011-11-9 20:33
果断复制了
作者: 罗勃    时间: 2011-11-14 13:28

作者: bxsjc    时间: 2011-11-20 00:44
受益匪浅!
作者: YOON    时间: 2011-11-20 01:27
受教了~
作者: 豪杰    时间: 2012-3-7 19:36
力顶!:)
作者: 小木偶    时间: 2012-3-14 16:54
谢谢了
作者: 林崽    时间: 2012-3-15 14:45
顶起  辛苦了!
作者: tommyliu    时间: 2012-4-10 18:29
学习了,顶啊
作者: ilyht    时间: 2012-5-15 19:56
谢谢
作者: lingdongwoxin    时间: 2012-5-16 20:21
正需要这个呢  谢谢
作者: 罗志好    时间: 2013-3-6 15:34

作者: cty0111    时间: 2013-4-3 15:07
学习了

作者: dlyt03    时间: 2013-4-3 17:05
看看先
作者: ht7200    时间: 2013-4-12 15:30
碰到好的帖子我都会mark一下!
作者: 想恋爱。。。    时间: 2013-4-15 22:49
好东西,复制一份




欢迎光临 智能车制作 (http://dns.znczz.com/) Powered by Discuz! X3.2