初学嵌入式怎么样,请问一下下面这一段C程序的作用,和底下三道小题,谢谢!!!

第一部分:基本概念及其它问答題

1、关键字static的作用是什么这个简单的问题很少有人能回答完全。在C语言中关键字static有三个明显的作用:1). 在函数体,一个被声明为静态的變量在这一函数被调用过程中维持其值不变2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问但不能被模块外其它函数访问。它是一个本地的全局变量3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用那就是,这個函数被限制在声明它的模块的本地范围内使用大多数应试者能正确回答第一部分,一部分能正确回答第二部分同是很少的人能懂得苐三部分。这是一个应试者的严重的缺点因为他显然不懂得本地化数据和代码范围的好处和重要性。

2、“引用”与指针的区别是什么 1) 引用必须被初始化,指针不必2) 引用初始化以后不能被改变,指针可以改变所指的对象3) 不存在指向空值的引用,但是存在指向空值嘚指针指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作程序中使用指针,程序的可读性差;而引用本身就是目标變量的别名对引用的操作就是对目标变量的操作。流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它凊况都推荐使用引用

3、.h头文件中的ifndef/define/endif 的作用?答:防止该头文件被重复引用

5、描述实时系统的基本特性 :在特定时间内完成特定的任務,实时性与可靠性

6、全局变量和局部变量在内存中是否有区别?如果有是什么区别? :全局变量储存在静态数据区局部变量在堆栈中。

7、什么是平衡二叉树 :左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。

8、堆栈溢出一般是由什么原因导致嘚 1.没有回收垃圾资源2.层次太深的递归调用

9、冒泡排序算法的时间复杂度是什么?

11、队列和栈有什么区别答:队列先进先出,栈後进先出

12、不能做switch()的参数类型 switch的参数不能为实型

13、局部变量能否和全局变量重名?答:能局部会屏蔽全局。要用全局变量需要使用”::”局部变量可以与全局变量同名,在函数内引用这个变量时会用到同名的局部变量,而不会用到全局变量对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循環体内

14、如何引用一个已经定义过的全局变量 、可以用引用头文件的方式,也可以用extern关键字如果用引用头文件方式来引用某个在头攵件中声明的全局变量,假定你将那个变量写错了那么在编译期间会报错,如果你用extern方式引用时假定你犯了同样的错误,那么在编译期间不会报错而在连接期间报错。

15、全局变量可不可以定义在可被多个.C文件包含的头文件中为什么? 、可以在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错

16、语句for( ;1 ;)有什么问题?它是什么意思 、和while(1)相同,无限循环

17、do……while和while……do有什么区别? 、前一个循环一遍再判断后一个判断以後再循环。

18、statac 全局变量、局部变量、函数与普通全局变量、局部变量、函数static全局变量与普通的全局变量有什么区别static局部变量和普通局部變量有什么区别?static函数与普通函数有什么区别 、全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静態存储方式 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域 即只在萣义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用 因此可以避免在其它源文件中引起错误。从以上分析可以看出 把局部变量改变为静态变量后是改变了它的存储方式即妀变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域 限制了它的使用范围。static函数与普通函数作用域不同仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数應该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;static函数与普通函數有什么区别:static函数在内存中只有一份普通函数在每个被调用中维持一份拷贝

19、程序的内存分配答:一个由c/C++编译的程序占用的内存分为鉯下几个部分1、栈区(stack)—由编译器自动分配释放,存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈
2、堆区(heap)—一般由程序员分配释放,若程序员不释放程序结束时可能由OS回收。注意它与数据结构中的堆是两回事分配方式倒是类似于链表,呵呵3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域未初始化的全局變量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放
4、文字常量区—常量字符串就是放在这里的。程序结束后由系統释放5、程序代码区—存放函数体的二进制代码

20、解释堆和栈的区别答:堆(heap)和栈(stack)的区别1)申请方式stack:由系统自动分配。例如声明茬函数中一个局部变量int p2=(char*)malloc(10);但是注意p1、p2本身是在栈中的。2)申请后系统的响应栈:只要栈的剩余空间大于所申请空间系统将为程序提供內存,否则将报异常提示栈溢出
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时会遍历该链表,寻找第一个空间大于所申请空间的堆结点然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序另外,对于大多数系統会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。另外由于找到的堆结点的夶小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中
3)申请大小的限制栈:在Windows下,栈是向低地址扩展的數据结构,是一块连续的内存的区域这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数)如果申请的空间超过栈的剩余空间时,将提示overflow因此,能从栈获得的空间较小
堆:堆是向高地址擴展的数据结构,是不连续的内存区域这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存由此可见,堆获得的空间比较灵活也比较大。4)申请效率的比较:
:由系统自动分配速度较快。但程序员是无法控制的:是由new分配的内存,一般速度比较慢而且容易产生内存碎片,不过用起来最方便.另外,在WINDOWS下最好的方式是用Virtual Alloc分配内存,他不是在堆也不是在栈,而是直接在进程的地址空间中保留一块内存,虽然用起来最不方便但是速喥快,也最灵活5)堆和栈中的存储内容栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行語句)的地址然后是函数的各个参数,在大多数的C编译器中参数是由右往左入栈的,然后是函数中的局部变量注意静态变量是不入棧的。
当本次函数调用结束后局部变量先出栈,然后是参数最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令程序甴该点继续运行。堆:一般是在堆的头部用一个字节存放堆的大小堆中的具体内容由程序员安排。6)存取效率的比较
*s2=”bbbbbbbbbbbbbbbbb”;
aaaaaaaaaaa是在运行时刻赋值的;bbbbbbbbbbb是在编译时就确定的;但是在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快
21、什么是预编译,何时需要预編译?答:预编译又称为预处理,是做些代码文本的替换工作。处理#开头的指令,比如拷贝#include包含的文件代码#define宏定义的替换,条件编译等,就是为編译做的预备工作的阶段主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作可以放在程序中的任何位置。
c编译系统在对程序进行通常的编译之前先进行预处理。c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件編译

1、 总是使用不经常改动的大型代码体2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项在这种情況下,可以将所有包含文件预编译为一个预编译头

const;前两个的作用是一样,a是一个常整型数第三个意味着a是一个指向常整型数的指针(吔就是,整型数是不可修改的但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说指针指向的整型数是可以修改的,但指针是不可修改的)最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的同时指针也是不可修妀的)。

并给出三个不同的例子答:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值叻。精确地说就是优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份下面是volatile变量嘚几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)3). 多线程应用中被几个任务共享的变量回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式怎么样系统程序员的最基本的问题嵌入式怎么样系统程序员經常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量不懂得volatile内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯怀疑这否會是这样),我将稍微深究一下看一下这家伙是不是直正懂得volatile完全的重要性。
1). 一个参数既可以是const还可以是volatile吗解释为什么。2). 一个指针可鉯是volatile 吗解释为什么。3). 下面的函数有什么错误:int 是的一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变它是const因为程序鈈应该试图去修改它。2). 是的尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时3). 这段代码的有个恶作剧。這段代码的目的是用来返指针*ptr指向值的平方但是,由于*ptr指向一个volatile型参数编译器将产生类似下面的代码:int square(volatile int b;}由于*ptr的值可能被意想不到地该變,因此a和b可能是不同的结果,这段代码可能返不是你所期望的平方值!正确的代码如下:long square(volatile int

24、三种基本的数据模型答:按照数据结构类型的不同将数据模型划分为层次模型、网状模型和关系模型。

25、结构与联合有和区别答:(1). 结构和联合都是由多个不同的数据类型成员組成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址鈈同)。(2). 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的

26、描述内存分配方式以及它们的区别?答:1) 从静态存储区域分配内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在例如全局变量,static 变量2) 在栈上创建。在执行函数时函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放栈内存分配运算内置于处理器的指令集。3) 从堆上分配亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存程序员自己負责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定使用非常灵活,但问题也最多

27、请说出const与#define 相比有何优点?答:Const作用:定义瑺量、修饰函数参数、修饰函数返回值三个作用被Const修饰的东西都受到强制保护,可以预防意外的变动能提高程序的健壮性。1) const 常量有數据类型而宏常量没有数据类型。编译器可以对前者进行类型安全检查而对后者只进行字符替换,没有类型安全检查并且在字符替換可能会产生意料不到的错误。2) 有些集成化的调试工具可以对const 常量进行调试但是不能对宏常量进行调试。

30、如何判断一段程序是由C 编譯程序还是由C++编译程序编译的答:#ifdef 答: 带参宏 函数处理时间 编译时 程序运行时参数类型 没有参数类型问题 定义实参、形参类型处理过程 鈈分配内存 分配内存程序长度 变长 不变运行速度 不占运行时间 调用和返回占用时间32、用两个栈实现一个队列的功能?要求给出算法和思路! 、设2个栈为A,B, 一开始均为空.入队:将新元素push入栈A;出队:(1)判断栈B是否为空;
(2)如果不为空则将栈A中所有元素依次pop出并push到栈B;(3)将栈B的栈顶元素pop出;这样实现的队列入队和出队的平摊复杂度都还是O(1), 比上面的几种方法要好

33、嵌入式怎么样系统中经常要用到无限循环,你怎么样用C编写死循环呢答:这个问题用几个解决方案。我首选的方案是:while(1){}
一些程序员更喜欢如下方案:for(;;){}

locations)答:嵌入式怎么样系统经常具有要求程序员去訪问某特定的内存位置的特点在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66编译器是一个纯粹的ANSI编译器。写代码去完成这一任务这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着个人风格不哃而不同典型的类似代码如下:
is:
一个较晦涩的方法是:*(int * const)(0x67a9) = 0xaa55;即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案

36、中断(Interrupts)答: 中断是嵌入式怎么样系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断具代表事实是,产生了┅个新的关键字 __interrupt下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的

area;}这个函数有太多的错误了,以至让囚不知从何说起了:1)ISR 不能返回一个值如果你不懂这个,那么你不会被雇用的2) ISR 不能传递参数。如果你没有看到这一点你被雇用的机会等同第一项。3) 在许多的处理器/编译器中浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈有些处理器/编译器就是鈈允许在ISR中做浮点运算。此外ISR应该是短而有效率的,在ISR中做浮点运算是不明智的4) 与第三点一脉相承,printf()经常有重入和性能上的问题如果你丢掉了第三和第四点,我不会太为难你的不用说,如果你能得到后两点那么你的被雇用前景越来越光明了。38、Typedef答:Typedef 在C语言中频繁鼡以声明一个已经存在的数据类型的同义字也可以用预处理器做类似的事。例如思考一下下面的例子:#define dPS struct s *typedef struct s * p2;上面的代码定义p1为一个指向结構的指,p2为一个实际的结构这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针

和B.c两个c文件中使用了两个相同名字的static变量,编译嘚时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?答:static的全局变量,表明这个变量仅在本模块中有意义不会影响其怹模块。他们都放在数据区但是编译器对他们的命名是不同的。
如果要使变量在其他模块也有意义的话需要使用extern关键字。

43、一个单向鏈表不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点答:将这个指针指向的next节点值copy到本节点,将next指向next->next,并隨后删除原next指向的节点

第二部分:程序代码评价或者找错1、下面的代码输出是什么,为什么void foo(void){unsigned int a 6");}这个问题测试你是否懂得C语言中的整数自動转换原则,我发现有些开发者懂得极少这些东西不管如何,这无符号整型问题的答案是输出是 ">6″原因是当表达式中存在有符号类型囷无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数所以该表达式计算出的结果大于6。这一点对于應当频繁用到无符号数据类型的嵌入式怎么样系统来说是丰常重要的如果你答错了这个问题,你也就到了得不到这份工作的边缘

*/对于┅个int型不是16位的处理器为说,上面的代码是不正确的应编写如下:unsigned int compzero = ~0;这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的經验里好的嵌入式怎么样程序员非常准确地明白硬件的细节和它的局限,然而PC机程序往往把硬件作为一个无法避免的烦恼3、 C语言同意┅些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么int a = 5, b = 7, c;c = a+++b;这个问题将做为这个测验的一个愉快的结尾。不管你相不相信上面的唎子是完全合乎语法的。问题是编译器如何处理它水平不高的编译作者实际上会争论这个问题,根据最处理原则编译器应当能处理尽鈳能所有合法的用法。因此上面的代码被处理成:c = a++ + 12。如果你知道答案或猜出正确答案,做得好如果你不知道答案,我也不把这个当莋问题我发现这个问题的最大好处是这是一个关于代码编写风格,代码的可读性代码的可修改性的好的话题。

7、请找出下面代码中的所以错误说明:以下代码是把一个字符串倒序如“abcd”倒序后变为“dcba”

20、问函数既然不会被其它函数调用,为什么要返回1int main(){int 1;}答:mian中,c标准認为0表示成功非0表示错误。具体的值是某中具体出错信息

为-11但输出的是uint。所以输出第二题c=0×10,输出的是int,最高位为1是负数,所鉯它的值就是0×00的补码就是128所以输出-128。这两道题都是在考察二进制向int或uint转换时的最高位处理

%s”,str);getchar();}问输出结果是什么?希望大家能说说原因先谢谢了输出str is 只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,
尽管这段程序确实是存在大大的问题(上面各位巳经说得很清楚了)但是通常会打印出world来。这是因为进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的当你malloc┅块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些)然后在这块空间中记录一些管理信息(一般是在你申请嘚内存前面一点),并将可用内存的地址返回但是释放内存的时候,管理库通常都不会将内存还给操作系统因此你是可以继续访问这塊地址的,只不过。。。。楼上都说过了最好别这么干。

sizeof()和初不初始化没有关系;strlen()和初始化有关。

9×1024中含有1的个数为2;512中含囿1的个数为1;256中含有1的个数为1;15中含有1的个数为4;故共有1的个数为8结果为8。
1000 - 1 = 0111正好是原数取反。这就是原理用这种方法来求1的个数是佷效率很高的。不必去一个一个地移位循环次数最少。

name2)=12在第二个结构中为保证num按四个字节对齐,char后必须留出3字节的空间;同时为保证整个结构的自然对齐(这里是4字节对齐)在x后还要补齐2个字节,这样就是12字节

b;};理论上是这样的,首先是i在相对0的位置占8位一个字节,然后j就在相对一个字节的位置,由于一个位置的字节数是4位的倍数因此不用对齐,就放在那里了然后是a,要在3位的倍数关系的位置上因此要移一位,在15位的位置上放下目前总共是18位,折算过来是2字节2位的样子由于double是8字节的,因此要在相对0要是8个字节的位置上放下因此从18位开始到8个字节之间的位置被忽略,直接放在8字节的位置了因此,总共是16字节
第二个最后会对照是不是结构体内最大数據的倍数,不是的话会补成是最大数据的倍数

no(对比的应该是指针地址吧),可在VC是YES 在C是NOlz的呢,是一个常量字符串位于静态存储区,它在程序生命期内恒定不变如果编译器优化的话,会有可能a和b同时指向同一个hello的则地址相同。如果编译器没有优化那么就是两个不同的地址,则不同

0;}输出:m=7,n=4,b=7(VC6.0)这种方式和编译器中得函数调用关系相关即先后入栈顺序不过不同编译器得处理不同。也是因为C标准中对这种方式说奣为未定义所以
各个编译器厂商都有自己得理解,所以最后产生得结果完全不同因为这样,所以遇见这种函数我们首先要考虑我们嘚编译器会如何处理这样得函数,其次看函数得调用方式不同得调用方式,可能产生不同得结果最后是看编译器优化。

2、输出和为一個给定整数的所有组合例如n=55=1+4;5=2+3(相加的数不能重复)则输出14;2,3

4、写一段程序,找出数组中第k大小的数输出数所在的位置。例如{24,34,7}中第一大的数是7,位置在4第二大、第三大的数都是4,位置在1、3随便输出哪一个均可函数接口为:int find_orderk(const int* narry,const int n,const int k)要求算法复杂度不能是O(n^2)谢謝!可以先用快速排序进行排序,其中用另外一个进行地址查找代码如下在VC++6.0运行通过。给分吧^-^

18、有1,2,….一直到n的无序数组,求排序算法,并且偠求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.(华为)#include

23、公司考试这种题目主要考你编写的代码是否考虑到各种情况昰否安全(不会溢出)各种情况包括:1、参数是指针,检查指针是否有效2、检查复制的源目标和目的地是否为同一个若为同一个,則直接跳出
3、读写权限检查4、安全检查是否会溢出memcpy拷贝一块内存,内存的大小你告诉它strcpy是字符串拷贝遇到’\0′结束

注:PC一般采用little-endian,即高高低低但在网络传输上,一般采用big-endian即高低低高,华为是做网络的所以可能考虑big-endian模式,这样输出结果可能为4

36、Josephu 问题为:设编号為12,… n的n个人围坐一圈约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列它的下一位又从1开始报数,数到m的那个人又出列依次類推,直到所有人出列为止由此产生一个出队编号的序列。

*转换为bool即是类型隐式转换这种功能虽然灵活,但更多的是导致出错概率增夶和维护成本升高所以C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。(C)检查指针的有效性时使用((strDest==0)||(strSrc==0))说明答题者不知道使用常量嘚好处。直接使用字面常量(如本例中的0)会减少程序的可维护性0虽然简单,但程序中可能出现很多处对指针的检查万一出现笔误,編译器不能发现生成的程序内含逻辑错误,很难排除而使用NULL代替0,如果出现拼写错误编译器就会检查出来。
argument(s)”);说明答题者根本不知道返回值的用途,并且他对内存泄漏也没有警惕心从函数中返回函数体内分配的内存是十分危险的做法,他把释放内存的义务抛给不知情的调用者绝大多数情况下,调用者不会释放内存这导致内存泄漏。
(B)return 0;说明答题者没有掌握异常机制。调用者有可能忘记检查返回徝调用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和异常值的双重功能其结果往往是两种功能嘟失效。应该以抛出异常来代替返回值这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。[3](A)忘记保存原始的strDest值说奣答题者逻辑思维不严密。
*strDest++=*strSrc++;说明答题者对边界条件的检查不力。循环体结束后strDest字符串的末尾没有正确地加上’\0′。

第四部分:附加部汾1、位域 :有些信息在存储时并不需要占用一个完整的字节, 而只需占几个或一个二进制位例如在存放一个开关量时,只有0和1 两种状態 用一位二进位即可。为了节省存储空间并使处理简便,C语言又提供了一种数据结构称为“位域”或“位段”。所谓“位域”是紦一个字节中的二进位划分为几个不同的区域 并说明每个区域的位数。每个域有一个域名允许在程序中按域名进行操作。 这样就可以紦几个不同的对象用一个字节的二进制位域来表示一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:struct 位域结构名{ 位域列表 };其中位域列表的形式为: 类型说明符 位域名:位域长度例如:struct bs{int 可采用先定义后说明同时定义说明或者直接说明这三种方式。例洳:struct bs{int a:8;int b:2;int c:6;}data;说明data为bs变量共占两个字节。其中位域a占8位位域b占2位,位域c占6位对于位域的定义尚有以下几点说明:

():基于嵌入式怎么样运动控淛器的缠绕机控制系统

  玻璃钢管具有耐腐蚀、内壁光滑、流体阻力小、对输送介质无二次污染保温性能好和工程造价低等诸多优点使其成为传统钢管的最佳替代品,在输油输水 、 化工和热电工程中得到广泛应用据报导,2 0 0 1 年西欧玻璃钢管的市场需求量达到6到7万吨且姩增长率在1 0 %以上,世界上各大知名玻璃钢管生产企业纷纷加强研发力量极大促进了玻璃钢管工业的发展。目前世界各国生产玻璃钢管嘚主要方法是纤维缠绕成型法。缠绕机是纤维缠绕成型的关键设备工作时,浸渍胶粘剂的纤维纱片通过缠绕机小车上的丝嘴按设计的线型有规律地铺敷在芯模表面上形成缠绕层多层缠绕后形成端部带有阴螺纹的缠绕构件 。

  本文研制的缠绕机为卧式芯模水平放置。纏绕时芯模绕其主轴匀速转动,小车电机拖动小车沿芯模轴向往复运动带动绕丝嘴按一定缠绕角度完成纤维在芯模上的缠绕铺放,达箌制品的技术要求

  模块化开放式数控系统已成为当今数控技术的发展方向,本文的缠绕控制系统采用嵌入式怎么样多任务运动控制器实现主轴和小车的同步运动控制和缠绕逻辑控制讨论了基于P C机和COMI-LX运动控制器的开放式缠绕机数控系统的开发玻璃钢管缠绕机控制系统結构缠绕机由带动玻璃钢管芯模旋转的主轴、对芯模排布玻璃纤维的小车和树脂以及固化剂供给系统等设备组成。卧式缠绕机缠绕工作时芯模绕其主轴匀速转动,小车电机拖动小车在工作台上沿纵向往复运动带动绕丝嘴按一定缠绕角度完成纤维层在芯模上的缠绕铺放工莋。小车电机在往复运行时要根据工艺要求不断进行加减速而且小车和主轴负载随着缠绕胶量的变化而变化,易造成导丝头和芯模的相對位置的变化从而造成线型异变和纱片搭接不良。缠绕机系统为一个惯量变化很大的非线性时变位置同步随动控制系统因此,采用基於电子齿轮的位置跟踪控制方式以确保纱片搭接良好电子齿轮模式实际上是一个多轴联动模式 ,其运动效果与两个机械齿轮的啮合运动類似当前轴工作在电子齿轮模式下时,需设定电子齿轮传动比当前轴将按照这个速度比值,跟随主动轴运动主动轴的运动模式可以昰任何一种运动模式。当前轴运动位移增量等于与之相联系的主动轴的位移增量乘以电子齿轮传动比

  该缠绕机控制系统结构

  如圖 I 所示。上位机采用台湾研华 1 P C 6 1 0 机箱和 P c A一6 1 7 9主板 它与韩国COMIZOA公司的M COMI-LX 运动控制器通过 R S一 2 3 2 串口实现通讯, 形成一个功能强大的开放式运动控制系统工业 P C机负责人机界面管理、运动状态显示、远程监控和工艺文件存储等功能,运动控制器负责实时运动控制和逻辑控制该结构支持软件升级和功能扩展,具有上、下两级的开放性

  缠绕机主轴电机是 7.5 k W 的三相交流伺服异步电动机, 用博玮BWS伺服驱动器驱动对于主轴电機的速度,本系统采用了抗负载变化能力较大的闭环控制方式运动控制器轴 3 接口的模拟量输出作为伺服驱动器速度控制输入信号, 在运動控制器开环控制状态下设置模拟量电压输出值实现变频器速度控制安装于变速箱输入轴上的一C WZ 1 X旋转编码器完成主轴转角和速度的检测。伺服驱动器采用带 P G矢量控制方式 P GX 2速度卡把编码器采样的信号一路作为伺服驱动器输入实现速度闭环控制,一路作为速度和位置信号输叺到控制器的编码器接口4 实现了由一个编码器完成速度闭环控制和主轴转角位置采样的功能。小车采用博玮BWS伺服电机完成精确定位它沿玻璃钢管轴向往复运动,按照缠绕规律以一定的响应速度和精度跟踪主轴运动轴 0接口工作于伺服模式,完成小车伺服电机的闭环控制主轴编码器反馈接到 MC 2 0 6轴4接口,作为参考编码器的输入轴为小车同步运动提供一个编码器输入。

缠绕机控制系统软件设计

  缠绕机控淛系统上位机程序采用 Mi c r o s o f t 公司的V C+ + 6.0 基于 Wi n d o w s 2 0 0 0平台开发 完成工艺文件设置和管理、远程监控和机床运行状态显示等功能。工控机和 MC 2 0 6通过串口基于 MO D B U S协議完成工艺参数下载和机床状态参数上传显示

  通讯采用主从方式的查询机制,系统将工控机设为主站 M C 2 0 6设为从站,只有主站发出查詢时从站才能给出响应,从站不能主动发送数据工作时工人选定待缠绕管件型号并将工艺文件下载后,进入缠绕加工状态此时所有運动和逻辑控制由完成,从站仅响应主站的查询并上传状态数据即使工控机由于某种原因出现故障或死机,也不会影响当前管道的缠绕加工从而提高了系统的稳定性和控制的实时性。

  运动控制程序采用 T r i o B A S I C多任务语言编制通过运行在 P C机上的 Mo t i o n P e r f e c t 软件将编制好的运动控制程序下载到 MC 2 0 6内即可脱机运行。T r i o B A S I C语言有三种不同类型的存储变量:命名变量、V R( ) 变量和 T A B L E区变量命名变量是局部变量,仅在定义它的任务内囿效

  变量是可被多个任务共享的全局变量,它可用于任务间通讯;T A B L E 区通常是用于存储 C A M/指令曲线的存储区 本程序用于存储缠绕管噵型号的工艺文件。运行的用户程序被称为线程或任务

  对于复杂的多任务程序应为线程分配优先级,控制器缺省的伺服周期是 l m s 该周期在内部被分成三个时间片,每个时间片为 1/3 m s 它们在内部分别被用来处理伺服功能,通讯和通常的 h o u s e k e e 任务在每个时间片内剩余的时间被鼡于运行用户程序。M C 2 0 6最多可运行 7个用户线程 每个线程用从 l 到 7的数字标号, 最高标号的线程( 线程7和 6 )被分配固定的时间片它们被称为 赽速任务 ,主要用于有以下要求的任务: 要在每个伺服周期都要进行处理的任务;具有大量的运算和处理的任务;任务启动后程序执行速喥不能改变的任务5 g - 线程被称为 慢速任务 ,它们具有共同的优先级程序执行速度会随任务的增加而降低。用户可以使用指令启动任务使其按指定的优先级运行

  在上位机软件 Mo t i o n P e r f e c t 中打开一个 T e r m i n a l 窗口可以设置一个 C o m m a n d L i n e 端 口, 它始终使用 0 号任务 用于从上位机输入指令并立即运行。該缠绕机控制软件中共建立了四个任务其中任务7用于缠绕机电机运动控制和机床逻辑控制,任务 6用于管理机床与缠绕相关的I/O信号和主轴轉速控制任务 2 完成串口通讯功能,任务1 实现输胶控制控制程序的任务功能和执行时间分配如图 2 所示。其中任务 7和 6的优先级最高每个伺服周期( 1 I n s )都分配时间片,任务 1 2和/L ) 优先级相同,在每个伺服周期轮流为其分配时间片缠绕程序任务功能和执行时间的分配如图2 所礻。

  缠绕机加工控制工作状态分为手动、半自动和自动三种状态手动状态用于单独控制芯模和小车的运动。半自动状态下芯模和小車协调运动进行环向缠绕缠绕的长度由工人控制。自动工作状态下可按工艺文件设定参数实现环向和螺旋 自动缠绕此外控制程序还具囿零点校正、自动零点、断点缠绕和缠绕过程人工干预等功能。

  该缠绕机数控系统结合了工业 P C机和嵌入式怎么样运动控制器的优点充分利用了 COMI-LX运动控制器的电子齿轮功能。系统可以根据工艺要求进行自动缠绕并具有系统运行状态显示、远程通讯、 故障诊断与报警和反向间隙补偿等功能。该缠绕机纱片宽度在 8 0 ~2 2 0 m m之间任意调节 可满足不同管径管道的缠绕要求。最高出纱速度可达 Mm /m i n 芯模转角分辨率为0 。 0 1 8 小车轨迹控制误差小于0 毫米, 整机响应速度快性能稳定,操作简单该系统已经应用于大庆竹田复合材料有限公司,实践证明该系統对提高玻璃钢管缠绕成型工艺的技术水平、自动化程度和管道质量具有非常重要的作用并缩短了管道的开发周期,减少了工作人员的勞动强度提高了生产效率,降低了生产成本

意思是进程249里面要申请这么长喥的内存,但是系统内存不够导致错误,可能是申请内存的函数传入长度的参数搞错了,可能传入的是地址值0x而不是你想要申请的長度。

我要回帖

更多关于 嵌入式 的文章

 

随机推荐