当前位置:首页 > 公众号精选 > 嵌入式微处理器
[导读]1. 流水线被指令填满时才能发挥最大效能,即每时钟周期完成一条指令的执行(仅指单周期指令)。如果程序发生跳转,流水线会被清空,这将需要几个时钟才能使流水线再次填满。因此,尽量少的使用跳转指令可以提高程序执行效率,解决发案就是尽量使用指令的“条件

1. 流水线被指令填满时才能发挥最大效能,即每时钟周期完成一条指令的执行(仅指单周期指令)。如果程序发生跳转,流水线会被清空,这将需要几个时钟才能使流水线再次填满。因此,尽量少的使用跳转指令可以提高程序执行效率,解决发案就是尽量使用指令的“条件执行”功能。


2. 在LPC2200系列中:


可以通过过下面的程序延迟10毫秒:

for(i=0;i<200;i++){for(j=0;j<200;j++);}


3. 通过下面语句将一个16位的变量放在两个8位的变量中。


//IP数据报总长度高字节

IpHeadUint8[10]=(IpHead.e_ip.Crc&0xff00)>>8;

//IP数据报总长度低字节

IpHeadUint8[11]=IpHead.e_ip.Crc&0x00ff;


4. 在对全部数组元素赋初值时,可以不指定数组长度。


eg;inta={1,2,3,4,5};


但如果当输出第a[5]以上的元素时,系统回输出随机数值,所以使用此方法时,不能使用超过初始值元素以上的元素。


5. 由于ADS先天性的对printf不支持;因此不便于我们调试,可以利用串口输出来代替printf来调试。


6. 用或运算,可使某位置为1,其它位不变


eg: PINSEL0 |= 0x00000005; //设置串口引脚


使第0位和第二位置一,其他位不变。


7. 函数指针


1> C语言中函数名直接对应于函数生成的指令代码在内存中的地址,因此函数名可以直接赋给指向函数的指针。


2> 调用函数实际上等同于“调用指令+参数传递处理+回归位置入栈”,本质上最核心的操作是将函数生成的目标代码的首地址赋给CPU的PC寄存器。


3> 因为函数调用的本质是跳转到某一个地址单元的code去执行,所以可以“调用一个根本就不存在在函数实体。


4> int (*p);定义p是一个指向函数的指针变量,次函数返回带回整型的返回值。*P两侧的括号不能省略,表示p先于*结合,是指针变量,然后再与后面的结合,表示此指针指向函数。


区别:int *p表示这个函数的返回值是指向整型变量的指针。


说明:


(1) 指向函数的指针变量的一般定义形式为:


数据类型 (*指针变量名);


1> 此处的“数据类型”是指函数返回值的类型


(2) 返回指针值的函数:


类型名 *函数名(参数表)


eg: int * func(int x,int y)


func是函数名,调用它以后能返回一个指向整型数据的指针。x,y是func的形参。


区别方法:


a.从右往左找第一个括号,括号里面的是函数的形参。

b.括号外面的第一个标识符是函数的名字,函数前面的表示函数的返回数值。


8. 数组指针


1>int (*p)[4]


表示*p有4个元素,每个元素为整型。也就是p所指的对象有4个整型元素的数组,既P是行指针。


2> 指针数组


Ø 一个数组,其元素均为指针类型数据,称为指针数组;即指针数组中的每一个元素都相当于一个指针变量。


Ø 一维指针数组的定义形式为:


类型名 *数组名[数组长度]


eg:int *p[4]:


作用:它用于指向若干个字符串,使字符串处理更加方便灵活。适用于一个二维字符串数组,其中每一行的字符数组的长度各不相同


eg:char * name={“Follow me”,”BASIC”,”GreatWall”};


9. 结构体


1> 可以用结构体变量做实参。但是用结构体变量作实参时,采取的是“值传递”的方式,将结构体变量所占的内存单元的内容全部顺序递给形参。形参也必须是同类型的结构体变量。


eg:pint(su);//注在此处su为结构体


注:这种传递方式在空间和时间上开销较大,如果结构体的规模较大时,开销是很可观的。


2> 用直向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参


eg:print(&su);//注在此处su为结构体


10. 共用体


1> 共用体把几种不同数据类型的变量存放在同一块内存里。公用体中的变量共享同一块内存。


2> 定义公用体类型变量的一般形式为:


union 共用体名

{

成员列表;

}变量列表;


3>在共用体中同一块内存可以用来存放几种不同类型的数据,但在某一时刻只能在其中存放一个成员变量。共用体变量中起作用的成员是最后一次存入的数据。


eg: union data{int i;char c;double d;};union data a;


共用体变量a中的成员i,c,d三个变量在内存中从同一个地址开始存储。如进行如下赋值:


a.i = 100;

a.c = ‘A’;


那么此时共用体变量a中的成员i已经没有值了,因为存储该值的内存现在已经被用来存储成员c的值了。


3> 共用体变量的长度取决于其成员的最大长度:


说明:


结构体变量所占内存的长度是各个成员的总和,每个成员分别占有自己的存储空间。共用体变量所占内存的长度是其最长成员的长度。当然,编译器出于提高访问效率的目的,在编译分配存储空间时往往要进行对齐操作。


对齐操作以最大基本类型为准。即以最大基本类型为基本单元。若按实际算下的长度不是基本单元的整数倍,则其实际长度应该是基本单元的整数倍。


(在TurboC中不进行对齐,在Linux中进行对齐)


11. CPU字长与存储器位宽不一致处理


例如:使用共用体来解决这一冲突:


union send_temp{

uint16 words;

uint8 bytes[2];

}send_buff;

eg:send_buff.bytes[0]=a;//此处a 是8位

send_buff.bytes[1]=b;//此处 b 是8位;

此时就将8位字拼成了16位字存储了。

发送时send(send_buff.words)就可以每次发送一个16位的数据了。


12. C语言符号优先级:


1>复合赋值运算符号:

a+=3*5;

等价于a=a+(3*5);


13.一个常见的调试策略是把一些printf函数的调用散布于程序中,确定错误出现的具体位置。但是,这些函数调用的输出结果被写入到缓冲区中,并不立即显示于屏幕上。事实上,如果程序失败,缓冲输去可能不会被实际写入,因此得到的错误位置就是错误的。解决的方法是在每个用于调试的printf函数之后立即调用fflush函数即可得到。


printf(“something or other”);fflush(stdout);


14.关键字volatile的用法


volatile变量可能用于如下几种情况:

1>设备的硬件寄存器(如:状态寄存器)

2>一个中断服务子程序中会访问到的全局变量

3>多线程应用中被几个任务共享的变量。


15.关键字register的用法:


当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。


(1) 只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量;


(2) register是一个"建议"型关键字,意指程序建议该变量放在寄存器中,但最终该变量可能因为条件不满足并未成为寄存器变量,而是被放在了存储器中,但编译器中并不报错(在C++语言中有另一个"建议"型关键字:inline)。


16.对于程序代码,已经被烧录在FLASH或ROM中,我们可以让CPU直接从其中读取代码执行,但通常这不是一个好办法,我们最好在系统启动后将FLASH或ROM中的目标代码拷贝入RAM中后再执行以提高取指令速度。


CPU对各种存储器的访问速度,基本上是:

CPU内部RAM > 外部同步RAM > 外部异步RAM > FLASH/ROM


17. 宏定义


C语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。


1>宏定义“像”函数;

2>宏定义不是函数,因而需要括上所有“参数”;

3>宏定义可能产生副作用。因而不要给宏定义传入有副作用的"参数"。



-END-


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

嵌入式开发作为信息技术领域的重要分支,其涉及的语言种类繁多,各具特色。这些语言的选择取决于目标平台的特性、性能需求、开发者的熟练程度以及项目的具体要求。本文将详细介绍几种常见的嵌入式开发语言,包括C语言、C++、汇编语言...

关键字: 嵌入式开发 C语言

Java语言和C语言是两种不同的编程语言,它们在语法、特性和应用领域上有许多差别。下面将详细介绍Java语言和C语言之间的差异以及它们各自的技术特点。

关键字: Java语言 C语言 编程

嵌入式系统是一种专门设计用于特定应用领域的计算机系统,它通常由硬件和软件组成,并且被嵌入到其他设备或系统中,以实现特定的功能。在嵌入式系统的开发过程中,选择适合的编程语言是至关重要的。C语言是一种被广泛应用于嵌入式系统开...

关键字: 嵌入式 计算机 C语言

C语言是一种广泛应用于软件开发领域的编程语言。它是由贝尔实验室的Dennis Ritchie在20世纪70年代初创建的,旨在为UNIX操作系统的开发提供一种高级编程语言。C语言具有简洁、高效、可移植性强等特点,因此成为了...

关键字: C语言 操作系统 应用程序

嵌入式系统是现代生活中无处不在的一部分。它们包括了我们的家电、汽车、智能手机、医疗设备等等。这些系统的工作必须高效、可靠,因为它们往往控制着生活中的关键方面。而C语言作为一种广泛用于嵌入式系统开发的编程语言,其质量和稳定...

关键字: 嵌入式系统 C语言 编程

在嵌入式系统开发领域中,C语言是使用最广泛的编程语言之一。它具有高效、灵活和可移植的特点,成为嵌入式系统设计师的首选语言。本文将介绍C语言编程的基本概念、特点以及在嵌入式系统开发中的应用。

关键字: 嵌入式系统 C语言 编程

C语言编译器是一种用于将C语言源代码转换为可执行程序的软件工具。它的主要功能是将C语言代码翻译成机器语言,以便计算机能够理解和执行。C语言编译器通常包括预处理器、编译器、汇编器和链接器等多个组件,它们协同工作以完成编译过...

关键字: C语言 编译器 Microsoft Visual C++

Matlab和C语言的区别是:1、用途不同;2、语法不同;3、运行速度不同;4、可移植性不同;5、代码管理不同。Matlab是一种数值计算和科学计算工具

关键字: matlab语言 C语言 系统编程

单片机是一种集成电路,它包含了中央处理器、存储器、输入输出接口和时钟等基本部件。单片机广泛应用于各种电子设备中,如家用电器、汽车电子、医疗设备等。单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用...

关键字: 单片机编程 单片机 C语言

一直以来,嵌入式都是大家的关注焦点之一。因此针对大家的兴趣点所在,小编将为大家带来嵌入式的相关介绍,详细内容请看下文。

关键字: 嵌入式 C语言
关闭
关闭