嵌入式C语言编程小知识总结

发布者:WhisperingWave最新更新时间:2018-11-22 来源: eefocus关键字:嵌入式  C语言编程  小知识 手机看文章 扫描二维码
随时随地手机看文章

 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)。


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


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


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


15. 宏定义


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


1>宏定义“像”函数;


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


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


关键字:嵌入式  C语言编程  小知识 引用地址:嵌入式C语言编程小知识总结

上一篇:堆栈溢出技术从入门到精通
下一篇:C语言中随机函数应用

推荐阅读最新更新时间:2024-03-16 16:18

一种用VHDL设计嵌入式Web Server的方案
摘要:近几年嵌入式Internet开始迅猛发展,但绝大多数嵌入式Internet都使用微控制器和相应的软件来实现。本文介绍一种基于硬件来实现嵌入式Web Server的方案。该方案的核心思想是用VHDL语言来设计实现,并且用FPGA进行验证。 关键词:VHDL Internet协议 控制信息协议 数据报 最近几年随着Internet应用的迅猛发展,Internet的通信协议,特别是TCP/IP协议,已成为嵌入式Internet的主体构架;然而,仅仅使用嵌入TCP/IP协议对许我应用来说远远不够,它们要求更高层次的信息传输和交换方式。在原有嵌入TCP/IP协议基于上加入HTTP/1.1将构成一个功能较为简单的嵌入式Web Server
[嵌入式]
ARM7嵌入式系统在车辆调度中的应用
一、车辆调度系统的整体设计: 整个系统包括四个部分(1)通信主站;(2)车载从站;(3)通信链路。(4)系统监控部分。下面对各个部分的功能做一个简单的介绍。 (1)通信主站:完成信息的转发,它是连接系统监控部分和车载从站的纽带,它将从系统监控部分来的信息转发给车载从站。并且接收车载从站的信息,并将信息上传给系统监控部分。 (2)车载从站:被监控的对象,接收监控调度命令,并可以返回自己的状态信息。状态信息的取得是依靠在车载从站中的GPS接收机来完成车辆位置和速度信息等的采集工作。 (3)通信链路:完成通信主站和车载从站的信息传递及通信主站和系统监控部分的信息交互。其中前者在本次设计中是以GSM手机模块做为通信的工具,而后者是
[单片机]
ARM7<font color='red'>嵌入式</font>系统在车辆调度中的应用
基于运行嵌入式Linux操作系统的ARM/DSP多机I2C通信设计方案
  引言   在很多嵌入式控制系统中,系统既要完成大量的信息采集和复杂的算法,又要实现精确的控制功能。采用运行有嵌入式Linux操作系统的ARM9微控制器完成信号采集及实现上层控制算法,并向DSP芯片发送上层算法得到控制参数,DSP芯片根据获得的参数和下层控制算法实现精确、可靠的闭环控制。   1 多机系统组成   该多机控制系统以ARM9微控制器s3c2440为核心,采用I2C总线挂载多个DSP芯片TMS320F28015作为协控制器,构成整个控制系统的核心。   1.1 S3C2440及TMS320F28015简介   Samsung公司的处理器S3C2440是内部集成了ARM公司ARM920T处理器内核的32位微控制器,资源
[单片机]
基于运行<font color='red'>嵌入式</font>Linux操作系统的ARM/DSP多机I2C通信设计方案
嵌入式系统的通信规约管理平台设计
摘要:论述设计通信规约管理平台的必要性与可行性;借鉴操作系统的PCB思想,结合面向对象的方法学提出通信规约管理平台设计的核心思想——用户填写静态规约说明书。规约管理平台根据规约书生成通信规约控制块,由规约控制块控制、管理并适应千差万别规约程序的运行。 关键词:平台 规约说明书 CPCB 动态描述静态描述 逻辑描述 引言 众所周知,通信的双方必须遵守相同的协议,报文才能互相识别。目前,不同行业间的通信协议千差万别。为解决不同通信协议间的计算机系统通信问题,人们普遍采用的措施是一个具体规约对应一段程序。如果出现新规约,只能由通信双方共同配合,由一方按另一方的标准修改或增加通信规约来解决问题。这种解决措施使得通信系统的适应能力不
[应用]
DVR系统嵌入式Linux解决方案
应用前景: 近几年来,DVR(数字视频录像)在安防监控领域应用越来越广泛,传统的模拟录像技术已经逐渐被数字录像技术取代,数字录像技术可以达到更好的图像质量和提供更大的存储容量。目前DVR已广泛应用到金融、文博、酒店、交通、商业、医院、工厂、学校、住宅小区物业管理等各个领域。从目前趋势看,多媒体监控系统的应用领域还在不断扩展。 目前,已经有一些公司推出了基于X86 PC-based的数字视频录像机(DVR),但是功耗、成本、体积、稳定性方面还是有所欠缺,PC-BASED的DVR产品正逐步为嵌入式取代。华恒科技目前提供基于PowerPC的嵌入式linux开发平台可以满足这方面应用的设计要求。该设计以PowerPC处理器和专用音视频编
[应用]
基于Nagle算法的嵌入式TCP协议
随着嵌入式系统的发展,在嵌入式系统中实现网络连接已成为研究热点,广泛使用的廉价8/ 16 位嵌入式处理器的性能不足与网络协议的复杂构成了尖锐的矛盾。 嵌入式Internet 技术的核心是在嵌入式系统中实现TCP/ IP 协议簇, TCP 协议的机制比较复杂,对8/ 16 位嵌入式处理器的存储能力和运算能力要求较高,必须进行简化。 本文提出了一种适用于8/ 16 位低速处理器的简化TCP 协议。对其性能进行分析发现,在嵌入式网络大量使用小数据包,造成网络带宽利用率低下并且容易造成网络阻塞。 因此在简化的TCP 协议中引入Nagle 算法,大幅度减少了嵌入式网络中发送的小数据包个数,提高了吞吐率,并减少了所需的带宽。 简化TC
[嵌入式]
基于MSP430的嵌入式DTMF拨号解码器实现方案
引言 DTMF(双音多频)信号是电话网中常用的信令,无论是家用电话、移动电话还是程控交换机上,多采用DTMF信号发送接收号码。DTMF技术还可以用于电力线载波通信等场合。可见,DTMF拨号和解码在通信系统及其它方面有着广泛的应用。通常DTMF信号的检测采用专用芯片或DSP来实现,但其成本较高。本文介绍了一种低成本的基于MSP430F133的DTMF拨号解码器实现方案。 MSP430F133是TI的一款16位RISC结构MCU,最短指令周期为150ns,含有8KB Flash ROM,256B RAM并内置12位ADC。 DTMF信号 DTMF信号是将拨号盘上的0~9、A~D及*/E、#/F共16个字符,用音频范围的8个频率来表
[单片机]
基于MSP430的<font color='red'>嵌入式</font>DTMF拨号解码器实现方案
USB知识——500mA的总线供电模式
USB的规范中规定一个USB的根集线器(root hub)最多只能提供500mA的电流,这一方面是为了减轻PC机的负担,另一方面是保护USB的主控制器(Host Controller),目前USB主控制器往往集成在南桥中。理论上来讲,任何一个USB Hub应该使用一个电源开关来防止过电流,但目前至少有10%以上的主板没有使用电源开关或使用一些低性能的元器件以节省成本。当外设需要多于500mA的电流时,就需要采用自供电模式了。这对于USB硬盘的应用是一个瓶颈,也是一个挑战。2.5英寸以上的硬盘本身就需要超过500mA,所以必须自供电,自供电可以使用电池,也可以使用稳压源,这对于移动设备来说都不是理想的方法。有一种折衷的方法是连接两个U
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved