久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 646|回復: 12
打印 上一主題 下一主題
收起左側

關于如何提高代碼的執行效率-進階篇

[復制鏈接]
跳轉到指定樓層
樓主
ID:446156 發表于 2025-3-10 10:55 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我在上一篇帖子簡單展示了如何使用狀態機來替代阻塞延時,這一篇我將向大家展示如何使用結構體和函數指針來構建對象。假設有個需求是需要三個LED分別按照5HZ、1HZ和0.5HZ的頻率來閃爍,我們應該怎么實現它呢?如果按照上篇的解決方案需要三個LED_Twinkle函數,只是函數內部關于開關LED的部分不一樣。這樣存在一個問題,假如LED_Twinkle是一個非常復雜函數,那么寫三遍非常費時費力容易出bug并且編譯出的可執行文件體積還大。于是乎面向對象和代碼分層呼之欲出,廢話不多說先上代碼。

  1. struct LED_Obj
  2. {
  3.    uint8_t Status;
  4.    uint16_t DelayTime_LED;
  5.    void (*LED_OnOff)(uint8_t Com);
  6. };
  7. void LED1_OnOff(uint8_t Com)
  8. {
  9.    if(Com != 0)
  10.    {
  11.      LED1(ON);
  12.    }
  13.    else
  14.    {
  15.      LED1(OFF);
  16.    }
  17. }
  18. void LED2_OnOff(uint8_t Com)
  19. {
  20.    if(Com != 0)
  21.    {
  22.      LED2(ON);
  23.    }
  24.    else
  25.    {
  26.      LED2(OFF);
  27.    }
  28. }
  29. void LED3_OnOff(uint8_t Com)
  30. {
  31.    if(Com != 0)
  32.    {
  33.      LED3(ON);
  34.    }
  35.    else
  36.    {
  37.      LED3(OFF);
  38.    }
  39. }
  40. struct LED_Obj LED1 =
  41. {
  42.    .LED_OnOff = LED1_OnOff
  43. };
  44. struct LED_Obj LED2 =
  45. {
  46.    .LED_OnOff = LED2_OnOff
  47. };
  48. struct LED_Obj LED3 =
  49. {
  50.    .LED_OnOff = LED3_OnOff
  51. };
  52. void DelayTimeCount_ms(uint16_t *DelayTime_Count)
  53. {
  54.    if(*DelayTime_Count==0)
  55.    {
  56.      *DelayTime_Count=0;
  57.    }
  58.    else
  59.    {
  60.      *DelayTime_Count-=1;
  61.    }
  62. }
  63. void Set_Delay_Time(uint16_t Time,uint16_t *DelayTime_Count)
  64. {
  65.    *DelayTime_Count=Time;
  66. }
  67. uint8_t CheckDelay(uint16_t *DelayTime_Count)
  68. {
  69.    if(*DelayTime_Count==0)
  70.    {
  71.      return 0;
  72.    }
  73.    else
  74.    {
  75.      return 1;
  76.    }
  77. }
  78. void LED_Twinkle(struct LED_Obj *LED,uint16_t HarfPeriod)
  79. {
  80.    switch(LED->Status)
  81.    {
  82.      case 0:
  83.      {
  84.         LED->LED_OnOff(ON);
  85.         Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
  86.         LED->Status++;
  87.       }break;
  88.      case 1:
  89.      {
  90.         if(CheckDelay(&LED->DelayTime_LED) == 0)
  91.         {
  92.            LED->Status++;
  93.         }
  94.      }break;
  95.      case 2:
  96.      {
  97.         LED->LED_OnOff(OFF);
  98.         Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
  99.         LED->Status++;
  100.       }break;
  101.      case 3:
  102.      {
  103.        if(CheckDelay(&LED->DelayTime_LED) == 0)
  104.        {
  105.          LED->Status = 0;
  106.        }
  107.      }break;
  108.    }
  109. }
  110. void LED_Run(void)
  111. {
  112.    LED_Twinkle(&LED1,100);
  113.    LED_Twinkle(&LED2,500);
  114.    LED_Twinkle(&LED3,1000);
  115. }
  116. void Task_1mS(void)
  117. {
  118.    DelayTimeCount_ms(&LED1.DelayTime_LED);
  119.    DelayTimeCount_ms(&LED2.DelayTime_LED);
  120.    DelayTimeCount_ms(&LED3.DelayTime_LED);
  121. }
復制代碼



這段代碼涉及到結構體和函數指針的語法知識,關于語法這里不再贅述,我來介紹一下這段代碼是如何面向對象和分層的。
結構體:

struct LED_Obj
{
    uint8_t Status;
    uint16_t DelayTime_LED;
    void (*LED_OnOff)(uint8_t Com);
};



該結構體成員包括運行狀態變量(Status)、LED開關延時變量(DelayTime_LED)以及作為上下層接口用來控制LED開關的函數指針(*LED_OnOff)(uint8_t Com)
硬件層部分:

void LED1_OnOff(uint8_t Com);
void LED2_OnOff(uint8_t Com);
void LED3_OnOff(uint8_t Com);
這三個函數就是控制IO來實現LED開關
結構體實例化(對象):


struct LED_Obj LED1 =
{
    .LED_OnOff = LED1_OnOff
};
struct LED_Obj LED2 =
{
    .LED_OnOff = LED2_OnOff
};
struct LED_Obj LED3 =
{
    .LED_OnOff = LED3_OnOff
};



因為我們有3個LED需要控制,所以需要創建3個LED_Obj對象并實現硬件層和應用層的連接(函數指針初始化,指向一個函數)
應用層:


void LED_Twinkle(struct LED_Obj *LED,uint16_t HarfPeriod)
{
    switch(LED->Status)
    {
        case 0:
        {
            LED->LED_OnOff(ON);
            Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
            LED->Status++;
        }break;
        case 1:
        {
            if(CheckDelay(&LED->DelayTime_LED) == 0)
            {
                LED->Status++;
            }
        }break;
        case 2:
        {
            LED->LED_OnOff(OFF);
            Set_Delay_Time(HarfPeriod,&LED->DelayTime_LED);
            LED->Status++;
        }break;
        case 3:
        {
            if(CheckDelay(&LED->DelayTime_LED) == 0)
            {
                LED->Status = 0;
            }
        }break;
    }
}
void LED_Run(void)
{
    LED_Twinkle(&LED1,100);
    LED_Twinkle(&LED2,500);
    LED_Twinkle(&LED3,1000);
}
void Task_1mS(void)
{
    DelayTimeCount_ms(&LED1.DelayTime_LED);
    DelayTimeCount_ms(&LED2.DelayTime_LED);
    DelayTimeCount_ms(&LED3.DelayTime_LED);
}

至此,我們就實現了三個LED的分別控制。



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:446156 發表于 2025-3-10 11:08 | 只看該作者
注意LED(ON)屬于形式代碼,對于stm32來說可能是HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);或者PAout(15) = 0;對于51單片機來說可能是P1^0 = 0;
回復

使用道具 舉報

板凳
ID:33522 發表于 2025-3-12 07:58 | 只看該作者
雖然看不懂,但是得先點贊
回復

使用道具 舉報

地板
ID:446156 發表于 2025-3-12 16:46 | 只看該作者
wwzgch 發表于 2025-3-12 07:58
雖然看不懂,但是得先點贊

我步子邁大啦?
回復

使用道具 舉報

5#
ID:33522 發表于 2025-3-12 21:41 | 只看該作者

是我這理解能力有待進步,平時都是用8位機。都是簡單的寫法,向群主學習
回復

使用道具 舉報

6#
ID:118322 發表于 2025-3-13 09:05 | 只看該作者
間下AI怎么寫
回復

使用道具 舉報

7#
ID:446156 發表于 2025-3-13 10:06 | 只看該作者
wwzgch 發表于 2025-3-12 21:41
是我這理解能力有待進步,平時都是用8位機。都是簡單的寫法,向群主學習

我回復你之后,你的頁面右上角頭像左邊那里會有提醒嗎
回復

使用道具 舉報

8#
ID:446156 發表于 2025-3-13 16:06 | 只看該作者
大家可以把我上邊的代碼復制到deepseek,NNT的比我解釋的都好
回復

使用道具 舉報

9#
ID:446156 發表于 2025-3-13 16:22 | 只看該作者
我并沒有系統學習過面向對象編程,只是在工作中經常遇到很多重復功能,比如有好多個DS18B20接口(獨立總線),有好多個同型號的IIC設備(獨立總線),有好多個PID控制器等等。經過不斷摸索不斷嘗試,發現這種編寫代碼的方法最高效最易讀最易維護,直到后來我才知道原來我這種寫作方法就是面向對象。狀態機+面向對象可以使工作特別高效,我現在連操作系統都看不上(項目沒那么復雜)。希望初學者不要像我一樣多走好幾年彎路,提早走向面向對象編程的懷抱。
回復

使用道具 舉報

10#
ID:33522 發表于 2025-3-13 18:49 | 只看該作者
qinlu123 發表于 2025-3-13 10:06
我回復你之后,你的頁面右上角頭像左邊那里會有提醒嗎

消息里面會有提醒,平時我登陸這個網站不多
回復

使用道具 舉報

11#
ID:446156 發表于 2025-3-14 07:54 | 只看該作者
發表于 2025-3-13 18:49
消息里面會有提醒,平時我登陸這個網站不多

@admin為啥我沒有提醒
回復

使用道具 舉報

12#
ID:33522 發表于 2025-3-14 10:51 | 只看該作者
qinlu123 發表于 2025-3-13 16:22
我并沒有系統學習過面向對象編程,只是在工作中經常遇到很多重復功能,比如有好多個DS18B20接口(獨立總線 ...

是的,不想被淘汰就要不斷的學習新的編程思想和技巧。樓主平時都用什么MCU做方案
回復

使用道具 舉報

13#
ID:624769 發表于 2025-3-14 23:35 | 只看該作者
標題和內容不符,
標題是: 關于如何提高代碼的執行效率
而實際是: 反而降低了執行效率
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一级毛片大全免费播放 | 欧美成人精品一区 | 黄网站在线播放 | 日日爱夜夜操 | 久久精品一区 | 天天射视频 | 九九亚洲 | 日韩精品免费在线观看 | 国产高清免费 | 欧美亚洲视频 | 国产69久久精品成人看动漫 | 亚洲成人一级 | 亚洲一区二区三区在线 | 在线免费观看成年人视频 | 日韩1区 | 四虎影院在线免费观看 | 国产成人高清视频 | 中文字幕在线观看第一页 | 色视频网站| 美国一级黄色片 | 国产乱码精品1区2区3区 | 日韩欧美不卡 | 欧美一级观看 | 成人午夜免费福利视频 | 国产精品一区二区不卡 | 精品国产一区二区三区免费 | 免费黄色a级毛片 | 日本在线看片 | 欧美一二三 | 精品在线一区 | 精品免费国产一区二区三区 | 91原创视频在线观看 | 国产一区二区三区四区在线观看 | 日韩中文字幕一区二区 | 麻豆视频在线免费观看 | 一区二区三区视频在线 | 国产精品黄色 | 久久人| 亚洲视频免费 | 在线观看国产91 | 最近日韩中文字幕 |