久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

單片機(jī)數(shù)碼管動(dòng)態(tài)顯示程序與釋義

 心不留意外塵 2016-11-15
我們?cè)谏弦徽聦W(xué)習(xí)數(shù)碼管靜態(tài)顯示的時(shí)候說到,74HC138 只能在同一時(shí)刻導(dǎo)通一個(gè)三極管,,而我們的數(shù)碼管是靠了 6 個(gè)三極管來控制,,那我們?nèi)绾蝸碜寯?shù)碼管同時(shí)顯示呢?這就用到了動(dòng)態(tài)顯示的概念,。

多個(gè)數(shù)碼管顯示數(shù)字的時(shí)候,,我們實(shí)際上是輪流點(diǎn)亮數(shù)碼管(一個(gè)時(shí)刻內(nèi)只有一個(gè)數(shù)碼管是亮的),利用人眼的視覺暫留現(xiàn)象(也叫余輝效應(yīng)),,就可以做到看起來是所有數(shù)碼管都同時(shí)亮了,,這就是動(dòng)態(tài)顯示,也叫做動(dòng)態(tài)掃描,。

例如:有 2 個(gè)數(shù)碼管,,我們要顯示“12”這個(gè)數(shù)字,先讓高位的位選三極管導(dǎo)通,,然后控制段選讓其顯示“1”,,延時(shí)一定時(shí)間后再讓低位的位選三極管導(dǎo)通,然后控制段選讓其顯示“2”,。把這個(gè)流程以一定的速度循環(huán)運(yùn)行就可以讓數(shù)碼管顯示出“12”,,由于交替速度非常快,,人眼識(shí)別到的就是“12”這兩位數(shù)字同時(shí)亮了,。

那么一個(gè)數(shù)碼管需要點(diǎn)亮多長時(shí)間呢?也就是說要多長時(shí)間完成一次全部數(shù)碼管的掃描呢(很明顯:整體掃描時(shí)間=單個(gè)數(shù)碼管點(diǎn)亮?xí)r間*數(shù)碼管個(gè)數(shù)),?答案是:10ms 以內(nèi),。當(dāng)電視機(jī)和顯示器還處在 CRT(電子顯像管)時(shí)代的時(shí)候,有一句很流行的廣告語——“100Hz無閃爍”,,沒錯(cuò),,只要刷新率大于 100Hz,即刷新時(shí)間小于 10ms,,就可以做到無閃爍,,這也就是我們的動(dòng)態(tài)掃描的硬性指標(biāo)。那么你也許會(huì)問,,有最小值的限制嗎,?理論上沒有,但實(shí)際上做到更快的刷新卻沒有任何進(jìn)步的意義了,,因?yàn)橐呀?jīng)無閃爍了,,再快也還是無閃爍,,只是徒然增加 CPU 的負(fù)荷而已(因?yàn)?1 秒內(nèi)要執(zhí)行更多次的掃描程序)。所以,,通常我們?cè)O(shè)計(jì)
程序的時(shí)候,都是取一個(gè)接近 10ms,,又比較規(guī)整的值就行了,。我們開發(fā)板上有 6 個(gè)數(shù)碼管,那么我們現(xiàn)在就來著手寫一個(gè)數(shù)碼管動(dòng)態(tài)掃描的程序,,實(shí)現(xiàn)兼驗(yàn)證上面講的動(dòng)態(tài)顯示原理,。

我們的目標(biāo)還是實(shí)現(xiàn)秒表功能,只不過這次有 6 個(gè)位了,,最大可以計(jì)到 999999 秒,。那么現(xiàn)在要實(shí)現(xiàn)的這個(gè)程序相對(duì)于前幾章的例程來說就要復(fù)雜的多了,既要處理秒表計(jì)數(shù),,又要處理動(dòng)態(tài)掃描,。在編寫這類稍復(fù)雜的程序時(shí),建議初學(xué)者們先用程序流程圖來把程序的整個(gè)流程理清,,在動(dòng)手寫程序之前先把整個(gè)程序的結(jié)構(gòu)框架搭好,,把每一個(gè)環(huán)節(jié)要實(shí)現(xiàn)的功能先細(xì)化出來,然后再用程序代碼一步一步的去實(shí)現(xiàn)出來,。這樣就可以避免無處下筆的迷茫感了,。如圖 6-1 就是本例的程序流程圖,大家先根據(jù)流程圖把程序的執(zhí)行經(jīng)過在大腦里走一遍,,然后再看接下來的程序代碼,,體會(huì)一下流程圖的作用,看是不是能幫助你更順暢的理清程序流程,。
圖 6-1  數(shù)碼管動(dòng)態(tài)顯示秒表程序流程圖
圖 6-1  數(shù)碼管動(dòng)態(tài)顯示秒表程序流程圖
  1. #include <reg52.h>
  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;
  7. unsigned char code LedChar[] = { //數(shù)碼管顯示字符轉(zhuǎn)換表
  8. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  9. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  10. };
  11. unsigned char LedBuff[6] = { //數(shù)碼管顯示緩沖區(qū),,初值 0xFF 確保啟動(dòng)時(shí)都不亮
  12. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  13. };
  14. void main(){
  15. unsigned char i = 0; //動(dòng)態(tài)掃描的索引
  16. unsigned int cnt = 0; //記錄 T0 中斷次數(shù)
  17. unsigned long sec = 0; //記錄經(jīng)過的秒數(shù)
  18. ENLED = 0; //使能 U3,選擇控制數(shù)碼管
  19. ADDR3 = 1; //因?yàn)樾枰獎(jiǎng)討B(tài)改變 ADDR0-2 的值,,所以不需要再初始化了
  20. TMOD = 0x01; //設(shè)置 T0 為模式 1
  21. TH0 = 0xFC; //為 T0 賦初值 0xFC67,,定時(shí) 1ms
  22. TL0 = 0x67;
  23. TR0 = 1; //啟動(dòng) T0
  24. while (1){
  25. if (TF0 == 1){ //判斷 T0 是否溢出
  26. TF0 = 0; //T0 溢出后,清零中斷標(biāo)志
  27. TH0 = 0xFC; //并重新賦初值
  28. TL0 = 0x67;
  29. cnt++; //計(jì)數(shù)值自加 1
  30. if (cnt >= 1000){ //判斷 T0 溢出是否達(dá)到 1000 次
  31. cnt = 0; //達(dá)到 1000 次后計(jì)數(shù)值清零
  32. sec++; //秒計(jì)數(shù)自加 1
  33. //以下代碼將 sec 按十進(jìn)制位從低到高依次提取并轉(zhuǎn)為數(shù)碼管顯示字符
  34. LedBuff[0] = LedChar[sec%10];
  35. LedBuff[1] = LedChar[sec/10%10];
  36. LedBuff[2] = LedChar[sec/100%10];
  37. LedBuff[3] = LedChar[sec/1000%10];
  38. LedBuff[4] = LedChar[sec/10000%10];
  39. LedBuff[5] = LedChar[sec/100000%10];
  40. }
  41. //以下代碼完成數(shù)碼管動(dòng)態(tài)掃描刷新
  42. if (i == 0)
  43. { ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; }
  44. else if (i == 1)
  45. { ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; }
  46. else if (i == 2)
  47. { ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; }
  48. else if (i == 3)
  49. { ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; }
  50. else if (i == 4)
  51. { ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; }
  52. else if (i == 5)
  53. { ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; }
  54. }
  55. }
  56. }

這段程序,,大家自己抄到 Keil 中,,然后邊抄邊結(jié)合程序流程圖來理解,最終下載到實(shí)驗(yàn)板上看一下運(yùn)行結(jié)果,。其中下邊的 if...else 語句就是每 1ms 快速的刷新一個(gè)數(shù)碼管,,這樣 6個(gè)數(shù)碼管整體刷新一遍的時(shí)間就是 6ms,視覺感官上就是 6 個(gè)數(shù)碼管同時(shí)亮起來了,。

在 C 語言中,, /”等同于數(shù)學(xué)里的除法運(yùn)算,,而“%”等同于我們小學(xué)學(xué)的求余數(shù)運(yùn)算,這個(gè)前邊已有介紹,。如果是 123456 這個(gè)數(shù)字,,我們要正常顯示在數(shù)碼管上,個(gè)位顯示,,就是直接對(duì) 10 取余數(shù),,這個(gè)“6”就出來了,十位數(shù)字就是先除以 10,,然后再對(duì) 10 取余數(shù),,以此類推,就把 6 個(gè)數(shù)字全部顯示出來了,。

對(duì)于多選一的動(dòng)態(tài)刷新數(shù)碼管的方式,,我們?nèi)绻?switch 會(huì)有更好的效果,大家來看一下我們用 switch 語句完成的情況,。
  1. #include <reg52.h>
  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;
  7. unsigned char code LedChar[] = { //數(shù)碼管顯示字符轉(zhuǎn)換表
  8. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  9. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  10. };
  11. unsigned char LedBuff[6] = { //數(shù)碼管顯示緩沖區(qū),,初值 0xFF 確保啟動(dòng)時(shí)都不亮
  12. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  13. };
  14. void main(){
  15. unsigned char i = 0; //動(dòng)態(tài)掃描的索引
  16. unsigned int cnt = 0; //記錄 T0 中斷次數(shù)
  17. unsigned long sec = 0; //記錄經(jīng)過的秒數(shù)
  18. ENLED = 0; //使能 U3,選擇控制數(shù)碼管
  19. ADDR3 = 1; //因?yàn)樾枰獎(jiǎng)討B(tài)改變 ADDR0-2 的值,,所以不需要再初始化了
  20. TMOD = 0x01; //設(shè)置 T0 為模式 1
  21. TH0 = 0xFC; //為 T0 賦初值 0xFC67,,定時(shí) 1ms
  22. TL0 = 0x67;
  23. TR0 = 1; //啟動(dòng) T0
  24. while (1){
  25. if (TF0 == 1){ //判斷 T0 是否溢出
  26. TF0 = 0; //T0 溢出后,清零中斷標(biāo)志
  27. TH0 = 0xFC; //并重新賦初值
  28. TL0 = 0x67;
  29. cnt++; //計(jì)數(shù)值自加 1
  30. if (cnt >= 1000){ //判斷 T0 溢出是否達(dá)到 1000 次
  31. cnt = 0; //達(dá)到 1000 次后計(jì)數(shù)值清零
  32. sec++; //秒計(jì)數(shù)自加 1
  33. //以下代碼將 sec 按十進(jìn)制位從低到高依次提取并轉(zhuǎn)為數(shù)碼管顯示字符
  34. LedBuff[0] = LedChar[sec%10];
  35. LedBuff[1] = LedChar[sec/10%10];
  36. LedBuff[2] = LedChar[sec/100%10];
  37. LedBuff[3] = LedChar[sec/1000%10];
  38. LedBuff[4] = LedChar[sec/10000%10];
  39. LedBuff[5] = LedChar[sec/100000%10];
  40. }
  41. //以下代碼完成數(shù)碼管動(dòng)態(tài)掃描刷新
  42. switch (i){
  43. case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
  44. case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
  45. case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
  46. case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
  47. case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
  48. case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
  49. default: break;
  50. }
  51. }
  52. }
  53. }
程序完成的功能是一模一樣的,,但大家看一下,,switch 語句是不是比 if...else 語句顯得要整齊清爽呢。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多