面向对象的技术成为主流以前许多年,C语言的编程者使用C语言支持模块是的编程风格,使用这种方法,就可以即在C中创建“基于文件的类”,又不增加许多内存或CPU的负载。文件变成了我们的类,且文件中“static”数据成为该类的私有数据成员,该文件中定义的 函数成为文件类的 成员函数,并且我们的整个程序可以分成许多清晰定义的(基于文件的)类。
以上程序的结果是在模块1、2、3中都定义了整型变量a,a在不同的模块中对应不同的地址单元,这个世界上从来不需要这样的程序。正确的做法是:
这样如果模块1、2、3操作a的话,对应的是同一片内存单元。 一个嵌入式系统通常包括两类模块: (1)硬件驱动模块,一种特定硬件对应一个模块; (2)软件功能模块,其模块的划分应满足低偶合、高内聚的要求。 程序清单 基于文件的C语言类的一个例子(H文件) /*------------------------------------------------------------------*- PC_IO.H (v1.00) ------------------------------------------------------------------ - see PC_IO.C for details. COPYRIGHT --------- This code is associated with the book: EMBEDDED C by Michael J. Pont [Pearson Education, 2002: ISBN: 0-201-79523-X]. This code is copyright (c) 2001 by Michael J. Pont. See book for copyright details and other information. -*------------------------------------------------------------------*/ #ifndef _PC_IO_H #define _PC_IO_H // ------ Public constants --公有的常数------------------------------- // Value returned by PC_LINK_Get_Char_From_Buffer if no character is // available in buffer #define PC_LINK_IO_NO_CHAR 127 // ------ Public function prototypes -公有“成员”函数------------- void PC_LINK_IO_Write_String_To_Buffer(const char* const); void PC_LINK_IO_Write_Char_To_Buffer(const char); char PC_LINK_IO_Get_Char_From_Buffer(void); // Must call this function frequently ... void PC_LINK_IO_Update(void); #endif /*------------------------------------------------------------------*- ---- END OF FILE ------------------------------------------------- -*------------------------------------------------------------------*/ 基于文件的C语言类的一个例子(C文件) /*------------------------------------------------------------------*- PC_IO.C (v1.00) ------------------------------------------------------------------ Core files for simple PC link library for 8051 family Uses the UART, and Pins 3.1 (Tx) and 3.0 (Rx) #include "Main.h" #include "PC_IO.h" // ------ Public variable definitions -----公共变量-------------- tByte In_read_index_G; // Data in buffer that has been read tByte In_waiting_index_G; // Data in buffer not yet read tByte Out_written_index_G; // Data in buffer that has been sent tByte Out_waiting_index_G; // Data in buffer not yet sent // ------ Private function prototypes ------------------------------ static void PC_LINK_IO_Send_Char(const char); // ------ Private constants -----私有常数------------------ // The receive buffer length #define RECV_BUFFER_LENGTH 8 // The transmit buffer length #define TRAN_BUFFER_LENGTH 50 #define XON 0x11 #define XOFF 0x13 // ------ Private variables ----私有变量-------------------- static tByte Recv_buffer[RECV_BUFFER_LENGTH]; static tByte Tran_buffer[TRAN_BUFFER_LENGTH]; /*------------------------------------------------------------------*- PC_LINK_IO_Update() Checks for character in the UART (hardware) receive buffer Sends next character from the software transmit buffer -*------------------------------------------------------------------*/ void PC_LINK_IO_Update(void) { // Deal with transmit bytes here // Is there any data ready to send? if (Out_written_index_G < Out_waiting_index_G) { PC_LINK_IO_Send_Char(Tran_buffer[Out_written_index_G]); Out_written_index_G++; } else { // No data to send - just reset the buffer index Out_waiting_index_G = 0; Out_written_index_G = 0; } // Only dealing with received bytes here // -> Just check the RI flag if (RI == 1) { // Flag only set when a valid stop bit is received, // -> data ready to be read into the received buffer // Want to read into index 0, if old data has been read // (simple ~circular buffer) if (In_waiting_index_G == In_read_index_G) { In_waiting_index_G = 0; In_read_index_G = 0; } // Read the data from UART buffer Recv_buffer[In_waiting_index_G] = SBUF; if (In_waiting_index_G < RECV_BUFFER_LENGTH) { // Increment without overflowing buffer In_waiting_index_G++; } RI = 0; // Clear RT flag } } /*------------------------------------------------------------------*- PC_LINK_IO_Write_Char_To_Buffer() Stores a character in the 'write' buffer, ready for later transmission -*------------------------------------------------------------------*/ void PC_LINK_IO_Write_Char_To_Buffer(const char CHARACTER) { // Write to the buffer *only* if there is space // - No error reporting in this simple library... if (Out_waiting_index_G < TRAN_BUFFER_LENGTH) { Tran_buffer[Out_waiting_index_G] = CHARACTER; Out_waiting_index_G++; } } /*------------------------------------------------------------------*- PC_LINK_IO_Write_String_To_Buffer() Copies a (null terminated) string to the character buffer. (The contents of the buffer are then passed over the serial link) STR_PTR - Pointer to the NULL-TERMINATED string. -*------------------------------------------------------------------*/ void PC_LINK_IO_Write_String_To_Buffer(const char* const STR_PTR) { tByte i = 0; while (STR_PTR[i] != '\0') { PC_LINK_IO_Write_Char_To_Buffer(STR_PTR[i]); i++; } } /*------------------------------------------------------------------*- PC_LINK_IO_Get_Char_From_Buffer() Retrieves a character from the (software) buffer, if available The character from the buffer is returned, or - if no data are available - PC_LINK_IO_NO_CHAR is returned. -*------------------------------------------------------------------*/ char PC_LINK_IO_Get_Char_From_Buffer(void) { char Ch = PC_LINK_IO_NO_CHAR; // If there is new data in the buffer if (In_read_index_G < In_waiting_index_G) { Ch = Recv_buffer[In_read_index_G]; if (In_read_index_G < RECV_BUFFER_LENGTH) { In_read_index_G++; } } return Ch; } /*------------------------------------------------------------------*- PC_LINK_IO_Send_Char() Based on Keil sample code, with added (loop) timeouts. Implements Xon / Off control. Uses on-chip UART hardware. -*------------------------------------------------------------------*/ void PC_LINK_IO_Send_Char(const char CHARACTER) { tLong Timeout1 = 0; tLong Timeout2 = 0; if (CHARACTER == '\n') { if (RI) { if (SBUF == XOFF) { Timeout2 = 0; do { RI = 0; // Wait for uart (with simple timeout) Timeout1 = 0; while ((++Timeout1) && (RI == 0)); if (Timeout1 == 0) { // UART did not respond - error // No error reporting in this simple library... return; } } while ((++Timeout2) && (SBUF != XON)); if (Timeout2 == 0) { // UART did not respond - error // No error reporting in this simple library... return; } RI = 0; } } Timeout1 = 0; while ((++Timeout1) && (TI == 0)); if (Timeout1 == 0) { // UART did not respond - error // No error reporting in this simple library... return; } TI = 0; SBUF = 0x0D; // Output CR } if (RI) { if (SBUF == XOFF) { Timeout2 = 0; do { RI = 0; // Wait for UART (with simple timeout) Timeout1 = 0; while ((++Timeout1) && (RI == 0)); if (Timeout1 == 0) { // UART did not respond - error // No error reporting in this simple library... return; } } while ((++Timeout2) && (SBUF != XON)); RI = 0; } } Timeout1 = 0; while ((++Timeout1) && (TI == 0)); if (Timeout1 == 0) { // UART did not respond - error // No error reporting in this simple library... return; } TI = 0; SBUF = CHARACTER; } /*------------------------------------------------------------------*- ---- END OF FILE ------------------------------------------------- -*------------------------------------------------------------------*/ (落鹤生) |