91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在單片機(jī)中引入面向?qū)ο蟮乃枷?/h1>

在看別人單片機(jī)程序時,你也許是奔潰的,因為全局變量滿天飛,不知道哪個在哪用了,哪個表示什么,而且編寫極其不規(guī)范。自己寫單片機(jī)程序時,也許你也是奔潰的??偢杏X重新開啟一個項目,之前的寫過相似的代碼也無法使用,得重新敲,代碼重用度不高,編程效率低下,代碼無法積累。而且感覺寫這個代碼沒有思想,沒有靈魂,沒有框架,只是一個一個功能代碼的堆砌,很空泛。

那么這個時候,你也許應(yīng)該在單片機(jī)中引入面向?qū)ο蟮乃枷肓?,使代碼更規(guī)范。

一、單片機(jī)程序框架

1、輪流執(zhí)行

intmain(void)
{
while(1)
{
sing();
dance();
play();
}
}

函數(shù)sing執(zhí)行的時間比較長的話,函數(shù)dance就不能很快的被執(zhí)行。任何一個函數(shù)死掉的話就會影響整個系統(tǒng)。

2、前后臺

在使用 51、AVR、STM32 單片機(jī)裸機(jī)的時候一般都是在main函數(shù)里面用while(1)做一個大循環(huán)來完成所有的處理,即應(yīng)用程序是一個無限的循環(huán),循環(huán)中調(diào)用相應(yīng)的函數(shù)完成所需的處理。有時候我們也需要中斷中完成一些處理。相對于多任務(wù)系統(tǒng)而言,這個就是單任務(wù)系統(tǒng),也稱作前后臺系統(tǒng),中斷服務(wù)函數(shù)作為前臺程序,大循環(huán)while(1)作為后臺程序。

對應(yīng)的編程代碼大概是這樣的:

voidEXTI_IRQHandler()
{
flag=1;
}
intmain(void)
{
while(1)
{
if(flag=1)
{
do_something();
flag=0;
}
}
}

有什么問題?

前后臺系統(tǒng)的實時性差,前后臺系統(tǒng)各個任務(wù)(應(yīng)用程序)都是排隊等著輪流執(zhí)行,不管你這個程序現(xiàn)在有多緊急,沒輪到你就只能等著!相當(dāng)于所有任務(wù)(應(yīng)用程序)的優(yōu)先級都是一樣的。但是前后臺系統(tǒng)簡單啊,資源消耗也少?。≡谏晕⒋笠稽c的嵌入式應(yīng)用中前后臺系統(tǒng)就明顯力不從心了。

3、多任務(wù)

voidfirst_task()
{
while(1)
{
if(has_data())
put_data();
}
}
voidsecond_task()
{
while(1)
{
if(get_data())
do_something();
}
}

intmain(void)
{
create_task(first_task);
create_task(second_task);
start_scheduler();
}

多任務(wù)系統(tǒng)會把一個大問題“分而治之”,把大任務(wù)劃分成很多個小問題,逐步的把小任務(wù)解決掉,大任務(wù)也就隨之解決了,這些任務(wù)是并發(fā)處理的。注意,并不是說同一時刻一起執(zhí)行很多個任務(wù),而是由于每個任務(wù)執(zhí)行的時間很短,導(dǎo)致看起來像是同一時刻執(zhí)行了很多個任務(wù)一樣。

二、執(zhí)行的程序怎么寫?

以按鍵為例,點亮一個小燈!

1.常規(guī)寫法

intmian(void)
{
while(1)
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)==GPIO_PIN_SET)
{
printf("按鍵按下
");
}
}
}

2.面向?qū)ο蟮膶懛?/span>

首先我們把每一個按鍵都看成一個對象,既然是對象就肯定有屬性和行為,比如我們定義一個學(xué)生,那么這個學(xué)生有什么屬性呢?

肯定有姓名、年齡、身高、體重對吧,這些是一些基本的屬性,我們可以用一些單獨的變量來定義它,比如:

typedefstruct
{
uint8_t*name;//姓名(變量)
uint8_tage;//年齡(變量)
uint8_theight;//身高(變量)
uint8_tweight;//體重(變量)
}student_t;

但是一個學(xué)生還有很多行為對吧,它會唱歌、跳舞、打籃球、也會關(guān)注果果小師弟的公眾號對吧,于是我們就可以這樣定義:

typedefstruct
{
uint8_t*name;//姓名(變量)
uint8_tage;//年齡(變量)
uint8_theight;//身高(變量)
uint8_tweight;//體重(變量)
void(*Sing_song)(void);//會唱歌(函數(shù)指針)
void(*Dance_latin)(void);//會跳舞(函數(shù)指針)
void(*Wechat_zhiguoxin)(void);//會關(guān)注果果的公眾號(函數(shù)指針)
}student_t;

好了,這里我們提到了函數(shù)指針,所以就來說一說函數(shù)指針。

函數(shù)指針,顧名思義它就是一個指針,只不過它是一個函數(shù)指針,所以指向的是一個函數(shù)。類比一般的變量指針,指針變量,實質(zhì)上是一個變量,只不過這個變量存放的是一個地址,在32位單片機(jī)中,任何類型的指針變量都存放的是一個大小為4字節(jié)的地址。

重要的話說三遍!牢記在心?。?!為什要記住函數(shù)指針,因為在單片機(jī)面向?qū)ο缶幊讨?,結(jié)構(gòu)體的成員不是變量就是函數(shù)指針這兩種類型。變量就不用說了,函數(shù)指針理解就好。

其實函數(shù)指針可以類比一般的變量,看下面:

inta;voidSing_song(void);
int*p;void(*zhiguoxin)(void);
p=&a;zhiguoxin=&Sing_song;
  1. 左邊走義變量a,右邊定義函數(shù)Sing_song;
  2. 左邊定義int指針,右邊定義函數(shù)指針;
  3. 左邊賦值指針,右邊賦值函數(shù)指針;

那么函數(shù)指針怎么用呢?我們還是以單片機(jī)為例,把按鍵類比為一個對象,這個按鍵有按鍵標(biāo)志位,有長按或者短按,按鍵還有行為:按鍵初始化、按鍵循環(huán)檢測等。

所以我們創(chuàng)建下面這樣一個結(jié)構(gòu)體,當(dāng)然這個結(jié)構(gòu)體不一定僅僅有這些變量和函數(shù),這完全取決于你自己的定義,你想怎么定義就怎么定義,你甚至可以定義按鍵的顏色都。

typedefstruct
{
uint8_tKEY_Flag;//標(biāo)志位(變量)
uint8_tClick;//按下(變量)
void(*KEY_Init)(void);//按鍵初始化(函數(shù)指針)
void(*KEY_Detect)(void);//按鍵檢測(函數(shù)指針)
}KEY_t;

現(xiàn)在已經(jīng)定義了KEY_t這種類型的結(jié)構(gòu)體,處理器還沒有分配給這個結(jié)構(gòu)體內(nèi)存,因為我們只是聲明這樣一個類型,而類型是不占用內(nèi)存的,只有我們定義對應(yīng)的結(jié)構(gòu)體類型的變量時才會在占用內(nèi)存空間。

那么怎么定義一個結(jié)構(gòu)體類型的變量呢?

KEY_tKEY1;

然后就要初始化結(jié)構(gòu)體的成員變量了。

KEY_tKEY1={0,0,KEY_init,KEY_detect};

這里要注意了現(xiàn)在結(jié)構(gòu)體有四個成員,前兩個普通的變量,我們初始化為0,還有兩個函數(shù)指針,我們是不是要把我們想寫得函數(shù)的函數(shù)名字放在這里啊。

那么聰明的你肯定知道還要定義KEY_init();KEY_detect();這兩個函數(shù)。這兩個函數(shù)可以這樣寫。

staticvoidKEY_init()
{
GPIO_InitTypeDefGPIO_InitStruct;
GPIO_InitStruct.Pin=GPIO_PIN_3;
GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull=GPIO_NOPULL;
GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
}
staticvoidKEY_detect()
{
uint8_ti=0;
if(KEY1.KEY_Flag==1)
{
HAL_Delay(100);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)==GPIO_PIN_SET)
{
printf("按鍵按下
");
}
KEY1.KEY_Flag=0;
}
}

好了具體函數(shù)中的代碼我就不需要解釋了。這樣一個按鍵的對象我們就定義好了,這個按鍵我們賦予了"他"生命,有屬性(變量)有行為(函數(shù))。

這樣我們在主函數(shù)就可以這樣的調(diào)用,來實現(xiàn)相應(yīng)的功能了。按鍵使用了中斷,這里并沒有講解。

voidmain(void)
{
KEY1.KEY_Init();//初始化按鍵
while(1)
{
KEY1.KEY_Detect();//按鍵檢測
}
}

如果理解了這些,那么面向?qū)ο蟮木枘慊疽呀?jīng)掌握了,接下來就是不斷地去練習(xí)和實踐了。

三、為什么要面向?qū)ο螅?/span>

我們知道,現(xiàn)有的編程范式主要是:面向過程編程、面向?qū)ο缶幊?、函?shù)式編程。

對于流程清晰的簡單程序,一般只有一條流程主線,很容易被劃分成順序執(zhí)行的幾個步驟,面向?qū)ο缶幊毯兔嫦蜻^程編程沒有太大差別,并且面向過程編程常常比面向?qū)ο缶幊谈又庇^高效。

但當(dāng)我們面對一個大型的復(fù)雜程序,由于其錯綜復(fù)雜的流程和交互關(guān)系,很難將其簡單地拆分成一條主線串成的簡單步驟,而通常表現(xiàn)為一個網(wǎng)狀關(guān)系結(jié)構(gòu)。這個時候,面向過程編程的這種流程化和線性化的思維方式就會顯得比較吃力,而面向?qū)ο缶幊痰膬?yōu)勢就比較明顯了。

面向?qū)ο缶幊田L(fēng)格的代碼更容易復(fù)用、擴(kuò)展和維護(hù)、更高級、更人性化、更適合大規(guī)模復(fù)雜程序的開發(fā)。在Linux中就是用的面向?qū)ο缶幊?,里面有很多的結(jié)構(gòu)體、指針、鏈表等等。如果還沒有接觸到面向?qū)ο缶幊讨荒苷f明你做的東西還不夠復(fù)雜。

在單片機(jī)舉一個例子,一塊開發(fā)板可能會適配不同的屏幕:

那么每一塊板子肯定有不同的代碼適配,在程序中我們可以讀出屏幕的ID,然后通過if判斷來執(zhí)行不同的指令,就行這樣。

如果使用面向?qū)ο缶幊?,那么就可以這樣寫代碼。

typedefstructlcd{
uint8_ttype;
void(*LCD_Init)(void)
}lcd_t,*plcd_t;

intRead_id()
{
/*0:LCDA
*1:LCDB
*/
return0;
}

intGet_Lcd_Type(void)
{
returnRead_id();
}

voidLCDA_Init(void)//屏幕A初始化
{
LCD_WR_REG(0xCF);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xC1);
LCD_WR_DATA(0X30);
}

voidLCDB_Init(void)//屏幕B初始化
{
LCD_WR_REG(0X11);
delay_ms(20);
LCD_WR_REG(0XD0);
LCD_WR_DATA(0X07);
}

lcd_topenedv_com_lcds[]={
{0,LCDA_Init},
{1,LCDB_Init},
};

plcd_tget_lcd(void)//獲取到屏幕類型
{
inttype=Get_Lcd_Type();
return&openedv_com_lcds[type];
}

intmain(void)
{
plcd_tlcd;
lcd=get_lcd();//獲取到屏幕類型
lcd->LCD_Init();//初始化對應(yīng)屏幕
while(1)
{}
}

這里只是偽代碼處理辦法,原理就和上面所講的一樣,在結(jié)構(gòu)體中使用變量和函數(shù)。

到這里你應(yīng)該掌握了面向?qū)ο蟮?a href="http://m.makelele.cn/v/tag/1778/" target="_blank">單片機(jī)編程方法,一起來試驗幾個例子:

LED

typedefstruct
{
void(*LED_ON)(uint8_tLED_Num);//打開
void(*LED_OFF)(uint8_tLED_Num);//關(guān)閉
void(*LED_Flip)(uint8_tLED_Num);//翻轉(zhuǎn)
}LED_t;

按鍵KEY

typedefstruct
{
uint8_tKEY_Flag;//標(biāo)志位(變量)
uint8_tClick;//按下(變量)
void(*KEY_Init)(void);//按鍵初始化(函數(shù)指針)
void(*KEY_Detect)(void);//按鍵檢測(函數(shù)指針)
}KEY_t;

蜂鳴器BEEP

typedefstruct
{
uint8_tStatus;//狀態(tài)
void(*ON)(void);//打開
void(*OFF)(void);//關(guān)閉
}BEEP_t;

串口UART

typedefstruct
{
USART_TypeDef*uart;/*STM32內(nèi)部串口設(shè)備指針*/
uint8_t*pTxBuf;/*發(fā)送緩沖區(qū)*/
uint8_t*pRxBuf;/*接收緩沖區(qū)*/

uint16_tusTxBufSize;/*發(fā)送緩沖區(qū)大小*/
uint16_tusRxBufSize;/*接收緩沖區(qū)大小*/

uint16_tusTxWrite;/*發(fā)送緩沖區(qū)寫指針*/
uint16_tusTxRead;/*發(fā)送緩沖區(qū)讀指針*/
uint16_tusTxCount;/*等待發(fā)送的數(shù)據(jù)個數(shù)*/

uint16_tusRxWrite;/*接收緩沖區(qū)寫指針*/
uint16_tusRxRead;/*接收緩沖區(qū)讀指針*/
uint16_tusRxCount;/*還未讀取的新數(shù)據(jù)個數(shù)*/

void(*RS485_Set_SendMode)(void);//RS-485接口設(shè)置為發(fā)送模式
void(*RS485_Set_RecMode)(void);//RS-485接口設(shè)置為接收模式
}UART_T;

責(zé)任編輯:haq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6076

    文章

    45495

    瀏覽量

    670444
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3846

    瀏覽量

    85249
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4968

    瀏覽量

    73989

原文標(biāo)題:分享幾點單片機(jī)面向?qū)ο笏枷氲陌咐?/p>

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    單片機(jī)系統(tǒng)設(shè)計方法

    器件對EPROM的軟件進(jìn)行加密.以及采用多單片機(jī)結(jié)構(gòu)來解決加密的問題軟件加密的思想則是通過對程序和數(shù)據(jù)進(jìn)行處理.具體的有插入多條跳轉(zhuǎn)指令降低程序可讀性、程序模塊之間插入一些加密字節(jié)
    發(fā)表于 01-06 06:23

    穎電子8位單片機(jī)的I/O設(shè)置介紹

    嵌入式系統(tǒng)設(shè)計,單片機(jī)的I/O端口設(shè)置是基礎(chǔ)且關(guān)鍵的一環(huán)。今天我們來詳細(xì)解析穎電子8位單片機(jī)的I/O設(shè)置,幫助工程師更好地理解和應(yīng)用。
    的頭像 發(fā)表于 12-30 09:37 ?737次閱讀
    <b class='flag-5'>中</b>穎電子8位<b class='flag-5'>單片機(jī)</b>的I/O設(shè)置介紹

    單片機(jī)引腳的VCC和VDD有什么區(qū)別

    。本文將介紹VCC和VDD的區(qū)別及其單片機(jī)的應(yīng)用。 VCC VCC(Voltage at the Common Collector)是指芯片的電源電壓,通常是5V或3.3V,用于為芯片提供工作電壓
    發(fā)表于 12-16 06:19

    一個面向單片機(jī)、事件驅(qū)動的嵌入式開發(fā)平臺介紹

    EventOS,是一個面向單片機(jī)、事件驅(qū)動的嵌入式開發(fā)平臺。它主要有兩大技術(shù)特色:一是事件驅(qū)動,二是超輕量。EventOS以及其母項目EventOS,目標(biāo)是開發(fā)一個企業(yè)級的嵌入式開發(fā)平臺,以事件總線
    發(fā)表于 12-05 06:26

    怎么學(xué)好單片機(jī)?

    東西是越老越辣,越久越醇,鍛煉多了,自然會精。 假如你一點都不懂,那請看上面的一段,學(xué)硬件基礎(chǔ)去吧。 假如略懂,那么你現(xiàn)在的切入點就是五花八門的單片機(jī)找一款合適的入門單片機(jī),初
    發(fā)表于 12-04 07:16

    什么單片機(jī)比較耐用

    ? ? ? ? 工業(yè)控制、戶外設(shè)備、醫(yī)療儀器等場景,單片機(jī)的耐用性直接決定了設(shè)備的穩(wěn)定運行與維護(hù)成本。耐用的單片機(jī)通常具備寬溫工作范圍、強(qiáng)抗干擾能力、穩(wěn)定的電源適應(yīng)性和長壽命的硬件
    的頭像 發(fā)表于 07-31 13:48 ?781次閱讀

    單片機(jī)的儲存優(yōu)點是什么

    場景。深圳市安凱星科技有限公司單片機(jī)應(yīng)用開發(fā),充分利用這些儲存優(yōu)點,為拓邦、朗科、安徽龍多等客戶打造了高效穩(wěn)定的解決方案。 1.集成度高,節(jié)省硬件空間 單片機(jī)將程序存儲器(ROM)
    的頭像 發(fā)表于 07-31 10:09 ?698次閱讀

    怎么測單片機(jī)系統(tǒng)頻率

    單片機(jī)系統(tǒng)頻率是指單片機(jī)工作時的時鐘頻率,它直接影響單片機(jī)的運行速度和處理能力,準(zhǔn)確測量系統(tǒng)頻率對單片機(jī)應(yīng)用開發(fā)、程序調(diào)試和性能優(yōu)化具有重要意義。測量
    的頭像 發(fā)表于 07-25 11:39 ?794次閱讀

    單片機(jī)怎么驅(qū)動電機(jī)?

    各類自動化設(shè)備和智能裝置,電機(jī)是重要的執(zhí)行部件,而單片機(jī)作為控制核心,需要通過特定的方式驅(qū)動電機(jī)運轉(zhuǎn)。單片機(jī)驅(qū)動電機(jī)并非直接連接即可,而是要根據(jù)電機(jī)類型和功率,搭配合適的驅(qū)動電路,
    的頭像 發(fā)表于 07-25 09:31 ?917次閱讀

    單片機(jī)怎么燒程序

    單片機(jī)燒程序是將編寫好的程序代碼寫入單片機(jī)內(nèi)部存儲單元,讓單片機(jī)按照預(yù)設(shè)邏輯工作的過程,是單片機(jī)應(yīng)用開發(fā)不可或缺的環(huán)節(jié)。無論是簡單的燈光控
    的頭像 發(fā)表于 07-23 11:47 ?1309次閱讀

    低功耗單片機(jī)各型號的對比及選型參考

    不同品牌、不同系列的低功耗單片機(jī)功耗控制、性能表現(xiàn)、外設(shè)配置等方面各有特點,通過低功耗單片機(jī)各型號的對比,能幫助開發(fā)者更精準(zhǔn)地匹配應(yīng)用需求。本文將圍繞主流低功耗單片機(jī)型號展開對比,并
    的頭像 發(fā)表于 07-22 18:25 ?1456次閱讀

    單片機(jī)定制開發(fā)的設(shè)計思路

    。開發(fā)團(tuán)隊需與客戶充分溝通,明確設(shè)備的應(yīng)用場景、功能目標(biāo)、性能指標(biāo)以及成本預(yù)算等。例如,工業(yè)控制設(shè)備單片機(jī)可能需要具備較強(qiáng)的抗干擾能力和實時數(shù)據(jù)處理功能;而在消費電子領(lǐng)域,低功耗和小型化往往是重點考量因素
    的頭像 發(fā)表于 07-17 11:14 ?789次閱讀
    <b class='flag-5'>單片機(jī)</b>定制開發(fā)的設(shè)計思路

    完整版—單片機(jī)編程思想(推薦下載!)

    單片機(jī)的編程思想,希望能幫助大家寫出簡明的代碼 內(nèi)容簡介 以單片機(jī)裸環(huán)境為基礎(chǔ),為編程者定義了一個微操作系統(tǒng)(MOS)的編程環(huán)境,并面向應(yīng)用
    發(fā)表于 04-16 15:06

    單片機(jī)科普總結(jié),建議收藏!

    單片機(jī)(MicrocontrollerUnit,MCU)作為嵌入式系統(tǒng)的核心之一,現(xiàn)代電子產(chǎn)品無處不在。從智能家居、汽車電子,到工業(yè)控制、醫(yī)療設(shè)備,單片機(jī)支撐著無數(shù)智能化應(yīng)用的發(fā)展
    的頭像 發(fā)表于 04-07 11:58 ?5665次閱讀
    <b class='flag-5'>單片機(jī)</b>科普總結(jié),建議收藏!

    晶振受到電磁干擾對單片機(jī)的影響

    單片機(jī)可以正常運行的一個因素就是晶振的穩(wěn)定性。工作過程,晶振可能會受到電磁干擾的影響,導(dǎo)致單片機(jī)發(fā)生故障,甚至出現(xiàn)死機(jī)的情況。
    的頭像 發(fā)表于 03-20 18:01 ?1178次閱讀