When the project team does a relatively complex project , It means you don't work alone anymore . It's working with team members , This requires the team members to be responsible for part of the project . For example, you may only be responsible for communication or display .

At this time , You should write your own program into a module , Separate commissioning , Set aside interfaces for other modules to call .

/// Insert a message : At the beginning of this year, I recorded a set of systematic introductory single chip microcomputer tutorial , If you want, just ask me for it. It's free , I can send a private message ~ You can also get it by clicking my avatar in black font and adding my earth . I've been relatively idle recently , Lead to finish setting , Take students to provincial or above competitions ///

Start of text :

last , After the team members have written and debugged the modules they are responsible for , The project team leader shall carry out combined commissioning .

Such occasions require that the program must be modular . The benefits of modularity are many , Not just to facilitate division of labor , It also helps to debug the program , It is conducive to the division of program structure , It can also increase the readability and portability of the program .

What to say

Beginners often don't understand how to program modularity , In fact, it is easy to learn , And it is one of the effective methods of well-organized program structure .

This article will first talk about the modular methods and precautions , Finally, it will be the most widely used for beginners keil c Compiler as an example , The detailed steps of modular programming are given .

Modular programming should understand the following overview :

A module is a .c File and one .h Combination of documents , Header file (.h) Is the declaration of the module interface ;

This article summarizes the implementation method and essence of modularity : Write the code of a functional module into a .c file , Then put the interface function of the module in .h In the file . give an example : If you use LCD , Then you may write a LCD driver module , To implement characters , The reality of Chinese characters and images , Named :
led_device.c, Of this module .c The document can be roughly written as :


// Define variables

 unsigned char value;// global variable

// Define function

// This is the first function in this module , Play the role of delay , Only for function calls of this module , So use static Keyword modification

/******************** Delay subroutine ************************/

static void delay (uint us) //delay time


// This is the second function in this module , To call in another module

/********************* Character writing program **************************

** function : towards LCD Write character

** parameter :dat_comm by 1 What is written is data , by 0 What is written is an instruction

content Number or instruction written for


void wr_lcd (uchar dat_comm,uchar content)




/***************************** END Files***********************************/

notes : Only these two functions are written here , The scope of the first delay function is within the module , the second , It is required by other modules . To simplify , The function body is not written here .

.h The interface of the module is given in the document . In the above example , towards LCD Write character function :wr_lcd (uchar dat_comm,uchar
content) Is an interface function , Because other modules will call it , that .h This function must be declared as an external function in the file ( use extrun Keyword modification ), Another delay function :void
delay (uint us) Only used in this module ( Local function , use static Keyword modification ), So it doesn't need to be put .h In the file .

.h The file format is as follows :

// Declare global variables

extern unsigned char value;

// Declare interface functions

extern void wr_lcd (uchar dat_comm,uchar content); // towards LCD Write character


/***************************** END Files***********************************/

Here are three points to note :

. stay keil In compiler ,extern Even if this keyword is not declared , The compiler will not report an error , And the program runs well , But there is no guarantee that other compilers will be used as well . It is strongly recommended to add , Develop good programming practices .

..c The functions in the file will only appear in other modules when they are used .h In the file , Like local delay function static void delay (uint
us) Even if it appears in .h The document is also doing useless work , Because other modules don't call it at all , You can't actually call it (static Restrictive effect of keywords ).

. Be sure to add a semicolon at the end of this sentence ”;”, I believe many students have encountered this strange compiler error : error C132: 'xxxx': not in formal
parameter list, This mistake is actually .h The last semicolon of the function is declared less .

Application of module : If necessary LCD Menu module lcd_menu.c LCD driver module used in lcd_device.c Functions in void wr_lcd (uchar
dat_comm,uchar content), Just LCD Menu module lcd_menu.c Add the header file of LCD driver module to the file lcd_device.h that will do .

// Contains the LCD driver header file , Then you can .c Call in file //lcd_device.h Global functions in , Using the global in the LCD driver // variable ( If any ).

// Call to LCD Write character function

wr_lcd (0x01,0x30);

// Assign values to global variables


The external functions and data provided by a module to other modules need to be .h In the middle of the document extern Keyword declaration ;

This sentence has been reflected in the above example , That is, the external functions and global variables provided by a module to other modules need to be .h In the middle of the document extern Keyword declaration .

Let's focus on the use of global variables . A difficulty in using modular programming ( Relative to novices ) Is the setting of global variables , It is often difficult for beginners to figure out how to realize the variables shared by modules and modules , The conventional practice is mentioned in this sentence , stay .h The external data in the document is preceded by extern Keyword declaration .

For example, the variables in the above example value Is a global variable , If a module also uses this variable , It is the same as using external functions , Just use the module .c File contains #include“lcd_device.h” that will do .

Another way to deal with global variables between modules comes from embedded operating system uCOS-II, This operating system handles global variables in a special way , It's also difficult to understand , But after learning, it can be used infinitely , This method only needs to be defined once in the header file . The method is :

When defining all global variables (uCOS-II Define all global variables in one .h Within the document ) of .h In header file :

#ifdef xxx_GLOBALS

#define xxx_EXT


#define xxx_EXT extern


.H Every global variable in the file is added xxx_EXT Prefix of .xxx Represents the name of the module .

Of this module .C The file has the following definitions :

#define xxx_GLOBALS

#include "includes.h"

When the compiler processes .C File time , It forces xxx_EXT( In corresponding .H It can be found in the file ) Empty ,( because xxx_GLOBALS Already defined ).

So the compiler allocates memory space to each global variable , And when the compiler handles other .C File time ,xxx_GLOBAL No definition ,xxx_EXT Defined as extern, This allows the user to call external global variables . To illustrate this concept , See uC/OS_II.H, This includes the following definitions :


#define OS_EXT


#define OS_EXT extern





meanwhile ,uCOS_II.H There are the following definitions in :

#define OS_GLOBALS


When the compiler processes uCOS_II.C Time , It makes the header file as follows , because OS_EXT Is set to null .

INT32U OSIdleCtr;

INT32U OSIdleCtrRun;

INT32U OSIdleCtrMax;

In this way, the compiler will allocate these global variables in memory . When the compiler handles other .C File time , The header file looks like this , because OS_GLOBAL No definition , therefore OS_EXT Defined as extern.

extern INT32U OSIdleCtr;

extern INT32U OSIdleCtrRun;

extern INT32U OSIdleCtrMax;

under these circumstances , No memory allocation , And any  .C Files can use these variables . In this way, you just need to  .H Just define it once in the file .

The functions and global variables in the module need to be .c File begins with static Keyword declaration ;

This sentence is mainly about keywords static Role of .Static Is a very important keyword , He can make some constraints on functions and variables , And it can convey some information .

For example, in the above example LCD Drive module .c Delay function defined in file static void delay (uint
us), This function is preceded by static modification , On the one hand, it limits the scope of the function and only plays a role in this module , On the other hand, it also conveys such a message to people : This function will not be called by other modules .

Let's talk about the function of this keyword in detail , stay C In language , keyword static There are three obvious effects :

. In function body , A variable declared static maintains its value during the call of this function .

. In module ( But outside the function ), A variable declared static can be accessed by functions used in the module , But it cannot be accessed by other functions outside the module . It is a local global variable .

. In module , A function declared as static can only be called by other functions in this module . That's it , This function is restricted to the local scope of the module that declares it .

The first two are easier to understand , The last function is the delay function just mentioned in the example (static void delay (uint us)), Localization functions are quite useful .

Never in .h Variables defined in the file !

Compare the code :

Code one :


int a = 5; /* In module 1 of .h Defined in file int a */

/*module1 .c*/

#include "module1.h" /* In module 1 Contains modules 1 of .h file  */

/*module2 .c*/

#include "module1.h" /* In module 2 Contains modules 1 of .h file  */

/*module3 .c*/

#include "module1.h" /* In module 3 Contains modules 1 of .h file  */

The result of the above procedure is in the module 1,2,3 Integer variables are defined in a,a Corresponding to different address elements in different modules , There has never been a need for such a program in this world . The right thing to do is :

Code two :


extern int a; /* In module 1 of .h Stated in the document int a */

/*module1 .c*/

#include "module1.h" /* In module 1 Contains modules 1 of .h file  */

int a = 5; /* In module 1 of .c Defined in file int a */

/*module2 .c*/

#include "module1.h" /* In module 2 Contains modules 1 of .h file  */

/*module3 .c*/

#include "module1.h" /* In module 3 Contains modules 1 of .h file  */

So if the module 1,2,3 operation a Words , It corresponds to the same memory unit .

notes : An embedded system usually includes two types ( Note that there are two types , Not two ) modular :

· Hardware driver module , A specific hardware corresponds to a module ;

· Software function module , The division of modules shall meet the requirements of low coupling , High cohesion requirements .