版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
4.1概述4.1.1嵌入式系统应用的编程语言汇编C目前使用的最多C++JAVA第4章ARM的C语言编程技术满足系统的实时性要求尽量减少执行代码和数据所占的空间在算法上的特殊考虑
充分使用宏定义与条件编译
运用好位操作
I/O端口变量的定义要使用修饰符volatile
编制中断服务程序是要注意有时要使用可重入函数
4.1.2嵌入式系统C语言程序设计考虑的问题
字符型最基本数据类型整型
浮点型尽量少用尽可能使用4.2数据类型整型常量的表达(1)十六进制数需在数字前加前缀0x(2)二进制数需转换成十六进制数表示2.I/O端口的变量一般要使用易变性修饰符volatile(含义为易变的)修饰使用volatile的修饰符定义的变量,表示对它的访问不能采用缓存,不能将对几次顺序的访问优化为一次访问。使用Volatil修饰的变量能反映I/O端口的实时变化。4.3常量与变量代码1:voidmain(void){int*a=0x58000000//定义I/O端口
*a=0//输出低电平*a=1//输出高电平*a=0//输出低电平
}程序的执行结果I/O端口保持为0
例:比较有无volatile修饰的变量的差异
代码2:voidmain(void){volatileint*a=0x0x5800000050000000//定义I/O端口
*a=0//输出低电平*a=1//输出高电平*a=0//输出低电平}程序的执行结果为I/O端口先输出为0,然后输出为1,最后再输出为0,即输出一个脉冲预处理指令:文件包含预处理指令宏定义预处理指令条件编译预处理指令#pragma4.4预处理指令1宏定义宏定义:用一个指定的标识符来代表一个数据或字符串。#define标识符数据(或字符串)例1:#definePI3.1415926其作用是PI定义后在程序中的PI代替数据1。例2:#defineU8unsignedchar,其作用是定义后在程序中的U8都用unsignedchar代替宏定义的基本思想是:一次定义,多次使用其优点是:可以用标识符来代替长的数据,减少需要输入的数据或字符串;用易于理解的标识符来代替那些不太好记的具体的数据,便于程序的理解和维护;有利于程序的修改和升级,当这个数据需要修改时,只需改动宏定义之处即可。其作用类似于汇编中的伪指令EQU还可以用指定的标识符来代表一个内存单元的数#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)地址定义后,程序中rUTRSTAT0代表(0x50000010)中的数RAM中的I/O寄存器标识符while(!(rUTRSTAT0&0x1));例:#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)……(0x50000010)中的数与1与后取反作为循环判断的条件也可以进行带参数的宏定义。#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)形式参数程序中宏调用WrUTXH0(0xa)的功能为:(0x50000020)=0xa数据类型地址#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)……WrUTXH0(0xa)带参数的宏RAM中的I/O寄存器#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)也可以进行带返回数据的宏定义。带返回数据的宏地址#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)……*Revdata=RdURXH0();程序中宏调用*Revdata=RdURXH0()的功能为:将(0x50000024)中的数据送到*
Revdata中RAM中的I/O寄存器#defineTRUE 1#definerUTRSTAT1(*(volatileunsignedchar*)0x50004010)#defineWrUTXH1(ch) (*(volatileunsignedchar*)0x50004020)=(unsignedchar)(ch)#defineRdURXH1() (*(volatileunsignedchar*)0x50004024)练习:嵌入式C语言编程经常用到位操作运算:& 与操作;例:x=rUTRSTAT0&0x4
| 或操作;例:x=x|0xf
y=PRSCVL|ADCCON^ 异或操作;例:a=a^a~
取反操作;例:c=~ c>> 右移操作;例:d=8>>3<< 左移操作;例:r=0x1<<15
PRSCVL=49<<6
4.5位运算#defineADCCON_FLAG(0x1<<15)#defineADCCON_ENABLE_START_BYREAD (0x1<<1)#definePRSCVL(49<<6)#defineADCCON_ENABLE_START(0x1)#defineSTDBM(0x0<<2)#definePRSCEN(0x1<<14)练习:子函数声明main()
{
……
函数调用
……
}子函数定义{
……}声明该函数使用该函数定义函数方式一先声明主函数后定义4.6函数的程序结构
函数定义{……
}main()
{
……
函数调用
……
}定义函数使用该函数方式二先定义主函数直接调用/*********************************************\ Copyright(c)2004-2007Zhangming@,Allrightsreserved. byZhangming2004.5.12----------------------程序功能---------------------------------串口通信Cmain函数----------------------创建与修正时间----------------------- 2004-5-12 创建2005-1-10修正*********************************************/4.7嵌入式系统C语言应用程序的结构#include<string.h>#include<stdio.h>#defineU8unsignedchar#defineTRUE 1#defineFALSE 0#pragmaimport(_use_no_semihosting_swi)//不使用软中断
/**********串口自发自收通信主函数***********/#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)//#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)//#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)//voidUart_SendByten(int,U8);charUart_Getchn(char*Revdata,intUartnum,inttimeout);voidARMTargetInit(void);voidhudelay(inttime);/*******主函数********/intmain(void){charc1[1];charerr;ARMTargetInit();//目标板初始化
while(1){Uart_SendByten(0,0xa);//向串口0发送“换行”符Uart_SendByten(0,0xd);//向串口0发送“回车”符err=Uart_Getchn(c1,0,0);//串口从超级终端接收数据Uart_SendByten(0,c1[0]);//串口向超级终端发送数据}}
/*****串口0向发送数据子函数*******/voidUart_SendByten(intUartnum,U8data){ while(!(rUTRSTAT0&0x4));// hudelay(10);//延时 WrUTXH0(data);//}
/******串口0接收数据子函数*****/charUart_Getchn(char*Revdata,intUartnum,inttimeout){ while(!(rUTRSTAT0&0x1));// *Revdata=RdURXH0();// returnTRUE;//串口0接收数据成功返回}
4.8嵌入式C语言程序设计技巧4.8.1变量定义4.8.2参数传递4.8.3循环条件4.8.1变量定义
在变量声明的时候,最好把所有相同类型的变量放在一起定义,这样可以优化存储器布局。由下例可以看出:对于局部变量类型的定义,使用short或char来定义变量并不是总能节省存储空间。有时使用32位int或unsinged
int局部变量更有效率一些,如下图所示:变量定义中,为了精简程序,程序员总是竭力避免使用冗余变量。但有时使用冗余变量可以减少存储器访问的次数这可以提高系统性能。
4.8.2参数传递
为了使单独编译的C语言程序和汇编程序能够互相调用,定义了统一的函数过程调用标准ATPCS。ATPCS定义了寄存器组中的{R0~R3}作为参数传递和结果返回寄存器,如果参数数目超过四个,则使用堆栈进行传递。内部寄存器的访问速度是远远大于存储器的,所以要尽量使参数传递在寄存器里面进行,即应尽量把函数的参数控制在四个以下。4.8.3循环条件
计数循环是程序中十分常用的流程控制结构,一般有以下两种形式:for(loop=1;loop<=limit;loop++)
for(loop=limit;loop!=0;loop--)这两种循环形式在逻辑上并没有效率差异,但是映射到具体的体系结构中时,就产生了很大的不同,如下图所示。
4.9C与汇编语言混合编程4.9.1ATPCS介绍4.9.2内嵌汇编4.9.3C和ARM汇编程序间相互调用4.9.1ATPCS介绍
ATPCS(ARM-ThumbProduceCallStandard)是ARM程序和Thumb程序中子程序调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。
寄存器的使用规则寄存器别名特殊名使用规则R0a1
参数/结果/scratch寄存器1R1a2
参数/结果/scratch寄存器2R2a3
参数/结果/scratch寄存器3R3a4
参数/结果/scratch寄存器4R4v1
ARM状态局部变量寄存器1R5v2
ARM状态局部变量寄存器2R6v3
ARM状态局部变量寄存器3R7v4wrARM状态局部变量寄存器4Thumb状态工作寄存器R8v5
ARM状态局部变量寄存器5R9v6sbARM状态局部变量寄存器6,在支持RWPI的ATPCS中为静态基址寄存器R10v7slARM状态局部变量寄存器7,在支持数据栈检查的ATPCS中为数据栈限制指针R11v8fpARM状态局部变量寄存器8/帧指针R12
ip子程序内部调用的scratch寄存器R13
sp数据栈指针R14
lr连接寄存器R15
pc程序计数器数据栈的使用规则根据堆栈指针指向位置的不同和增长方向的不同可以分为以下4种数据栈:
FD(FullDescending)
满递减
ED(EmptyDescending)空递减
FA(FullAscending)
满递增
EA(EmptyAscending)
空递增ATPCS规定数据栈为FD(满递减)类型,并且对数据栈的操作是8字节对齐的。
参数的传递规则参数个数固定的子程序参数传递规则:第一个整数参数,通过寄存器R0~R3来传递。其他参数通过数据栈传递。
参数个数可变的子程序参数传递规则:当参数不超过4个时,可以使用寄存器R0~R3来传递参数;当参数超过4个时,还可以使用数据栈来传递参数子程序结果返回规则
结果为一个32位的整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推。
NEXT4.9.2内嵌汇编
在C程序中嵌入汇编程序可以实现一些高级语言没有的功能,并可以提高执行效率。内嵌的汇编指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的变量定义,数据交换必须通过ATPCS进行。嵌入式汇编在形式上表现为独立定义的函数体。内嵌汇编指令的语法格式
__asm(“指令[;指令]”);ARMC汇编器使用关键字“__asm"。如果有多条汇编指令需要嵌入,可以用“{}”将它们归为一条语句。如:__asm{ 指令[;指令] … [指令]}需要特别注意的是__asm是两个下划线。
内嵌汇编指令的应用举例4.9.3C和ARM汇编程序间相互调用
在C和ARM汇编程序之间相互调用必须遵守ATPCS(ARM-ThumbProcedureCallStandard)规则。C和汇编之间的相互调用可以从以下这三方面来介绍:汇编程序对C全局变量的访问在C语言程序中调用汇编程序在汇编程序中调用C语言程序汇编程序访问全局C变量
汇编程序可以通过地址间接访问在C语言程序中声明的全局变量。通过使用IMPORT关键词引人全局变量,并利用LDR和STR指令根据全局变量的地址可以访问它们。对于不同类型的变量,需要采用不同选项的LDR和STR指令,如下所示:
unsignedchar LDRB/STRBunsignedshort LDRH/STRHunsignedint LDR/STRchar
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《高等数学2》课程教学大纲
- 2024年出售竹荪菌种合同范本
- 2024年出售垃圾车合同范本
- 2024年代还款三方协议书模板范本
- u007f关爱艾滋病病人
- 出科护理技术操作流程
- 人体解剖学培训课件
- 2024-2025学年第一学期期中考试八年级地理学科试卷
- 北京市大兴区2024~2025学年上学期七年级期中数学试卷(含答案)
- 广东省广州市外国语学校附属学校2023-2024学年七年级上学期期中考试语文试卷(含答案)
- ACS510变频器参数表
- G344项目临建工程施工方案-12号定稿
- 小学数学人教四年级上册(2022年新编)平行四边形和梯形认识平行四边形
- 少先队主题班会工作汇报模板009号课件
- 电气设备常见故障分析
- 人教版七年级数学上册 《实际问题与一元一次方程》教学课件(第1课时)
- 造纸和纸制品公司安全风险分级管控清单
- 双重预防体系培训考试卷(含答案)
- 共工怒触不周山-完整版PPT
- 多元统计分析习题及解答
- 国家开放大学电大公共行政学形考任务1-3答案(全)
评论
0/150
提交评论