原创 读书笔记之《C语音嵌入式系统开发》

2007-9-15 22:56 4975 4 4 分类: MCU/ 嵌入式

        前几天粗粗地读了Michael J.Pont编著的《C语音嵌入式系统开发》,感觉写的非常浅显易懂,并且似乎也不知不觉学到了一些知识点。我下面将记录我在读这书中的心得。


        嵌入式系统是一种应用系统,它至少包含一个可编程的计算机。


        第一章 嵌入式系统中的C语音编程


         先摘录一段文字:“如果每个项目开放都是从头编写新代码的话,没有一家软件公司在业务上可以基业常青。编程语言必须支持创建灵活方便的库,这样同类的项目可以重用那些经过充分测试的代码模块。当使用新的处理器或升级处理器时,整个代码系统移植到新系统应该是可行的,并且尽可能少费劲。”


         第二章 8051系列微控制器简介


          对于大多数现代CMOS芯片,功耗和EMI(电磁干扰)与震荡频率之间成类似线形的关系。因此需要选择合适的震荡频率,来平衡性能功耗和干扰。


         在台式PC上,当运行程序时候,程序代码常从磁盘复制到RAM中,程序从RAM执行。而大多数嵌入式系统中,程序从ROM就地执行。这就使得嵌入式系统对RAM的需求变少。RAM只用来存储程序执行时候的变量以及程序的堆栈。


         第三章 你好,嵌入式世界


         本章主要讲了如何利用KEIL软件实现软件仿真。特殊寄存器的定义和使用有些特殊。对应于每个特殊寄存器,我们都在头文件中进行声明和定义。如:


                      sfr P0 = 0x80;


          使用该寄存器的时候,只需要简单赋值,如:


                         P0 = 0xFF;


           如果定义了P0是个地址,那么给地址赋值的话应该是*P0 = 0xFF;但是,编译器知道如何处理特殊寄存器,故可以直接赋值。


           第四章  读取开关值


           本章给出了读两种不同的开关的实现代码。一种是判断开和关的状态,如开灯关灯。另外一种是需要判断何时按键松开,如数山羊计数等。同样需要主要的是20ms左右的抖动,具体的抖动时间可以看示波器。


           第五章 为代码添加结构


           本章是有关编程风格的论述。讲的也非常好。提出的关键点主要有3个。1是使用C来编写面向对象风格的代码。2是使用端口头文件,搜集项目使用的所有的端口的信息。3是项目头文件的创建和使用,封装硬件环境的各主要方面,如芯片类型、震荡频率等等信息。


           面向对象的C语音编程,方法是创建并使用文件类。将一个功能写在一个文件中,规定好成员函数和变量。将这个功能当作一个类来使用,并且可以方便地移植到其他项目中。


            规定好成员函数和变量后,就需要仔细部署这些东西,需要注意的是:


            公有成员函数在.c文件中实现,但是要在.h中声明。


            私有的成员函数只需要在.c文件中声明。并且声明的时候可以在函数前面加static进行修饰。


            公有的常数要在.h文件中定义,主要是指宏吧。


            私有变量和常数要在.c中定义。


            少数的一些全局变量要在.c中定义??对于这一点,可能还有更方便的写法。可以借鉴ucos那本书的方式。将全局变量统一写在.h中,全局变量前面用一个统一的宏来修饰,当第一次编译的时候,如果这个宏得到了定义,则这个变量被识别并且分配相应的内存空间,当第二次碰到的时候,宏没有被定义,则这个宏变成一个extern关键字,说明这个变量是一个外部全局变量,不会再分配空间了。还有种说法:.h文件中不要定义变量,因为每次编译的时候,都会给变量分配空间。


        第六章 满足实时性的限制条件


         开始考虑精确测量时间的问题,因为许多嵌入式系统必须满足实时性的限制条件。嵌入式系统的一个重要特性就是需要迅速地处理输入并产生输出,且必须以毫秒为计量尺度。


         实时性最怕的是while语句,这个意味着CPU会一直查询一个条件。


          本章讨论了两种延时,一种是软件延时,另外一种是使用定时器来实现精确延时。这些延时都是通过while来查询来实现的。


          如何克服while带来的不利影响哪?可以使用“循环定时溢出”。例如我们对AD转换数值,通常采用的语句是:


                  while ( (ADCON & ADC1)==0);


           上面的语句可能会碰到问题,导致CPU一直查询,程序不能继续向下执行。解决的办法是采用“循环定时溢出”,如下:


                  while (((ADCON &ADC1) == 0) && (++Timeout_loop != 0));


           这样,即使有一些原因导致 (ADCON & ADC1)==0一直成立,也会因为(++Timeout_loop != 0)不成立而推出循环,让程序不至于死等在原地。


            上面的定时溢出是软件实现的,可能不太精确,从而可以通过创建硬件定时溢出来实现精确的定时溢出,如:


                  while( ((ADCON & ADC1) == 0) && !TF0);


          以后写while的时候,一定要多想一个问题:这个while怎么样才能保证退出?


          第七章 创建嵌入式操作系统


          超级循环架构的缺陷是很难在相同的时间间隔来执行目的函数(任务)。为了得到周期性的函数执行且避免浪费处理器的周期,可以使用定时器中断。具体办法是在规律且精确的时间间隔产生中断(一个tick),此中断可以用来周期性地调用合适的用户函数(任务)。使用这个操作系统的时候,需要注意两个问题:第一最坏情况下任务的执行时间要小于tick时间。第二是每个微控制器一个中断原则。


          第八章 多状态系统和函数序列


          上面的定时中断驱动的操作系统适合于周期性的执行任务的能力。多状态系统有如下的特点:涉及一系列的系统状态,每个状态可能要调用一个或者多个函数,存在用来定义状态之间转换的规则,状态转换时,可那会调用一个或者多个函数。可以分成2类,多状态时间驱动,即状态转换只取决于时间。多状态输入/时间驱动式,即状态转换取决与时间的推移和系统的输入。实现方式是在每个状态都计量时间,到达时间后转换状态。


          第九章 使用串行接口


          RS232常被用作某种形式的数据流控制。异步协议可以有2.5%波特率的波动。可以由软件或者硬件实现,容许数据接收端通知发送端暂停数据传输。尽管可以使用硬件联络,这却需要额外的信号线。数据流控制最普通的方法就是Xon/Xoff控制(发送端发送一个字节的数据,接收端有能力接收更多的数据,他什么也不做,发送端又发送一个字节的数据,直到接收端不能再接收更多的数据,于是他给发送端返回发送控制s(Xoff)字符,发送端收到Xoff后停止发送,如果接收端准备好了,他发送控制q(Xoff)字符给发送端,发送端继续发送数据,这样周而复始。)


          软件采用的思路是,不是将所有的数据立即全部发送,而只是将想要发送的数据存储在一个缓冲区内,没过一个时间检查缓冲区内的数据,且发送一个字符。我们不需要等待每个字符发送完,发送数据本身的程序执行非常快,数据发送过程本身不占用CPU时间。发送数据的时候,先查询是否发送完了,然后在将需要发送的数据放入缓冲区,然后退出就行。如下:


    while( (++Timeout1) &&(TI == 0);


     SBUF= char;


          第十一章 学习总结


           本书的目的如下:


           考虑了嵌入式系统中处理器及编程语言的选择,展示了怎样在嵌入式C语言程序中利用面向对象的设计和编程中的关键特性,以达到了在以后的项目中代码易重复使用的目标。描述了在许多简单的嵌入式应用程序中使用的超级循环软件架构。描述了一种简单的嵌入式操作系统,适合于很广范围的嵌入式应用程序。这个操作系统由定时器中断驱动,提供了精确的系统时间控制,却占用不到1%的处理器功能。研究了控制单个端口管脚状态的方法。研究了端口管脚的读取以及机械开关的读取。描述了如何使用8051芯片的串行端口。提供了一个案例分析,说明怎么样在实际的应用中将以上所有的内容组织起来。


 


         

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条