您的位置 首页 电源

AVR笔记6:C言语优异编程风格

作为一个初学者如何具有良好的程序设计风格呢?我想引用一个关于初学者请教编程大师的故事让读者自己去领悟。有一位编程大师,他写非结构化

作为一个初学者怎么具有杰出的程序设计风格呢?我想引证一个关于初学者讨教编程大师的故事让读者自己去领会。

有一位编程大师,他写非结构化的程序,一位初学者刻意模仿他,也写非结构化的程序。当他让大师看他的前进时,大师批评了他的非结构化程序:“ 对一位编程大师适宜的东西未必对一个初学者相同适宜,在逾越结构化之前,你有必要了解编程之道。” 我个人认为作为一个初学者应该踏踏实实的打好程序设计的根底,不要急于求成,舍近求远。我走过不少弯路,期望咱们能和我相同能紧记编程大师的劝告:“对编程大师适宜的东西未必对一个初学者相同适宜”。

本文所描绘的优异编程风格适合于大部分言语,文章中或许说到你不是很了解的概念,没有联系,你定心的读下去,当你运用AVR一个月之后,你什么都理解了。

AVR c言语优异编程风格

文件结构

模块化的程序应该是有一个很好的程序结构的。AVR C言语程序有两种用户文件,.c程序文件,.h头文件,程序中编写过程中需求在.c文件中包括.h头文件。初学者往往呈现重复包括或许头文件包括过错的问题,我其时也经常为这种过错而忧愁。下面我以我写的电机驱动例程来给咱们阐明一下,优异的编程文件结构。

这个工程中有8个文件,一个阐明文件,如下图:下载程序比方avrvi.com/down.php?file=examples/motor_control.rar”>电机操控事例。

我写的成型的程序的文件个数基本上都是偶数,由于每一个结构化的函数界说.c文件都会对应一个.h文件。main.c对应config.h。咱们来看看各文件的包括联系。下面咱们看看这些文件的包括联系与内容:[引荐的文件包括次序与联系]

  • 一切.c文件都包括了config.h文件。如: #include “config.h”
  • 在config.h 中有如下代码:
    #include "delay.h" #include "device_init.h" #include "motor.h"
  • 这样做就不简单呈现过错的包括联系,为了防备假如,咱们还引入了宏界说与预编译。如下:
    #ifndef _UNIT_H__ #define _UNIT_H__ 1 //100us extern void Delay100us(uint8 n); //1s extern void Delay1s(uint16 n); // n <= 6 ,when n==7, it is 1. //1ms extern void Delay1ms(uint16 n); #endif 第一次包括本文件的时分正确编译,而且#define _UNIT_H__ 1,第2次包括本文件#ifndef _UNIT_H__就不再建立,越过文件。 预编译还有更多的用处,比方能够依据不同的值编译不同的句子,如下: //#pragma REGPARMS #if CPU_TYPE == M128 #include  #endif #if CPU_TYPE == M64 #include  #endif #if CPU_TYPE == M32 #include  #endif #if CPU_TYPE == M16 #include  #endif #if CPU_TYPE == M8 #include  #endif
  • #include 与 #include “filename” 的差异 :前者是包括体系目录include下 的文件,后者是包括程序目录下的文件。

变量名与函数名

变量以及函数命名应该依照尽量短,按需长,具有实际意义。能够经过下划线或许大小写结合的办法组合动词和名词组成变量函数名。下面比照好的命名办法与欠好的命名办法:

  1. 好的:Delay100us();
    欠好的:Yanshi();
  2. 好的:init_devices();
    欠好的:Chengxuchushihua();
  3. 好的:int temp;
    欠好的:int dd;

外部调用

  1. 首先在模块化程序的.h文件中界说extern
    //端口初始化 extern void port_init(void); //T2初始化 void timer2_init(void); //各种参数初始化 extern void init_devices(void);
  2. 模块化程序的.c文件中界说函数,不要在模块化的程序中调用程序,及不要呈现向timer2_init();这样函数的运用,由于你今后不知道你究竟什么当地调用了函数,导致程序调试难度添加。能够在界说函数的过程中调用其他函数作为函数体。
    // PWM频率 = 体系时钟频率/(分频系数*2*计数器上限值)) void timer2_init(void) { TCCR2 = 0x00; //stop TCNT2= 0x01; //set count OCR2 = 0x66; //set compare TCCR2 = (1<
    
  3. 在少量几个文件中调用函数,在main.c中调用大部分函数,在interupts.c中依据不同的中止调用服务函数。
    void main(void) { //初始作业 init_devices(); while(1) { for_ward(0); //默许速度工作 正 Delay1s(5); //延时5s motor_stop(); //中止 Delay1s(5); //延时5s back_ward(0); //默许速度工作 反 Delay1s(5); //延时5s speed_add(20); //加快 Delay1s(5); //延时5s speed_subtract(20); //减速 Delay1s(5); //延时5s } }

宏界说

宏界说首要用于两个当地:

  1. 一是用得十分多的指令或句子,运用宏将其简化。
    #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif #define MIN(a,b) ((ab)?(a):(b)) #define ABS(x) ((x>)?(x):(-x)) typedef unsigned char uint8; typedef signed char int8; typedef unsigned int uint16; typedef signed int int16; typedef unsigned long uint32; typedef signed long int32;
  2. 二是运用宏界说便利的进行硬件接口操作,再程序需求修正时,只需求修正宏界说即可,而不需求满篇去找指令行,进行修正。
    //PD4,PD5 电机方向操控假如更改管脚操控电机方向,更改PORTD |= 0x10即可。#define moto_en1 PORTD |= 0x10 #define moto_en2 PORTD |= 0x20 #define moto_uen1 PORTD &=~ 0x10 #define moto_uen2 PORTD &=~ 0x20 //发动TC2守时比较和溢出 #define TC2_EN TIMSK |= (<<1OCIE2)|(1<
    

关于注释

为了添加程序的可读性,便利合作者读动程序,或许程序作者在一段时间之后还能看懂程序,咱们需求在程序中写注释。

  1. 在比较特别的函数运用或许指令调用的当地加单行注释。运用办法为:
    Tbuf_putchar(c,RTbuf); // 将数据加入到发送缓冲区并开中止 extern void Delay1s(uint16 n); // n <= 6 ,when n==7, it is 1.
  2. 在模块化的函数中运用具体阶段注释:
  3. 在文件头上加文件名,文件用处,作者,日期等信息。

要清楚,注释是为了便利阅览,增强程序的可度性,不要舍本求末,不要给很简单咱们都能看理解的程序加注释,不要让注释淹没了你的程序结构。关于函数,变量等尽量运用文件名自注释的办法,及经过文件名就能够知道意思。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/257338.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部