加入因仑 登录
因仑“3+1”工程特种兵精英论坛 返回首页

jerryzhai的个人空间 http://bbs.enlern.com/?136 [收藏] [复制] [分享] [RSS]

日志

AVR编程感悟

热度 10已有 1244 次阅读2014-8-5 10:59 |系统分类:职场文化

AVR编程感悟

 学习AVR单片机已有将近一个月的时间了,下面我想跟大家分享一下关于AVR单片机的编程思想:

以前在学校用的单片机都是51的,有NXP的,MCS的,和刚刚来因仑“3+1”特种兵训练营时用的STC15系列的,这三个单片机也基本上玩熟了,因之前都是写上层应用,一些编程的观念,特别是在玩了STC15系列后有了很大的改变,下面我把最近的一些编程中认识到的问题及想法先记录下来,当个备忘录吧。

首先是“编程规范”的思想:

以前的编程思想我就不跟大家分享了,大家懂就好,也不是说不堪入目,那样就太涨别人士气灭自己威风了,我只想就经过这近一个月的编程和在这过程中接触的一些高手来说说自己的感想,大家都知道对于程序员来说,能工作的代码并不等于“好”的代码。“好”代码的指标很多,包括易读、易维护、易移植和可靠等。然而,很少有程序员知道什么样的程序是安全的程序。很多程序只是表面上可以干活,还存在着大量的隐患,这其中也有C语言自身的原因,因为C语言是一门难以掌握的语言,其灵活的编程方式和语法规则对于一个新手来说很可能会成为机关重重的陷阱。首先我们来看看排版: 严格采用阶梯层次组织程序代码,函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case 语句下的情况处理语句也要遵从语句缩进要求。 程序块的分界符(C/C++ 语言的大括号‘{ 和‘})应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if for do while switch case 语句中的程序都要采用如上的缩进方式。 各层次缩进的风格采用TAB缩进(TAB宽度原则上使用系统默认值)比如说这是我最近才写的程序:

// INT0中断服务程序

#pragma interrupt_handler int0:2

void int0(void)

{

       if(PIND&0x40)

              ;

       else

       {

              delay_ms(20);

              counter++;

              if(counter >= 16)

                     counter = 0;

       }

 

}

注释:注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。通过对函数或过程、变量、结构等正确的命名以及合理地组织代码的结构,使代码成为自注释的——清晰准确的函数、变量等的命名,可增加代码可读性,并减少不必要的注释——过量的注释则是有害的。 注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。 您比如说:

void Read_Temperature(void)

{

    DS18B20_Init();                 //DS18B20初始化

    Write_Byte(0xcc);

    Write_Byte(0x44);

    delay_us(600);

    DS18B20_Init();                 //DS18B20初始化

    Write_Byte(0xcc);

    Write_Byte(0xbe);

    Temp_Value[0] = Read_Byte();    //第一次读取数据放入低位

    Temp_Value[1] = Read_Byte();    //第二次读取数据放入高位

 

}

 

函数头部应进行注释:函数头部应进行注释,列出:函数的目的/ 功能、输入参数、输出参数、返回值、调用关系(函数、表)等。您比如说:

/*******************************************************

//函数名称:delay_ms(uint k)

//函数功能:延时子程序

//入口参数:k,延时时间参数

//返回参数:无

********************************************************/

 

/*******************************************************

*   程序功能:外部中断触发

*   接线说明:核心板JP2 PA0-PA7连接到系统底板静态数码管显示电路JP71PD2PD3接到JP74上的DK0DK1

*   实验现象:按下DK0数码管加1,按下DK1数码管减1

*         : 2014/7/24

*         : 翟志刚

*******************************************************/

    其次我想讲一下程序代码的“封装”思想:

    最近一直在做网络课程体系,软件的工作都是我和我们团队战友搞定的,当然了,资源是很有限,写程序真的不是特别清楚,也没有去想过自己的程序中所有的东西怎么分配的,有点“活的不明不白”。原来4KRAM可以干好多好多事情的,包括LCD的控制显示,485通信,控制多个模块的工作,接收PC的控制命令,按键的控制等等。对于128,它的代码空间已经足够大了,所以可以将一些功能啥的都封装起来,这些一点问题没有,STC15系列也是同理,但最近这两天用的ATmega16系列,让我豁然发现,并不是所有的程序都适用这个原则的。开始用结构体将相关功能封装起来,在把基本的功能(IO口的配置,定时器的配置,串口的配置,看门狗的配置,中断的配置,串口的解包,EEPROM的接口)完成后,我了个去,ICC提示代码空间已用了80%多了,这还玩个P啊,先不管了,将串口的处理完成后,90%多了,先不管了,用C写了个简单的上位机,调试了大半天,终于连上位机和这些简单的功能调通了。还要用IO模拟另一个串口啊,没空间了,咋整涅,精简代码呗,想想看那些可以精简,首先想到的是函数调用的地方,将只用到了一次的直接将代码搬过去,函数干掉,多次用到的保留,函数调用最多只要两层(main函数本身不包括),清理了下,少了点,然后觉得还不行,应该还能清理,后来发现那些结构体封装的变量了,因为从结构体变量成员的访问需要在结构体的基址上加偏移玩的,所以估计这块会多消耗一些额外的指令的,所以将结构体通通干掉,改用多个全局变量,对其直接访问(这也是我原先最痛恨的一种写代码的方式),试了下,少了好多,代码变成70%多了,不错,继续看看,然后发现解包函数中有些共用的语句,包括正常的处理和异常的处理,想着,干脆放一块,用两个go to跳过去得了,试了下,恩,又小了些,已经很满足了。至此程序已改的和原先设计的结构完全不一样了,有点“面目全非”了,不过实用性提高了很多,将IO模拟的另一个串口的接收完成后,代码空间80%多一点,还好,还有其他的余地来干一些事情,到此我的工作也暂时完成了。此时我认识最深刻的就是稀缺资源的嵌入式设备编程时要尽量的用全局变量,尽量直接访问,少些函数,少用调用,多用goto,当然了,需要斟酌着用。完全和原先的观念相反。对于RAM使用的认识,对于很小的RAM设备,能共用就共用,必然ATmega16这块芯片,串口的首发的buff完全可以用一个来实现,刚开始我也用的两个,但后来在用IO模拟另一个串口是发现RAM不够用了,因128RAM30个字节还要用到函数栈空间,程序的空间只剩下可怜的90多个字节了,一条串口命令最长还有17个字节,所以很是吃紧了,后来干脆将串口的收发合到一起,因为只有在收完了才会发送的,所以在发送时关闭接收中断得了。RAM终于足够IO模拟用了。另外实在不够,还可以用128字节的EEP Rom做中转,还是比较可观的。另外一个就是函数栈空间,这里面的空间包括函数调用的地址保存,局部变量的保存,所以嘛这就是函数为什么尽可能的少调用,因为函数里面少不了局部变量,调用的多了,将栈空间用完,栈溢出,你就哭吧,程序某些功能正常,某些功能异常。最开始,为了确认板子程序启动了,在main的开始部分添加了个20字节的b u f,惨了。。。后来终于被我发现这个罪魁祸首了!

    另外一些算是常识性的东西,最近印象比较深刻的,记录下吧:

    每个有效的功能变量都有范围的,一定要限定边界值

    如果代码空间比较富裕,对EEPROM的操作最好做加校验,好处是在EEPROM被冲掉后,程序检测出异常会做异常的保护,也可以用来调试,提醒系统有问题。

    看门狗一定是要的

    AD采样,一定要多次采样,求平均值,这样可以减少异常的干扰

    程序一定要有版本号,否则,版本多了,哼哼…..够你查找的了!

    按键不仅要检测按下,还要检测释放按键,否则长按着…..(这个就看需求了)

    驱动一定要隔离,一定要做成模块,为上层应用提供接口,上层应用不要直接控制驱动相关的一些寄存器啊等等

    AVR的单片机呢,熔丝位(fuse)一定要烧写的,根据datasheet来确定,但是一定要记住,不要随便烧,否则,你懂得,板子都会废了

    对于每一个功能性的变量,要确定好其实际范围,符号类型,来选择适当的数据类型及符号类型,不要将有符号和无符号的数进行比较。


路过

鸡蛋
9

鲜花

握手

雷人

刚表态过的朋友 (9 人)

发表评论 评论 (10 个评论)

回复 还你一世界 2014-8-5 11:09
技术贴必须赞!!!
回复 liliuyang 2014-8-5 11:09
排版都不对额 。
回复 jerryzhai 2014-8-5 11:11
liliuyang: 排版都不对额 。
额。。。这个我没注意到!
回复 jerryzhai 2014-8-5 11:12
还你一世界: 技术贴必须赞!!!
纯属个人鄙见,不是啥技术贴,嘿嘿。。。
回复 杨玉玺 2014-8-5 11:18
大神有没有15系列的资料呀求分享
回复 jerryzhai 2014-8-5 11:29
杨玉玺: 大神有没有15系列的资料呀求分享
这个。。。let me 看看
回复 墨奚 2014-8-5 12:16
格式让我们沉思
回复 杨玉玺 2014-8-5 12:33
好,等着你的好消息
回复 张衍波 2014-8-5 15:17
这个是个好东西
回复 伊海 2014-8-9 08:55
内容丰富。感触很多

facelist

您需要登录后才可以评论 登录 | 加入因仑

返回顶部