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

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

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

3天內不再提示

單片機模塊化編程串口中斷怎么處理

ss ? 作者:工程師譚軍 ? 2018-09-11 09:22 ? 次閱讀

本文主要是關于單片機的相關介紹,并著重對單片機模塊化編程串口中斷的處理進行了詳盡的闡述。

模塊化編程

單片機編程時,如果代碼量不多,可以將所有的函數和定義等放在一個main.c文件中,但是隨著代碼量的增加,如果將所有代碼都放在同一個.C文件中,會使得程序結構混亂、可讀性與可移植性變差,而模塊化編程就是解決這個問題的常用而有效的方法。

模塊化設計的原則

“高內聚,低耦合

高內聚:一個C文件里面的函數,只有相互之間的調用,而沒有調用其它文件里面的函數,這樣可以視為高內聚。盡量減小不同文件里函數的交叉引用。

低耦合:一個完整的系統,模塊與模塊之間,盡可能的使其獨立存在。也就是說,讓每一個模塊,盡可能的獨立完成某個特定的子功能。模塊與模塊之間的接口,盡量的少而簡單。

模塊化編程的方法

1.創建一個.c源文件和一個.h頭文件

原則上文件可以任意命名;但強烈推薦如下原則:.c文件與.h文件同名;文件名要有意義,最好能夠體現該文件代碼的功能定義。

例如:IIC通信源文件與頭文件命名為IIC.c與IIC.h。

2.防重復包含

頭文件中需要防重復包含處理,防止頭文件在被多個文件引用的時候,讓編譯器在編譯時不會多次編譯。

在.h文件中加入如下代碼

#ifndef XXX

#define XXX

//Your Code

#endif

其中的XXX原則上可以是任意字符,在同一個工程中各個.h文件的XXX不能相同,因此強烈推薦如下的規則:將.h文件的文件名全部都大寫,“。”替換成下劃線”_”,首尾各添加2個下劃線”__”作為XXX。

例如IIC.h中的寫法:

#ifndef __IIC_H__

#define __IIC_H__

//code

#endif

3.代碼的封裝

.c文件中通常是:

函數的定義\

只被本.c文件調用的宏定義

.h文件中通常是

函數的聲明

被外部調用的宏定義

4.添加到工程中

只需要將。文件添加到工程中,.h文件不同添加到工程里,同時在.c文件里把對應的.h文件包含進來。

以下是一個IIC.h和IIC.c文件的內容

IIC.h的內容

復制代碼

#ifndef __I2C_H__

#define __I2C_H__

#include 《reg52.h》

#define uchar unsigned char

sbit SDA=P2^0;

sbit SCL=P2^1;

void delay();

void start();

void stop();

void ack();

void nack();

void write_byte(uchar date);

uchar read_byte();

void write_at24c02(uchar address ,uchar date);

uchar read_at24c02(uchar address);

#endif

復制代碼

IIC.c的內容

#include “i2c.h”

void delay()

{

;;

}

/*各個函數的定義*/

main.c內容

#include 《reg52.h》

#include “i2c.h”《br》

void main()

{

//code

}

單片機模塊化編程

在剛開始接觸到C語言程序的時候,由于學習內容所限,寫的程序都不是很大,一般也就幾百行而矣。所以所有的程序都完成在一個源文件里面。記得那時候大一參加學校里的一個電子設計大賽,調試了一個多星期,所有程序加起來大概將近1000行,長長的一個文件,從上瀏覽下來都要好半天。出了錯誤簡單的語法錯誤還好定位,其它一些錯誤,往往找半天才找的到。那個時候開始知道了模塊化編程這個東西,也嘗試著開始把程序分模塊編寫。最開始是把相同功能的一些函數(譬如1602液晶的驅動)全部寫在一個頭文件(.h)文件里面,然后需要調用的地方包含進去,但是很快發現這種方法有其局限性,很容易犯重復包含的錯誤。

而且調用起來也很不方便。很快暑假的電子設計大賽來臨了,學校對我們的單片機軟件編程進行了一些培訓。由于學校歷年來參加國賽和省賽,因此積累了一定數量的驅動模塊,那些日子,老師每天都會布置一定量的任務,讓我們用這些模塊組合起來,完成一定功能。而正是那些日子模塊化編程的培訓,使我對于模塊化編程有了更進一步的認識。并且程序規范也開始慢慢注意起來。此后的日子,無論程序的大小,均采用模塊化編程的方式去編寫。很長一段時間以來,一直有單片機愛好者在QQ上和我一起交流。有時候,他們會發過來一些有問題的程序源文件,讓我幫忙修改一下。同樣是長長的一個文件,而且命名極不規范,從頭看下來,著實是痛苦,說實話,還真不如我重新給他們寫一個更快一些,此話到不假,因為手頭積累了一定量的模塊,在完成一個新的系統時候,只需要根據上層功能需求,在底層模塊的支持下,可以很快方便的完成。而不需要從頭到尾再一磚一瓦的重新編寫。藉此,也可以看出模塊化編程的一個好處,就是可重復利用率高。下面讓我們揭開模塊化神秘面紗,一窺其真面目。

C語言源文件 *.c

提到C語言源文件,大家都不會陌生。因為我們平常寫的程序代碼幾乎都在這個XX.C文件里面。編譯器也是以此文件來進行編譯并生成相應的目標文件。作為模塊化編程的組成基礎,我們所要實現的所有功能的源代碼均在這個文件里。理想的模塊化應該可以看成是一個黑盒子。即我們只關心模塊提供的功能,而不管模塊內部的實現細節。好比我們買了一部手機,我們只需要會用手機提供的功能即可,不需要知曉它是如何把短信發出去的,如何響應我們按鍵的輸入,這些過程對我們用戶而言,就是是一個黑盒子。

在大規模程序開發中,一個程序由很多個模塊組成,很可能,這些模塊的編寫任務被分配到不同的人。而你在編寫這個模塊的時候很可能就需要利用到別人寫好的模塊的借口,這個時候我們關心的是,它的模塊實現了什么樣的接口,我該如何去調用,至于模塊內部是如何組織的,對于我而言,無需過多關注。而追求接口的單一性,把不需要的細節盡可能對外部屏蔽起來,正是我們所需要注意的地方。

C語言頭文件 *.h

談及到模塊化編程,必然會涉及到多文件編譯,也就是工程編譯。在這樣的一個系統中,往往會有多個C文件,而且每個C文件的作用不盡相同。在我們的C文件中,由于需要對外提供接口,因此必須有一些函數或者是變量提供給外部其它文件進行調用。

假設我們有一個LCD.C文件,其提供最基本的LCD的驅動函數

LcdPutChar(char cNewValue) ; //在當前位置輸出一個字符

而在我們的另外一個文件中需要調用此函數,那么我們該如何做呢?

頭文件的作用正是在此。可以稱其為一份接口描述文件。其文件內部不應該包含任何實質性的函數代碼。我們可以把這個頭文件理解成為一份說明書,說明的內容就是我們的模塊對外提供的接口函數或者是接口變量。同時該文件也包含了一些很重要的宏定義以及一些結構體的信息,離開了這些信息,很可能就無法正常使用接口函數或者是接口變量。但是總的原則是:不該讓外界知道的信息就不應該出現在頭文件里,而外界調用模塊內接口函數或者是接口變量所必須的信息就一定要出現在頭文件里,否則,外界就無法正確的調用我們提供的接口功能。因而為了讓外部函數或者文件調用我們提供的接口功能,就必須包含我們提供的這個接口描述文件----即頭文件。同時,我們自身模塊也需要包含這份模塊頭文件(因為其包含了模塊源文件中所需要的宏定義或者是結構體),好比我們平常所用的文件都是一式三份一樣,模塊本身也需要包含這個頭文件。

下面我們來定義這個頭文件,一般來說,頭文件的名字應該與源文件的名字保持一致,這樣我們便可以清晰的知道哪個頭文件是哪個源文件的描述。

于是便得到了LCD.C的頭文件LCD.h 其內容如下。

#ifndef _LCD_H_

#define _LCD_H_

extern LcdPutChar(char cNewValue) ;

#endif

這與我們在源文件中定義函數時有點類似。不同的是,在其前面添加了extern 修飾符表明其是一個外部函數,可以被外部其它模塊進行調用。

#ifndef _LCD_H_

#define _LCD_H_

#endif

這個幾條條件編譯和宏定義是為了防止重復包含。假如有兩個不同源文件需要調用LcdPutChar(char cNewValue)這個函數,他們分別都通過#include “Lcd.h”把這個頭文件包含了進去。在第一個源文件進行編譯時候,由于沒有定義過 _LCD_H_ 因此 #ifndef _LCD_H_ 條件成立,于是定義_LCD_H_ 并將下面的聲明包含進去。在第二個文件編譯時候,由于第一個文件包含時候,已經將_LCD_H_定義過了。因此#ifndef _LCD_H_ 不成立,整個頭文件內容就沒有被包含。假設沒有這樣的條件編譯語句,那么兩個文件都包含了extern LcdPutChar(char cNewValue) ; 就會引起重復包含的錯誤。

不得不說的typedef

很多朋友似乎了習慣程序中利用如下語句來對數據類型進行定義

#define uint unsigned int

#define uchar unsigned char

然后在定義變量的時候 直接這樣使用

uint g_nTimeCounter = 0 ;

不可否認,這樣確實很方便,而且對于移植起來也有一定的方便性。但是考慮下面這種情況你還會 這么認為嗎?

#define PINT unsigned int * //定義unsigned int 指針類型

PINT g_npTimeCounter, g_npTimeState ;

那么你到底是定義了兩個unsigned int 型的指針變量,還是一個指針變量,一個整形變量呢?而你的初衷又是什么呢,想定義兩個unsigned int 型的指針變量嗎?如果是這樣,那么估計過不久就會到處抓狂找錯誤了。

慶幸的是C語言已經為我們考慮到了這一點。typedef 正是為此而生。為了給變量起一個別名我們可以用如下的語句

typedef unsigned int uint16 ; //給指向無符號整形變量起一個別名 uint16

typedef unsigned int * puint16 ; //給指向無符號整形變量指針起一個別名 puint16

在我們定義變量時候便可以這樣定義了:

uint16 g_nTimeCounter = 0 ; //定義一個無符號的整形變量

puint16 g_npTimeCounter ; //定義一個無符號的整形變量的指針

在我們使用51單片機的C語言編程的時候,整形變量的范圍是16位,而在基于32的微處理下的整形變量是32位。倘若我們在8位單片機下編寫的一些代碼想要移植到32位的處理器上,那么很可能我們就需要在源文件中到處修改變量的類型定義。這是一件龐大的工作,為了考慮程序的可移植性,在一開始,我們就應該養成良好的習慣,用變量的別名進行定義。

如在8位單片機的平臺下,有如下一個變量定義

uint16 g_nTimeCounter = 0 ;

如果移植32單片機的平臺下,想要其的范圍依舊為16位。

可以直接修改uint16 的定義,即

typedef unsigned short int uint16 ;

這樣就可以了,而不需要到源文件處處尋找并修改。

將常用的數據類型全部采用此種方法定義,形成一個頭文件,便于我們以后編程直接調用。

文件名 MacroAndConst.h

其內容如下:

#ifndef _MACRO_AND_CONST_H_

#define _MACRO_AND_CONST_H_

typedef unsigned int uint16;

typedef unsigned int UINT;

typedef unsigned int uint;

typedef unsigned int UINT16;

typedef unsigned int WORD;

typedef unsigned int word;

typedef int int16;

typedef int INT16;

typedef unsigned long uint32;

typedef unsigned long UINT32;

typedef unsigned long DWORD;

typedef unsigned long dword;

typedef long int32;

typedef long INT32;

typedef signed char int8;

typedef signed char INT8;

typedef unsigned char byte;

typedef unsigned char BYTE;

typedef unsigned char uchar;

typedef unsigned char UINT8;

typedef unsigned char uint8;

typedef unsigned char BOOL;

#endif

至此,似乎我們對于源文件和頭文件的分工以及模塊化編程有那么一點概念了。那么讓我們趁熱打鐵,將上一章的我們編寫的LED閃爍函數進行模塊劃分并重新組織進行編譯。

在上一章中我們主要完成的功能是P0口所驅動的LED以1Hz的頻率閃爍。其中用到了定時器,以及LED驅動模塊。因而我們可以簡單的將整個工程分成三個模塊,定時器模塊,LED模塊,以及主函數

對應的文件關系如下

main.c

Timer.c --?Timer.h

Led.c --?Led.h

單片機模塊化編程串口中斷怎么處理

只要進行如下程序即可。

#include《reg51.h》

#define u16 unsigned int

#define u8 unsigned char

code u16 sj_tab[]={800,400,200,100};//每個檔位對應的時間

u8 setsj=0;//檔位

u16 jsflag;

#define LED P2

code u8 led_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,};//LED亮的方式

u8 ledflag=0;

/****************************************/

void init() //初始化函數

{ TMOD=0x01;

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

EA=1;

ET0=1;

}

/*********按鍵掃描******/

sbit k=P3^2;

u8 key(){

static u8 ms;

if(k==0){//檢測到0

if(ms《10)ms++;

if(ms==5)return 0;//連續5次掃描都為0,

}

else ms=0;

return 1;

}

/***********************************/

u8 count=0; //計數

void main()//主函數

{

init();//系統初始化

jsflag=sj_tab[setsj];//初始加載時間

TR0=1; //定時器開始計時

while(1){

if(key()==0){ //按鍵按下

if(++setsj》=4)setsj=0;//檔位+1,加到最大后歸0

}

LED=led_tab[ledflag];

}

}

/****************************/

void timer0() interrupt 1//1ms定時器

{

TH0=(65536-1000)/256;//重載初值

TL0=(65536-1000)%256;

if(jsflag》0)jsflag--;//1ms減1

if(jsflag==0){//減到0

jsflag=sj_tab[setsj];//重載時間

if(++ledflag》=8)ledflag=0;

}

}

結語

關于單片機模塊化編程的相關介紹就到這了,如有不足之處歡迎指正。

相關閱讀推薦:8051模塊化編程分析

相關閱讀推薦:如何對一個大的項目進行模塊化編程

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

    關注

    6035

    文章

    44554

    瀏覽量

    634653
  • 模塊化編程
    +關注

    關注

    4

    文章

    17

    瀏覽量

    7717
收藏 人收藏

    評論

    相關推薦

    單片機C語言模塊化編程

    單片機C語言模塊化編程下面讓我們揭開模塊化神秘面紗,一窺其真面目。
    發表于 01-14 16:46

    單片機C語言模塊化編程

    單片機C語言模塊化編程
    發表于 05-22 22:00

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

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

    單片機串口模塊化編程的相關資料分享

    單片機串口模塊化編程最近一直在研究串口,想把串口功能寫成一個
    發表于 12-03 06:56

    51單片機串口中斷使用總結

    51單片機串口中斷使用總結,有程序,可以參考。
    發表于 03-28 10:00 ?13次下載

    第6章單片機定時器串口中斷(20150709213857)

    第6章單片機定時器串口中斷(20150709213857)
    發表于 12-15 22:28 ?6次下載

    單片機的C語言模塊化編程

    單片機的C語言模塊化編程
    發表于 10-13 11:16 ?51次下載
    <b class='flag-5'>單片機</b>的C語言<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>

    單片機學習教程之外部中斷和定時器及串口中斷的資料和程序說明

    本文檔的主要內容詳細介紹的是單片機學習教程之外部中斷和定時器及串口中斷的資料和程序說明。CPU收到中斷請求,停下正在處理的工作A,去
    發表于 04-18 17:27 ?5次下載
    <b class='flag-5'>單片機</b>學習教程之外部<b class='flag-5'>中斷</b>和定時器及<b class='flag-5'>串口中斷</b>的資料和程序說明

    51單片機串口中斷功能的設置

    51單片機串口功能就是和外界進行通訊,所謂的“外界”也就是與單片機進行交互的媒介,最常用的就是我們經常使用的計算機、平板或者其他設備(比如另一個單片機配合顯示
    發表于 11-14 19:51 ?74次下載
    51<b class='flag-5'>單片機</b><b class='flag-5'>串口中斷</b>功能的設置

    單片機】Keil+Proteus流水燈(模塊化編程

    【征服單片機】實戰篇:Keil+Proteus流水燈(模塊化編程)主要是Keil的模塊化編程,同時實現了一個小實驗,通過Keil
    發表于 11-17 11:06 ?15次下載
    【<b class='flag-5'>單片機</b>】Keil+Proteus流水燈(<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>)

    51單片機-矩陣鍵盤模塊-長短按鍵&數碼管顯示-模塊化編程模板

    51單片機-矩陣鍵盤模塊-長短按鍵&數碼管顯示-模塊化編程模板
    發表于 11-21 09:21 ?28次下載
    51<b class='flag-5'>單片機</b>-矩陣鍵盤<b class='flag-5'>模塊</b>-長短按鍵&數碼管顯示-<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>模板

    經驗分享|十年老司機的單片機模塊化編程

    經驗分享|十年老司機的單片機模塊化編程
    發表于 11-23 17:51 ?33次下載
    經驗分享|十年老司機的<b class='flag-5'>單片機</b><b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>

    單片機工程模塊化操作_適用單片機編程新手

    對于一些接觸單片機編程不久的小萌新來說,模塊化編程這個概念剛接觸的時候可能會很懵,到底什么是模塊化編程
    發表于 11-23 17:51 ?26次下載
    <b class='flag-5'>單片機</b>工程<b class='flag-5'>模塊化</b>操作_適用<b class='flag-5'>單片機</b><b class='flag-5'>編程</b>新手

    單片機串口模塊化編程-中斷方式

    單片機串口模塊化編程最近一直在研究串口,想把串口功能寫成一個
    發表于 11-23 17:51 ?20次下載
    <b class='flag-5'>單片機</b><b class='flag-5'>串口</b>的<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>-<b class='flag-5'>中斷</b>方式

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

    單片機零基礎入門(8-4)模塊化編程---LED1602調試工具一、回顧二、什么是模塊化編程?1、傳統方式
    發表于 12-31 18:55 ?20次下載
    <b class='flag-5'>單片機</b>零基礎入門(8-5)<b class='flag-5'>模塊化</b><b class='flag-5'>編程</b>
    主站蜘蛛池模板: 免费观看视频成人国产| 午夜福利92看看电影80| 亚洲日产2020乱码草莓毕| a级毛片黄免费a级毛片| 韩国女人高潮嗷嗷叫视频 | 天天爽夜夜爽8888视频精品| 4399日本电影完整版在线观看免费| 国产人妻系列无码专区97SS| 日本久久精品视频| 婬香婬色天天视频| 国产小视频免费在线观看| 欧美18精品久久久无码午夜福利 | 国产精品第1页| 欧美成人免费观看久久| 与邻居换娶妻子2在线观看| 国产欧美无码亚洲| 色拍拍噜噜噜久久蜜桃| GAY东北澡堂激情2022| 老子午夜伦不卡电影院| 亚洲一二三产品区别在哪里| 国产精品久免费的黄网站| 日本无码色哟哟婷婷最新网站| 99久久精品国产亚洲AV| 老师洗澡让我吃她胸的视频 | 99精品视频在线观看免费| 久久re视频这里精品免费1| 亚洲成AV人电影在线观看 | 迅雷哥在线观看高清| 国产99青草全福视在线| 人人插人人射| wwwzzz日本| 欧美特级另类xxx| 99久久免费精品国产| 美女露出撒尿的部位| 自拍偷拍2| 美国caopo超碰在线视频| 中国午夜伦理片| 久久综合伊人 magnet| 欲插爽乱浪伦骨| 久久这里只有精品2| 中国老太太xxx|