国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

第7章 變量進階與點陣LED(7.1 7.2)

137933yu ? 來源:137933yu ? 作者:137933yu ? 2025-12-10 16:25 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

走在馬路上的時候,經常會看到馬路兩側有一些LED點陣的廣告牌,這些廣告牌看起來絢爛奪目,非常吸引人,而且還會變化很多種不同的顯示方式。本章就會學習到點陣LED的控制方式,同時也會學習C語言變量的進階知識——變量的作用域和存儲類別。
7.1變量的作用域
所謂的作用域就是指變量起作用的范圍,也是變量的有效范圍。變量按他的作用域可以分為局部變量和全局變量。
7.1.1局部變量
在一個函數內部聲明的變量是內部變量,它只在本函數內有效,在本函數以外是不能使用的,這樣的變量就是局部變量。此外,函數的形參也是局部變量,形參會在后面講解函數的時候再詳細解釋。
比如第6章程序中定義的unsigned long sec這個變量,它是定義在main函數內部的,所以只能由main函數使用,中斷函數就不能使用這個變量。同理,如果在中斷函數內部定義的變量,在main函數中也是不能使用的。
7.1.2全局變量
在函數外聲明的變量就是全局變量。一個源程序文件可以包含一個或者多個函數,全局變量的作用范圍是從它開始聲明的位置一直到程序結束。
比如第6章程序中定義的unsigned char LedBuff[6]這個數組,它的作用域就是從開始定義的位置一直到程序結束,不管是main函數,還是中斷函數InterruptTimer0,都可以直接使用這個數組。
局部變量只有在聲明它的函數范圍內可以使用,而全局變量可以被作用域內的所有的函數使用。所以在一個函數內既可以使用本函數內聲明的局部變量,也可以使用全局變量。從編程規范上講,一個程序文件內所有的全局變量都應定義在文件的開頭部分,在文件中所有函數之前。
由于C語言函數只有一個返回值,但是卻經常會希望一個函數可以提供或影響多個結果值,這時就可以利用全局變量來實現。但是考慮到全局變量的一些特征,應該限制全局變量的使用,過多使用全局變量也會帶來一些問題。
1、全局變量可以被作用域內所有的函數直接引用,可以增加函數間數據聯系的途徑,但同時加強了函數模塊之間的數據聯系,使這些函數的獨立性降低,對其中任何一個函數的修改都可能會影響到其它函數的執行結果,函數之間過于緊密的聯系不利于程序的維護。
2、全局變量的應用會降低函數的通用性,函數在執行的時候過多依賴于全局變量,不利于函數的重復利用。目前編寫的程序還都比較簡單,就一個.c文件,但以后要學到一個程序中有多個.c文件,當一個函數被另外一個.c文件調用的時候,必須將這個全局變量的變量值一起移植,而全局變量不只被一個函數調用,這樣會引起一些不可預見的后果。
3、過多使用全局變量會降低程序的清晰度,使程序的可讀性下降。在各個函數執行的時候都可能改變全局變量值,往往難以清楚的判斷出每個時刻各個全局變量的值。
4、定義全局變量會永久占用單片機的內存單元,而局部變量只有進入定義局部變量的函數時才會占用內存單元,函數退出后會自動釋放所占用的內存。所以大量的全局變量會額外增加內存消耗。
綜上所述之原因,在編程規范上有一條原則,就是盡量減少全局變量的使用,能用局部變量代替的就不用全局變量。
還有一種特殊情況,在看別人程序的時候請注意,C語言是允許局部變量和全局變量同名的,它們定義后在內存中占有不同的內存單元。如果在同一源文件中,全局變量和局部變量同名,在局部變量作用域范圍內,只有局部變量有效,全局變量不起作用,也就是說局部變量具有更高優先級。但是從編程規范上講,是要避免全局變量與局部變量重名的,從而避免不必要的誤解和誤操作。
7.2變量的存儲類別
變量的存儲類別分為自動、靜態、寄存器和外部這四種。其中后兩種暫不介紹,主要介紹自動變量和靜態變量這兩種。
函數中的局部變量,如果不加static這個關鍵字來修飾,都屬于自動變量,也叫做動態存儲變量。這種存儲類別的變量,在調用該函數的時候系統會給他們分配存儲空間,在函數調用結束后會自動釋放這些存儲空間。動態存儲變量的關鍵字是auto,但是這個關鍵字是可以省略的。
與動態變量對應的就是靜態變量。首先,全局變量均是靜態變量,此外,還有一種特殊的局部變量也是靜態變量。即在定義局部變量時前邊加上static這個關鍵字,加上這個關鍵字的變量就稱之為靜態局部變量,它的特點是,在整個生存期中只賦一次初值,在第一次執行該函數時,它的值就是給定的那個初值,而之后在該函數所有的執行次數中,它的值都是上一次函數執行結束后的值,即它可以保持前次的執行結果。
有這樣一種情況,某個變量只在一個函數中使用,但是卻想在函數多次調用期間保持住這個變量的值而不丟失,也就是說在該函數的本次調用中該變量值的改變要依賴與上一次調用函數時的值,而不能每次都從初值開始。如果使用局部動態變量的話,每次進入函數后上一次的值就丟失了,它每次都從初值開始,如果定義成全局變量的話,又違背了上面提到的盡量減少全局變量的使用這條原則,那么此時,局部靜態變量就是最好的解決方案了。
比如第6章最后的例程中有一個控制數碼管動態掃描顯示用的索引變量i和實現秒定時的計數變量cnt,當時就是定義成了全局變量,現在就可以改成局部靜態變量來試試。
#include

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char code LedChar[] = { //數碼管顯示字符轉換表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //數碼管顯示緩沖區,初值0xFF確保啟動時都不亮
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char flag1s = 0; //1秒定時標志

void main()
{
unsigned long sec = 0; //記錄經過的秒數

EA = 1; //使能總中斷
ENLED = 0; //使能U3,選擇控制數碼管
ADDR3 = 1; //因為需要動態改變ADDR0-2的值,所以不需要再初始化了
TMOD = 0x01; //設置T0為模式1
TH0 = 0xFC; //為T0賦初值0xFC67,定時1ms
TL0 = 0x67;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動T0

while (1)
{
if (flag1s == 1) //判斷1秒定時標志
{
flag1s = 0; //1秒定時標志清零
sec++; //秒計數自加1
//以下代碼將sec按十進制位從低到高依次提取并轉為數碼管顯示字符
LedBuff[0] = LedChar[sec%10];
LedBuff[1] = LedChar[sec/10%10];
LedBuff[2] = LedChar[sec/100%10];
LedBuff[3] = LedChar[sec/1000%10];
LedBuff[4] = LedChar[sec/10000%10];
LedBuff[5] = LedChar[sec/100000%10];
}
}
}
/* 定時器0中斷服務函數 */
void InterruptTimer0() interrupt 1
{
static unsigned char i = 0; //動態掃描的索引,定義為局部靜態變量
static unsigned int cnt = 0; //記錄T0中斷次數,定義為局部靜態變量

TH0 = 0xFC; //重新加載初值
TL0 = 0x67;
cnt++; //中斷次數計數值加1
if (cnt >= 1000) //中斷1000次即1秒
{
cnt = 0; //清零計數值以重新開始下1秒計時
flag1s = 1; //設置1秒定時標志為1
}
//以下代碼完成數碼管動態掃描刷新
P0 = 0xFF; //顯示消隱
switch (i)
{
case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
default: break;
}
}
注意看程序中中斷函數里的局部變量i,為其加上了static關鍵字來修飾,就成為了靜態局部變量。它的初始化i = 0操作只進行一次,程序執行代碼中會進行i++等操作,那么下次再進入中斷函數的時候,i會保持上次中斷函數執行完畢后的值。如果去掉static這個關鍵字,那么每次進入中斷函數后,i都會被初始化成0,可以自己修改程序看一下實際效果是否和理論相符。

審核編輯 黃宇

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

    關注

    243

    文章

    24458

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    8 函數進階與按鍵(8.1 8.2)

    用戶與單片機之間的信息交互需要依賴于兩類設備:輸入設備和輸出設備。前邊講的LED小燈、數碼管、點陣都是輸出設備,本章就來學習一下最常用的輸入設備——按鍵,同時還會學到一些硬件電路的基礎知識與C語言
    的頭像 發表于 12-18 11:27 ?98次閱讀
    <b class='flag-5'>第</b>8<b class='flag-5'>章</b> 函數<b class='flag-5'>進階</b>與按鍵(8.1 8.2)

    7 變量進階點陣LED(7.5 7.6)

    7.5?點陣的動畫顯示 點陣的動畫顯示,說到底就是對多張圖片分別進行取模,使用程序算法巧妙的切換圖片,多張圖片組合起來就成了一段動畫了,動畫片、游戲等等基本原理也都是如此。 7.5.1?點陣的縱向
    的頭像 發表于 12-17 16:51 ?2669次閱讀
    <b class='flag-5'>第</b><b class='flag-5'>7</b><b class='flag-5'>章</b> <b class='flag-5'>變量</b><b class='flag-5'>進階</b>與<b class='flag-5'>點陣</b><b class='flag-5'>LED</b>(7.5 7.6)

    7 變量進階點陣LED(7.3 7.4)

    LED點陣就要輕松得多了。一個數碼管是8個LED組成,同理,一個8*8的點陣就是由64個LED小燈組成。圖
    的頭像 發表于 12-11 14:56 ?219次閱讀
    <b class='flag-5'>第</b><b class='flag-5'>7</b><b class='flag-5'>章</b> <b class='flag-5'>變量</b><b class='flag-5'>進階</b>與<b class='flag-5'>點陣</b><b class='flag-5'>LED</b>(7.3 7.4)

    FZH367 具有獨立自動呼吸功能的LED(12×16)點陣驅動芯片 原廠技術支持

    概述 型號:FZH367FZH367是一種具有獨立自動呼吸功能的LED(12×16)點陣驅動芯片。芯片通過I2C協議控制每個LED實現 3 種自動呼吸模式及PMW模式的切換控制。此外,芯片具備
    發表于 11-18 09:18

    原廠 FZH365 具有獨立自動呼吸功能的LED(12×12)點陣驅動芯片

    是一種具有獨立自動呼吸功能的LED(12×12)點陣驅動芯片。芯片通過I2C協議控制每個 LED實現 3 種自動呼吸模式及PMW模式的切換控制。此外,芯片具備對每一個LED的開短路檢
    發表于 11-17 09:38

    原廠 FZH364 一款8×8點陣恒流LED驅動芯片

    )FZH364是一款8×8點陣恒流LED驅動芯片??蓮V泛應用于各種單色調光LED顯示系統,或RGB 全彩LED顯示系統。每顆LED都可以通過
    發表于 11-17 09:34

    2 點亮你的LED(2.5)

    程序5個步驟: 1步:芯片型號,選擇STC89C52RC系列下的STC89C52RC/LE52RC,一定不能選錯。 2步:掃描串口,根據查到的
    的頭像 發表于 10-16 10:58 ?335次閱讀
    <b class='flag-5'>第</b>2<b class='flag-5'>章</b> 點亮你的<b class='flag-5'>LED</b>(2.5)

    2 點亮你的LED(2.3 2.4)

    2.3?LED小燈 LED(light-emitting diode),即發光二極管,俗稱LED小燈,它的種類很多,參數也不盡相同,Kingst51開發板上用的是普通的貼片發光二極管。這種二極管通常
    的頭像 發表于 10-15 14:37 ?690次閱讀
    <b class='flag-5'>第</b>2<b class='flag-5'>章</b> 點亮你的<b class='flag-5'>LED</b>(2.3 2.4)

    2 點亮你的LED

    本章的標題是點亮LED,雖然任務很簡單,但是需要了解的單片機基礎知識卻很多,特別是對于初學者,剛開始要在頭腦中建立一個單片機的概念,然后通過點亮一個LED小燈來增加初學者對單片機的興趣和自信
    的頭像 發表于 10-13 15:52 ?351次閱讀
    <b class='flag-5'>第</b>2<b class='flag-5'>章</b>  點亮你的<b class='flag-5'>LED</b>

    Texas Instruments TPS92402 LED點陣控制器數據手冊

    Texas Instruments TPS92402 LED點陣控制器支持8通道獨立照明解決方案,提供高達2.5A像素級LED調光控制,具有4.5V至65V的寬輸入范圍。該器件包括一串八個串聯的集成
    的頭像 發表于 07-17 15:56 ?559次閱讀
    Texas Instruments TPS92402 <b class='flag-5'>LED</b><b class='flag-5'>點陣</b>控制器數據手冊

    Texas Instruments TPS92401 LED點陣控制器數據手冊

    FET為單個LED提供PWM調光功能。TPS92401點陣控制器包含一個用于系統時鐘的內部振蕩器,可支持高達16位的集成PWM 發生器,其可編程PWM頻率高達60kHz。這些LED點陣
    的頭像 發表于 07-14 14:38 ?555次閱讀
    Texas Instruments TPS92401 <b class='flag-5'>LED</b><b class='flag-5'>點陣</b>控制器數據手冊

    RK3568驅動指南|第十二篇 GPIO子系統-130 GPIO的調試方法

    RK3568驅動指南|第十二篇 GPIO子系統-130 GPIO的調試方法
    的頭像 發表于 06-03 11:32 ?1021次閱讀
    RK3568驅動指南|第十二篇 GPIO子系統-<b class='flag-5'>第</b>130<b class='flag-5'>章</b> GPIO的調試方法

    RK3568驅動指南|驅動基礎進階篇-進階7 向系統中添加一個系統調用

    RK3568驅動指南|驅動基礎進階篇-進階7 向系統中添加一個系統調用
    的頭像 發表于 05-21 14:15 ?577次閱讀
    RK3568驅動指南|驅動基礎<b class='flag-5'>進階</b>篇-<b class='flag-5'>進階</b><b class='flag-5'>7</b> 向系統中添加一個系統調用

    單片機外圍電路設計 (2版)

    及智能傳感器的接口技術。4闡述單片機測控系統的設計。5闡述數據采集系統及新穎檢測電路的設計。6
    發表于 04-18 16:16

    RK3568驅動指南|第三篇-并發與競爭-19 并發與競爭實驗

    RK3568驅動指南|第三篇-并發與競爭-19 并發與競爭實驗
    的頭像 發表于 02-24 16:26 ?877次閱讀
    RK3568驅動指南|第三篇-并發與競爭-<b class='flag-5'>第</b>19<b class='flag-5'>章</b> 并發與競爭實驗