项目驱动——深入理解嵌入式c

上传人:j****9 文档编号:54943740 上传时间:2018-09-22 格式:PPT 页数:20 大小:886.50KB
返回 下载 相关 举报
项目驱动——深入理解嵌入式c_第1页
第1页 / 共20页
项目驱动——深入理解嵌入式c_第2页
第2页 / 共20页
项目驱动——深入理解嵌入式c_第3页
第3页 / 共20页
项目驱动——深入理解嵌入式c_第4页
第4页 / 共20页
项目驱动——深入理解嵌入式c_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《项目驱动——深入理解嵌入式c》由会员分享,可在线阅读,更多相关《项目驱动——深入理解嵌入式c(20页珍藏版)》请在金锄头文库上搜索。

1、,深入理解嵌入式C,项目驱动-单片机应用设计技术,,5、深入理解嵌入式C,4、函数,3、存储器类型语言,2、开发工具与SDDC扩展,1、P89V51简介,,P89V51RB2功能框图,,P89V51RB引脚图,,开发工具与最小系统,开发工具简介: Tkstudio软件内置编辑器的多内核编译/调试环境。 支持80C51、ARM、AVR等内核。实验要学习使用。 SDCC (Smart Device C Compiler)是为8位微控制器开发的免费C编译器。 专门针对80C51资源做了扩展,特别是存储器类型、指针、函数方面做了扩充。,,C51中数据声明的格式,类型说明符修饰符 标识符=初值,例: u

2、nsigned char code Flag = 0x0f ;,类型说明符,修饰符(存储器类型),标识符,初值,这个定义给出的内容是:定义一个无符号的字符型变量,该变量的名字是Flag,初值为0x0f,该变量存放在ROM空间中。,说明:如果在一个定义中,没有修饰符,即没有说明存放的位置,则根据编译器编译模式的不同,有所区别。见PPT11页。具体数据类型见教材22页表1.3,,存储类型,DATA:直接寻址的片内数据存储器 BDATA:可位寻址的片内存储器 IDATA:间接寻址的片内数据存储器 PDATA:分页寻址的片外数据存储器 XDATA:片外数据存储器 CODE:程序存储器 具体例子见教材2

3、3页,,存储模式,1、小模式:small 默认片内数据存储器。和存储类型声明为data一样。 2、中模式:medium 默认外部数据区同一页中,和用pdata声明一样。 3、大模式:large 默认外部数据区64K区域(不限定同一页),和用xdata声明一样。 一般都使用small编译。 在TKS中如何选择存储模式: 工程配置目标目标输出界面最右边选择,,指针变量的存储,请看如下指针定义: xdata unsigned char *data p; data unsigned char *xdata p; xdata unsigned char *p; 显式指针p存放于内部RAM,指向外部RAM

4、 显式指针p存放于外部RAM,指向内部RAM 显式指针p存放于默认存储空间,指向外部RAM code unsigned char code *p; 显式 存于code 指向 code unsigned char *xdata p; 通用 存于xdata unsigned char *p; 通用 存于默认存储空间 char(*data fp)(void); 存放于data的函数指针,,通用指针和显式指针,1、通用指针 和标准C的指针声明相同 Char *str; Int *pnum; 用3个字节保存,最高字节表示数据空间信息,低两字节用来保存地址本身。 最高字节可能值如下: 0x00外部数据存储

5、器RAM(xdata/far) 0x40内部数据存储器RAM(idata/near) 0x60外部数据存储器页RAM (pdata) 0x80代码存储器ROM(code) 通用指针可以访问所有空间(除了bit),使用方便但速度慢,很多库函数使用通用指针。,,指针2,2、显式指针 定义时包括一个存储类型说明,并且总是指向次类型存储器空间。 data chat data *p xdata int *numtab code long data *powtab 由于存储类型编译时已经确定,因此最多只需要两个字节。指向idata、data、pdata(内部RAM,256单元以内)的指针只用1个字节保存。

6、指向code和xdata的指针用2个字节保存。 显式指针效率高,速度快,但指向确定因此不太方便。 两种指针效率对照表见教材28页表1.5,,函数1,1、函数参数和局部变量的存储问题 参数和局部变量可以分配(存储)在堆栈或一般数据空间(RAM)里。SDCC编译器默认分配这些变量到内部RAM中(小模式)或外部RAM(中模式或大模式)。 默认分配就导致了这些变量或参数在使用后是可以被覆盖的,因此这样的函数都不可重入。 如何分配局部变量和参数到堆栈: 1)函数声明里使用“reentrant”关键字使参数和局部变量被分配到堆栈中,从而使函数变得可重入。 2)函数定义前加上“#pragma stackau

7、to” 3) 使用编译参数-stack-auto 但这样会占用堆栈空间,因此要尽量少用。,,函数2,2、覆盖 为节省内存,编译器对未保存在堆栈中的局部变量和参数会进行覆盖(如果可能small模式下,函数没有调用其它函数,且次函数是不可重入的)。 有时候需要避免参数被覆盖,可以在函数定义前加上“#pragma nooverlay”。 1)比如中断服务程序中调用的不可重入函数。教材29页程序段。见下页 2)C51编译器不会对内嵌汇编做编译处理,因此汇编代码中如果调用C函数,可能导致此函数局部变量和参数被分配到可覆盖区域,因此这时候此函数应使用“#pragma nooverlay”。,,函数3,如果

8、没有#pragrma nooverlay的话,参数error可能会被覆盖从而导致不可预知运行结果。,,专用寄存器组的使用,1、使用方法: 函数声明后加“using”告诉编译器使用除了默认组0以外的寄存器组。 2、优点: 可以使中断服务程序更有效率,因为不用保存寄存器到堆栈。 3、注意的问题: 1)不同优先级的中断,只用不同的寄存器组。 2)中断服务函数中最好不调用其它函数,如果必须要调用,最好让这些函数和中断函数使用相同的寄存器组。,返回,,深入理解嵌入式C,本质,目的,方法,注意,C语言与汇编语言和机器语言一一对应,对比C语言代码与汇编语言的对应关系从而更好的理解C语言代码。,阅读编译手册查

9、看汇编代码,编译器不同版本,编译出的汇编语言不尽相同。甚至基本相同的C语言代码编译出来的汇编代码也不一定相同,,查看汇编代码方法,查看汇编源文件在输出目录一般有汇编元文件main.asm,但是用宏汇编写成,与反汇编看到的不同,借鉴了高级语言的部分特征。,查看汇编代码,查看反汇编在调试时查看反汇编代码 。需开启反汇编代码显示窗口。,,函数调用与参数传递,对比C51与对应的汇编程序分别观察无参数、1字节,2字节、3字节、4字节、2个参数、3个参数的参数传递过程,可以得到如下结论: SDDC51中,参数由左往右编号 1、1号参数传递通过SFR进行,根据参数大小依次使用DPL、DPTR、DPTR+B、

10、DPTR+B+A 2、从2号参数开始使用堆栈传递参数 3、参数压栈的顺序为参数编号的反序 4、参数压栈后由调用函数释放 详细汇编代码见课堂例子程序。,,函数返回,对比C51与对应的汇编程序分别观察无返回值、返回值分别为1字节、2字节、3字节、4字节返回值实现的汇编代码,可以得到如下结论: 参数返回值通过SFR传递,柑橘参数大小依次使用DPL、DPTR、DPTR+B、DPTR+B+A,,局部变量存储,C中,局部变量存储空间动态申请,进入定义了局部变量的函数时申请空间,退出函数时释放空间。 SDCC51局部变量存储规则: 1、优化掉部分未使用的和没有用的局部变量。 2、尽可能讲局部变量放在R0-R7中,其它局部变量放在堆栈中。 3、局部变量存储按照定义顺序由地址由低到高一次存储,高字节对应高地址。,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号