首页 > 编程知识 正文

单片机c语言程序设计,单片机需要c语言基础吗

时间:2023-05-04 02:02:35 阅读:154075 作者:4086

原标题:单片机C语言编程:h文件与. c文件的关系!

来源:电子学专辑

一个. c文件对应一个. h文件是一个好的编程习惯,那么. c文件和. h文件的关系呢?

一. h文件与. c文件的关系:

到目前为止编写的程序是一个非常简单的程序,我从没想过自己会写. h文件。 我也不知道. h文件是用来做什么的,它和. c文件有什么关系。 不过,最近编写键盘程序,参考别人的程序的话,别人写的严格程序会附有Keyhit和Keyscan等. c文件中自己写的函数定义的“KEY.H”

我查了资料,发现. h文件是头文件,大概是Head的意思。 这是规范程序结构化设计的必要性,既可以实现大型程序的模块化,也可以实现根各模块的连接调试。

1、 h文件介绍:

在单片机C编程中,项目一般采用功能模块化结构化。 将一个项目分为多个功能,将各功能的相关程序放入一个c程序文档中,称为一个模块。 对应的文件名是模块名称。 通常,一个模块由两个文档组成,一个是头文件*.h,用于描述模块中的数据结构和函数原型。 另一个是c文件*.c,它具体实现数据实例或对象定义以及函数算法。

2、 h文件的作用

项目设计是对整个项目功能的详细描述,以及对每个模块的详细定义,即给出所有模块的头文件。 h头文件通常定义模块中每个函数的功能以及输入和输出参数的要求。 模块的具体实现由项目结构根据h文件进行设计、编程、调试完成。 为了安全和安保,在实现模块后,它将提供给项目的其他成员,以便可以连接到文件OBJ或库文件LIB。 因为不需要提供源程序的文件,一方面可以公开发行,保证开发者的所有权,另一方面可以防止他人有意或无意地修改产生不一致性,版本混乱。 因此,h头文件是项目详细设计和团队工作划分的依据,也是模块测试的功能说明。 要引用模块中的数据或算法,用包含include指定模块h头文件即可。

3、 h文件的基本构成

/*以下为键盘驱动的头文档*

#ifndef _KEY_H_ //防重复引用,如果未定义_KEY_H_,则编译以下语句

#define _KEY_H_ //此符号是唯一的,如果它已被引用一次,即#i nclude,则意味着定义符号_KEY_H_

/

Charkeyhit(void ); //击键no

unsignedCharKeyscan(void ); //取键值

#endif

二、尽量使用宏观定义#define

当我开始查看别人的程序时,我注意到在程序的开头,文件的后面有很多#define语句。 那个时候,我觉得替换和替换这么多标记,不是很麻烦吗? 完全没有理解这个写法的好处。 原本,用一个符号表示常数,有利于今后的修改和维护,修改时只要在程序开头进行更改,程序内所有使用的地方都可以被修改,节约时间。

#define KEYNUM 65//键的数量,用于Keycode[KEYNUM]

#define LINENUM 8//键盘行数

#define ROWNUM 8//键盘列数

注意事项:

1、宏名通常使用大写字母

2、宏的定义不是c句,最后不是加号

三.不盲目定义变量类型

以前写了程序,需要新的变量时,无论是在函数内还是在函数外,直接在程序的开头定义,原则上并没有错,但这是不可取的。

下面介绍C语言变量类型的相关概念。

从变量的作用范围来划分,分为局部变量和全局变量。

1、全局变量:是在函数外定义的变量,我以前在程序开头定义的变量都是全局变量,这里我犯了大忌,过度使用了全局变量。

有两个问题。 一个是全局变量在程序的所有执行过程中占用资源。 二是全局变量过多会导致程序通用性差。 因为全局变量是模块之间耦合的原因之一。

2、局部变量:函数内部定义的变量只在函数内部有效。

变量变量值存在的时间分为以下两种。

1、静态存储变量:在程序运行过程中分配固定的存储空间。

2、动态内存变量:在程序运行过程中根据需要动态分配内存空间。

具体来说,有四种存储方法:自动静态注册扩展

1、局部变量默认为auto类型,即动态存储,如果不提供初始值,则为不确定值。 另一方面,如果将局部变量定义为静态类型,则其值在函数内不变,初始值默认为0。

静态未签名字符STS; //键的状态变量

static unsigned char Nowkeycode; //此时的键码

static unsigned char Prekeycode; //上次的键码

static unsigned char Keydowntime; //按下矩形键盘,抖动时间变量

静态未加密密钥更新; //矩形键盘释放抖振去除时间变量

静态未用

char Onoffdowntime;//关机键按下去抖时间变量

static unsigned char Onoffuptime;//关机键释放去抖时间变量

static unsigned char onoff_10ms; //判断关机键中断次数变量,累计150次大约为3S,因为前后进了两个10ms中断

2、全局变量,编译时分配为静态存储区,可以被本文件中的各个函数引用。如果是多个文件的话,如果在一个文件中引用另外文件中的变量,在此文件中要用extern说明。不过如果一个全局变量定义为static的话,就只能在此一个文件中使用。

四、特殊关键字const volatile的使用

1、const

const用于声明一个只读的变量

const unsigned char a=1;//定义a=1,编译器不允许修改a的值

作用:保护不希望被修改的参数

const unsigned char Key_code[KEYNUM]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,

0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,

0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,

0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,

0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,

0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,

0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,

0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,

0x41

};//键码

const unsigned char Line_out[LINENUM]={0xFE,0xFD,0xFB,0xf7,0xEF,0xDF,0xBF,0x7F};//行输出编码

const unsigned char Row_in[ROWNUM]={0xFE,0xFD,0xFB,0xf7,0xEF,0xDF,0xBF,0x7F};//列输入编码

2、volatile

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

static int i=0;

int main(void)

{

...

while (1)

{

if (i)

dosomething;

}

}

/* Interrupt service routine. */

void ISR_2(void)

{

i=1;

}

程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致dosomething永远也不会被调用。如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。

一般说来,volatile用在如下的几个地方:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2、多任务环境下各任务间共享的标志应该加volatile;

3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。返回搜狐,查看更多

责任编辑:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。