【51】51单片机C语言中.c文件和.h文件的关联

1)h文件作用

1 方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明;
2 提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h)。

2)h文件里应该有什么
    常量,结构,类型定义,函数,变量申明。

3)h文件不应该有什么
    变量定义, 函数定义。

4)extern问题
    对于变量需要extern;
    对于函数不需要因为函数的缺省状态是extern的.如果一个函数要改变为只在文件内可见,加static。

5)include包含问题
    虽然申明和类型定义可以重复,不过推荐使用条件编译。

#ifndef _FILENAME_H,

#define _FILENAME_H

……

#endif

6)应该在那儿包含h文件
    在需要的地方.比如某个提供接口的h文件仅仅被1.c文件需要,那么就在1.c文件里包含。                


编写的程序一般会有.H文件和相对应的.C文件,.H文件是声明所用,.C文件是其函数实现部分。在调用时只要包含.H文件即可,我们没有听说过#i nclude "delay.c"这类的程序,同时也不提倡使用这个形式。

         
在delay.h文件中:                //对调用的函数声明
#ifndef __DELAY_H__

#define __DELAY_H__


extern void Delayms(unsigned int n);

#endif


在delay.c文件中:                 //函数实现部分

#i nclude

//for crystal 11.0592M

void Delayms(unsigned int n)

{

       unsigned int i,j;

       for(j=n;j>0;j--)

       for(i=112;i>0;i--);

}

 

在主程序main.c中

#i nclude                 //在主程序包含.h文件,不能包含.c文件

……


上述方法仍然要求每建立一个工程就需要把对应的头文件复制到工程的文件夹里,这样看来仍然是比较麻烦的,这时还有另外一中方法就是将做好的头文件放在一个文件夹中,然后将这个文件夹整体拷贝到..KEILC51INC下面,以后若需要使用某个头文件,就如使用KEIL自带的头文件一样方便了,在主函数mani()之前有一句#i nclude 就可以在main()中使用其中的函数了。


参考资料:

1)h文件里变量(函数)申明用不用extern

http://www.unixresources.net/linux/clf/program/archive/00/00/33/65/336569.html

2).c文件和.h文件的概念与联系

http://www.vckbase.com/document/viewdoc/?id=1607

3)过马路,左右看

http://www.vckbase.com/document/viewdoc/?id=1606

4).c 和 .h文件的不同

http://hi.baidu.com/mfantastic/blog/item/d6fddd39793494f73a87ce0c.html

5)C51包含头文件方法

http://blog.ednchina.com/eleclike/52862/message.aspx

 

模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。 C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分在面向对象设计中成为一个错误,牛顿 定律遇到了相对论),C语言模块化程序设计需理解如下概念:

       (1)模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;

       (2)某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明;

       (3)模块内的函数和 全局变量需在.c文件开头冠以static关键字声明;

       (4)永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如:



int a = 5;

#include "module1.h"

#include "module1.h"

#include "module1.h"

  以上程序的结果是在模块1、2、3中都定义了整型变量a,a在不同的模块中对应不同的地址单元,这个世界上从来不需要这样的程序。正确的做法是:



extern int a;

#include "module1.h" int a = 5;

#include "module1.h"

#include "module1.h"

这样如果模块1、2、3操作a的话,对应的是同一片内存单元。
51单片机项目,如果你打算编写与1602液晶显示模块交互的代码,通常会涉及到硬件初始化、数据传输以及字符显示等功能。这里是一个简化的例子,展示如何创建一个.c和.h文件来控制1602 LCD。 首先,我们先创建一个`LCD.h`(头文件): ```c // LCD.h #ifndef LCD_H #define LCD_H #include <reg52.h> // 包含51单片机的寄存器定义 // 宏定义 LCD 的起始地址 #define LCD_PORT P1 #define LCD_RS RS0 // 数据线选择 #define LCD_RW RW0 // 读写线 #define LCD_EN EN0 // 指令使能 // 公共函数声明 void lcd_init(void); void lcd_command(uint8_t cmd); void lcd_data_write(uint8_t data); void lcd_clear(void); void lcd_put_string(const char *str); #endif // LCD_H ``` 在这个头文件里,我们定义了一些宏来引用液晶模块的寄存器,并声明了几个公共函数,如初始化、发送命令、写数据、清屏和显示字符串。 接下来,我们创建一个`LCD.c`(源文件)来实现这些函数: ```c // LCD.c #include "LCD.h" void lcd_init() { LCD_PORT = 0xff; // 高电平初始化 TRISD = 0x00; // 设置所有数据线为输出 delay_ms(10); // 等待足够时间让电路稳定 LCD_PORT &= ~0xf0; // 使能LCD并设置RS=0(写命令) delay_us(40); // 发送指令使能脉冲 LCD_PORT |= 0x01; // 发送初始化命令 for (int i = 0; i < 30; i++) { lcd_command(0xae); // 调整对比度 delay_us(45); } } // ...其他函数实现略... ``` 这个.c文件实现了`lcd_init()`函数以及一些基本操作,比如发送液晶控制命令、写数据等。注意实际代码可能需要考虑更详细的通信协议和延迟,此处仅作示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值