色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何對一個大的項目進行模塊化編程

GReq_mcu168 ? 來源:未知 ? 作者:胡薇 ? 2018-06-11 17:06 ? 次閱讀

當你在一個項目小組做一個相對較復雜的工程時,意味著你不再獨自單干。你需要和你的小組成員分工合作,一起完成項目,這就要求小組成員各自負責一部分工程。比如你可能只是負責通訊或者顯示這一塊。這個時候,你就應該將自己的這一塊程序寫成一個模塊,單獨調試,留出接口供其它模塊調用。最后,小組成員都將自己負責的模塊寫完并調試無誤后,由項目組長進行組合調試。像這些場合就要求程序必須模塊化。模塊化的好處是很多的,不僅僅是便于分工,它還有助于程序的調試,有利于程序結構的劃分,還能增加程序的可讀性和可移植性。

初學者往往搞不懂如何模塊化編程,其實它是簡單易學,而且又是組織良好程序結構行之有效的方法之一.

本文將先大概講一下模塊化的方法和注意事項,最后將以初學者使用最廣的keil c編譯器為例,給出模塊化編程的詳細步驟。

模塊化程序設計應該理解以下概述:

(1) 模塊即是一個.c 文件和一個.h 文件的結合,頭文件(.h)中是對于該模塊接口的聲明;

這一條概括了模塊化的實現方法和實質:將一個功能模塊的代碼單獨編寫成一個.c文件,然后把該模塊的接口函數放在.h文件中.舉例:假如你用到液晶顯示,那么你可能會寫一個液晶驅動模塊,以實現字符、漢字和圖像的現實,命名為: led_device.c,該模塊的.c文件大體可以寫成:

注:此處只寫出這兩個函數,第一個延時函數的作用范圍是模塊內,第二個,它是其它模塊需要的。為了簡化,此處并沒有寫出函數體.

.h文件中給出模塊的接口.在上面的例子中,向LCD寫入字符函數:wr_lcd (uchar dat_comm,uchar content)就是一個接口函數,因為其它模塊會調用它,那么.h文件中就必須將這個函數聲明為外部函數(使用extrun關鍵字修飾),另一個延時函數:void delay (uint us)只是在本模塊中使用(本地函數,用static關鍵字修飾),因此它是不需要放到.h文件中的。

.h文件格式如下:

這里注意三點:

1. 在keil 編譯器中,extern這個關鍵字即使不聲明,編譯器也不會報錯,且程序運行良好,但不保證使用其它編譯器也如此。強烈建議加上,養成良好的編程規范。

2. .c文件中的函數只有其它模塊使用時才會出現在.h文件中,像本地延時函數static void delay (uint us)即使出現在.h文件中也是在做無用功,因為其它模塊根本不去調用它,實際上也調用不了它(static關鍵字的限制作用)。

3.注意本句最后一定要加分號”;”,相信有不少同學遇到過這個奇怪的編譯器報錯: error C132: 'xxxx': not in formal parameter list,這個錯誤其實是.h的函數聲明的最后少了分號的緣故。

模塊的應用:假如需要在LCD菜單模塊lcd_menu.c中使用液晶驅動模塊lcd_device.c中的函數void wr_lcd (uchar dat_comm,uchar content),只需在LCD菜單模塊的lcd_menu.c文件中加入液晶驅動模塊的頭文件lcd_device.h即可.

(2) 某模塊提供給其它模塊調用的外部函數及數據需在.h 中文件中冠以extern 關鍵字聲明;

這句話在上面的例子中已經有體現,即某模塊提供給其它模塊調用的外部函數和全局變量需在.h 中文件中冠以extern 關鍵字聲明,下面重點說一下全局變量的使用。使用模塊化編程的一個難點(相對于新手)就是全局變量的設定,初學者往往很難想通模塊與模塊公用的變量是如何實現的,常規的做法就是本句提到的,在.h文件中外部數據冠以extern關鍵字聲明。比如上例的變量value就是一個全局變量,若是某個模塊也使用這個變量,則和使用外部函數一樣,只需在使用的模塊.c文件中包含#include“lcd_device.h”即可。

另一種處理模塊間全局變量的方法來自于嵌入式操作系統uCOS-II,這個操作系統處理全局變量的方法比較特殊,也比較難以理解,但學會之后妙用無窮,這個方法只需用在頭文件中定義一次。方法為:

在定義所有全局變量(uCOS-II將所有全局變量定義在一個.h文件內)的.h頭文件中:

當編譯器處理.C文件時,它強制xxx_EXT(在相應.H文件中可以找到)為空,(因為xxx_GLOBALS已經定義)。所以編譯器給每個全局變量分配內存空間,而當編譯器處理其他.C 文件時,xxx_GLOBAL沒有定義,xxx_EXT 被定義為extern,這樣用戶就可以調用外部全局變量。為了說明這個概念,可以參見uC/OS_II.H,其中包括以下定義:

同時,uCOS_II.H 有中以下定義:

#define OS_GLOBALS

#include “includes.h”

當編譯器處理uCOS_II.C 時,它使得頭文件變成如下所示,因為OS_EXT 被設置為空。

INT32U OSIdleCtr;

INT32U OSIdleCtrRun;

INT32U OSIdleCtrMax;

這樣編譯器就會將這些全局變量分配在內存中。當編譯器處理其他.C 文件時,頭文件變成了如下的樣子,因為OS_GLOBAL沒有定義,所以OS_EXT 被定義為extern。

extern INT32U OSIdleCtr;

extern INT32U OSIdleCtrRun;

extern INT32U OSIdleCtrMax;

在這種情況下,不產生內存分配,而任何 .C文件都可以使用這些變量。這樣的就只需在 .H文件中定義一次就可以了。

(3) 模塊內的函數和全局變量需在.c 文件開頭冠以static 關鍵字聲明;

這句話主要講述了關鍵字static的作用。Static是一個相當重要的關鍵字,他能對函數和變量做一些約束,而且可以傳遞一些信息。比如上例在LCD驅動模塊.c文件中定義的延時函數static void delay (uint us),這個函數冠以static修飾,一方面是限定了函數的作用范圍只是在本模塊中起作用,另一方面也給人傳達這樣的信息:該函數不會被其他模塊調用。下面詳細說一下這個關鍵字的作用,在C 語言中,關鍵字static 有三個明顯的作用:

1.在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。

2.在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變

量。

3.在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地范圍內使用。

前兩個都比較容易理解,最后一個作用就是剛剛舉例中提到的延時函數(static void delay (uint us)),本地化函數是有相當好的作用的。

(4) 永遠不要在.h 文件中定義變量!

呵呵,似乎有點危言聳聽的感覺,但我想也不會有多少人會在.h文件中定義變量的。

比較一下代碼:

代碼一:

以上程序的結果是在模塊1、2、3 中都定義了整型變量a,a 在不同的模塊中對應不同的地址元,這個世界上從來不需要這樣的程序。正確的做法是:

代碼二:

這樣如果模塊1、2、3 操作a 的話,對應的是同一片內存單元。

注:

一個嵌入式系統通常包括兩類(注意是兩類,不是兩個)模塊:

(1)硬件驅動模塊,一種特定硬件對應一個模塊;

(2)軟件功能模塊,其模塊的劃分應滿足低偶合、高內聚的要求。

下面以keil C 編譯器為例,講一下模塊化編程的步驟。

下面這個程序分為三層,共7個模塊,共同為主程序服務(它們之間也會相互調用)。

程序的結構圖如下所示:

序主要模塊和功能簡介:

一、底層驅動

1. 紅外鍵盤:程序通過紅外鍵盤進行操作。紅外鍵盤獨占定時器0和外部中斷0,以實現紅外解碼和鍵盤鍵值的識別。紅外鍵盤定義了五個按鍵,分別為上翻、下翻、左翻、右翻和確認鍵。

2. LCD液晶顯示:程序主要通過LCD顯示信息,LCD液晶顯示驅動提供顯示漢字、圖形和ASCII碼的函數接口。可以全屏、單行顯示漢字,任意位置顯示ASCII碼,還可以全屏、半屏顯示圖形。

二、功能模塊

1. LCD菜單程序:菜單程序可以使人機交互更加方便、容易。本菜單程序的菜單級別深度受RAM大小的限制,每增加一級菜單將多消耗4字節的RAM。菜單程序主要完成菜單功能函數的調度,LCD顯示刷新。

2. 計算器程序:實現65536以內的加、減、乘、除,超出范圍會出現溢出,溢出發生時,LCD顯示“錯誤:出現溢出”的錯誤提示,同時本次運算被忽略。對于負數會顯示“-”號,除數為零時LCD顯示“錯誤:除數為零”的錯誤提示。

3. 開機次數記憶程序:主要對基于IIC總線的EEPROM進行讀寫,單片機每次上電后,將開機次數寫入EEPROM.

4. 串口測試程序:進入該程序后,單片機向電腦發送字符串“Hello Word!”,發送數字24(以字符的形式顯示)。編寫此程序的目的是為了能夠方便的向電腦發送字符串和變量,便于程序的調試。串口占用串口資源,與頻率測量程序共享定時器1

5. 頻率測量:復用定時器1,占用外部中斷1,實現5~20KHZ頻率的測量.

三、主程序

主程序主要完成程序的初始化,LCD菜單顯示,監視鍵盤程序并根據鍵值更新菜單。

步驟為:

1.新建工程。

2.點擊File—New(或者點擊快捷圖標:),新建一個文檔。

3.點擊File—Save(或者點擊快捷圖標:),保存新建的文檔,在文件名后填寫LCD_device.c(液晶驅動模塊: LCD_device,提供顯示漢字、字符和圖像的接口),點擊確定。

在該文檔內編寫LCD驅動程序。

4. 點擊File—New(或者點擊快捷圖標:),再新建一個文檔。

5. 點擊File—Save(或者點擊快捷圖標:),保存新建的文檔,在文件名后填寫LCD_device.h(液晶驅動模塊的頭文件,模塊的接口和全局變量在這里聲明(感謝網友楊康佳指正這里的錯誤,原文將“聲明”寫成了“定義”,頭文件一般用來聲明變量和接口的))。點擊確定。在該文檔中整理全局變量和接口函數。以上步驟之后的效果見下圖:

至此,液晶驅動模塊書寫完畢,可以對這個模塊單獨的調試。

6.重復以上步驟2~5,定義 紅外鍵盤模塊:key.c與key.h

菜單模塊:menu.c與menu.h

串口通信模塊:uart_.c與uart.h

計算器模塊:counter.c與counter.h

頻率測量模塊:mea_fre.c與mea_fre.h

開機次數記憶模塊:eepram.c與eepram.h

7.重復以上步驟2~3,定義主程序main.c

最終效果如下圖所示:

完成1~7個步驟后,有些小白就習慣性的點擊編譯按鈕了,這時候會出現兩個警告信息:

*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL

*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL

這是因為你只是編寫好了程序模塊,卻沒有把他們加入到工程的緣故。

解決方法:在Project Workspace框中,右擊Source group 1文件夾,選擇Add Files to Group‘Source Group 1’,在彈出的對話框中添加你的.c文件即可。

遙想很久很久以前,我也對上面的兩個警告有過親身體會。那時候我還在大學,周圍有一大群的好哥們. 現在…想起來只剩唏噓!!!

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7608

    瀏覽量

    137129
  • 模塊化編程
    +關注

    關注

    4

    文章

    17

    瀏覽量

    7732

原文標題:嵌入式C語言之---模塊化編程

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    關于keil 模塊化編程小小疑惑

    請問模塊化編程中如圖所示,我要將最后c文件standby.c添加到main.c中,怎么操作??謝謝
    發表于 11-13 23:05

    模塊化編程

    大家起來講解看,,,到底何為模塊化編程???
    發表于 08-07 21:56

    如何對Keil 5模塊化進行編程

    如何對Keil 5模塊化進行編程
    發表于 10-11 06:08

    單片機模塊化是如何進行編程的?

    單片機模塊化是如何進行編程的?
    發表于 10-21 06:20

    模塊化編程&工程模板設計

    ???九層妖塔?起于壘土【藍橋杯】—{模板Template}—{Part1:模塊化編程&工程模板}、流程圖二、基礎知識1、編譯預處理2、變量的定義和說明3、`extern`三、操作流程1
    發表于 11-30 07:18

    到底什么是模塊化編程

    對于些接觸單片機編程不久的小萌新來說,模塊化編程這個概念剛接觸的時候可能會很懵,到底什么是模塊化編程
    發表于 12-03 07:39

    什么是模塊化編程

    1什么是模塊化模塊化編程就是把我們的整個項目,分成很多模塊(比如
    發表于 12-06 08:02

    新建模塊化編程工程及常見問題匯總

    先跳過關于模塊化編程的好處,在這里不多說了,因為這已經被人說爛了,但是有相當部分新手是覺得模塊化編程比較復雜,但是實際上,當面臨
    發表于 01-05 07:29

    什么是模塊化編程模塊化編程的注意事項

    、回顧上篇文章,我寫了單片機的實戰,數碼管的消影。這篇文章,將對單片機的模塊化編程進行記錄講解。二、什么是
    發表于 02-23 07:14

    模塊化程序設計簡單解釋

    模塊化程序設計模塊化程序設計是指在進行程序設計時將個大程序按照功能劃分為若干小程序模塊,每個小
    發表于 02-23 06:05

    模塊化編程思想

    模塊化編程思想,充分利用c語言的可移植性,更好的利用c語言。
    發表于 03-22 15:15 ?16次下載

    【C語言】模塊化編程-通俗易懂

    1什么是模塊化模塊化編程就是把我們的整個項目,分成很多模塊(比如
    發表于 11-23 18:06 ?10次下載
    【C語言】<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>-通俗易懂

    單片機零基礎入門(8-5)模塊化編程

    、回顧上篇文章,我寫了單片機的實戰,數碼管的消影。這篇文章,將對單片機的模塊化編程進行記錄講解。二、什么是
    發表于 12-31 18:55 ?20次下載
    單片機零基礎入門(8-5)<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>

    模塊化通知項目

    電子發燒友網站提供《模塊化通知項目.zip》資料免費下載
    發表于 12-16 14:01 ?0次下載
    <b class='flag-5'>模塊化</b>通知<b class='flag-5'>項目</b>

    如何模塊化編程

    塊程序寫成模塊,單獨調試,留出接口供其它模塊調用。 最后,小組成員都將自己負責的模塊寫完并調試無誤后,由
    的頭像 發表于 06-22 11:40 ?1325次閱讀
    主站蜘蛛池模板: 果冻传媒AV精品一区| 啦啦啦 中文 日本 韩国 免费| 免费看国产精品麻豆| 4399的视频BD高清在线观看免费| 免费观看成人毛片| 办公室里做好紧好爽H| 偷尝禁果H1V1幸运的山熊| 狠狠啪在线香蕉| 99热在线观看精品| 无码一区二区在线欧洲| 久久视频在线视频观品15 | 麻豆天美国产一区在线播放| 99视频福利| 小SAO货水真多把你CAO烂| 久久免费精品视频| 大桥未久与黑人中出视频| 亚洲伊人久久一次| 秋霞影音先锋一区二区| 好男人社区| 成人国产在线视频| 影音先锋av333资源网| 色橹橹欧美在线观看视频高| 久久精品热99看| 搞基福利社| 2022久久精品国产色蜜蜜麻豆| 少妇性饥渴BBBBBBBBB| 老司机福利在视频在ae8| 国产伦精品一区二区免费| 97伦理电影在线不卡| 亚洲国产在线观看免费视频| 欧美另类摘花hd| 久草在线福利资站免费视频| 国产国产乱老熟视频网站| 97色伦久久视频在观看| 亚洲精品123区| 色婷婷我要去我去也| 毛片免费观看| 黑人性xxx| 国产成人精视频在线观看免费| 91综合久久久久婷婷| 亚洲熟妇AV乱码在线观看|