找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3224|回復(fù): 4
收起左側(cè)

交通燈單片機(jī)程序改良與注釋

[復(fù)制鏈接]
ID:753618 發(fā)表于 2020-5-29 16:48 | 顯示全部樓層 |閱讀模式
交通燈程序在單片機(jī)入門級(jí)別的眾多程序中屬于較為復(fù)雜的,其中還用到了intrins.h頭文件,給眾多學(xué)習(xí)者造成困擾。
本人經(jīng)過學(xué)習(xí),在前人的基礎(chǔ)之上,對每一行比較重要的程序均做了注釋說明。希望幫助到列位黑友。
特別說明,intrins.h頭文件的添加與*.c文件的添加步驟實(shí)際上是一樣的。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png

單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. typedef unsigned char uchar;
  4. typedef unsigned int  uint;
  5. sbit k1 = P1^6;
  6. sbit k2 = P1^7;
  7. sbit k3 = P2^7;
  8. sbit k4 = P3^0;
  9. sbit yellowled_dx=P1^1;        //東西黃燈
  10. sbit yellowled_nb=P1^4;        //南北黃燈
  11. uchar code table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
  12. uchar dig;            //位選
  13. uchar led=0;          //偏移量
  14. uchar buf[4];
  15. uchar sec_dx=39;//東西數(shù)碼指示值
  16. uchar sec_nb=39;//南北數(shù)碼指示值
  17. uchar settime_dx;
  18. uchar settime_nb;//倒計(jì)時(shí)設(shè)置的鍵值保存
  19. uchar b;            //定時(shí)器中斷次數(shù)
  20. bit time;           //燈狀態(tài)循環(huán)標(biāo)志,借助time 實(shí)現(xiàn)判斷東西通行還是南北通行
  21. bit int0_time;      //中斷強(qiáng)行標(biāo)志
  22. bit set;            //調(diào)時(shí)方向切換鍵標(biāo)志
  23. /*************************************************
  24. 函數(shù)功能:軟件延時(shí)(約50ms)
  25. **************************************************/
  26. void delay(uint ms)
  27. {
  28.         uint j,k;
  29.         for(j=0;j<ms;j++)
  30.                 for(k=0;k<124;k++);
  31. }
  32. /*************************************************
  33. 函數(shù)功能:加 1 調(diào)整
  34. **************************************************/
  35. void key_ad1()
  36. {
  37.         TR0=0;         //關(guān)定時(shí)器
  38.         if(set==0)
  39.                 sec_nb++; //南北加1S
  40.         else
  41.                 sec_dx++;//東西加1S
  42.         if(sec_nb==100)
  43.                 sec_nb=1;//加到100置1
  44.         if(sec_dx==100)
  45.                 sec_dx=1;//加到100置1       
  46. }
  47. /*************************************************
  48. 函數(shù)功能:減 1 調(diào)整
  49. **************************************************/
  50. void key_dec1()
  51. {
  52.         TR0=0;//關(guān)定時(shí)器
  53.         if(set==0)
  54.                 sec_nb--;  //南北減1S
  55.         else
  56.                 sec_dx--;  //東西減1S
  57.         if(sec_nb==0)
  58.                 sec_nb=99;//減到0重置99       
  59.         if(        sec_dx==0 )
  60.                 sec_dx=99;//減到0重置99       
  61. }
  62. /*************************************************
  63. 函數(shù)功能:按鍵k1-k4掃描
  64. **************************************************/
  65. void key()       
  66. {
  67.         if(k1==0)
  68.         {
  69.                 delay(10);
  70.                 if(k1==0)
  71.                 {
  72.                         while(k1==0);
  73.                         key_ad1();
  74.                 }
  75.         }
  76.         if(k2==0)
  77.         {
  78.                 delay(10);
  79.                 if(k2==0)
  80.                 {
  81.                         while(k2==0);
  82.                         key_dec1();
  83.                 }
  84.         }
  85.         if(k4==0)
  86.         {
  87.                 delay(10);
  88.                 if(k4==0)
  89.                 {
  90.                         while(k4==0);
  91.                         set=!set;
  92.                 }
  93.         }
  94.         if(k3==0&&int0_time==1)  //確認(rèn)調(diào)完(k3按下),同時(shí)中斷強(qiáng)行標(biāo)志為1
  95.         {       
  96.                 TR0=1;   //啟動(dòng)定時(shí)器
  97.                 sec_nb=59;
  98.                 sec_dx=59;
  99.                 int0_time=0;//清標(biāo)志
  100.         }        
  101.         else if(k3==0&&int0_time==0)//確認(rèn)調(diào)完(k3按下),同時(shí)中斷強(qiáng)行標(biāo)志為0
  102.         {
  103.                 TR0=1;
  104.                 settime_nb=sec_nb; //設(shè)置的鍵值返回保存
  105.                 settime_dx=sec_dx; //設(shè)置的鍵值返回保存
  106.         }
  107. }
  108. /*************************************************
  109. 函數(shù)功能:顯示
  110. **************************************************/
  111. void display()
  112. {
  113. /*************************************************
  114. 以下6行實(shí)現(xiàn)給buf[0-3]賦值,決定數(shù)碼管要顯示的數(shù)值
  115. **************************************************/
  116.         buf[1]=sec_dx/10;  //第1位 東西秒十位
  117.         buf[2]=sec_dx%10;  //第2位 東西秒個(gè)位
  118.         buf[3]=sec_nb/10;  //第3位 南北秒十位
  119.         buf[0]=sec_nb%10;  //第4位 南北秒個(gè)位
  120.         P0=table[buf[led]];//賦初值(因?yàn)橐呀?jīng)給led賦初值=0,buf[0]=sec_nb%10)
  121.         delay(2);               //延時(shí)
  122. /*************************************************
  123. 以下6行實(shí)現(xiàn)給P2^0-3賦值,實(shí)現(xiàn)數(shù)碼管的循環(huán)顯示
  124. **************************************************/
  125.         P2=dig;  //給P2賦值dig,因?yàn)槭褂肞2口低4位,如dig = 1110,則P2.0=0,對應(yīng)LED不亮
  126.         dig=_crol_(dig,1); //dig數(shù)值按位向左 1 位帶循環(huán)(如1110-1101-1011-0111-1110)
  127.         led++;             //在這里實(shí)現(xiàn)led = 0、1、2、3,從而實(shí)現(xiàn)動(dòng)態(tài)循環(huán)顯示
  128.         if(led==4)    //led只有 0、1、2、3 四位,分別對應(yīng)buf[]的值,根據(jù)此值查表table[]
  129.         {
  130.                 led=0;
  131.                 dig=0xfe;
  132.         }
  133. }
  134. void main()
  135. {
  136.         TMOD=0x01;        //T0計(jì)數(shù)器工作在模式1
  137.         TH0=0x3C;   //定時(shí)50000毫秒
  138.         TL0=0xB0;   //定時(shí)50000毫秒
  139.         EA=1;       //開總中斷
  140.         ET0=1;      //定時(shí)器T0溢出中斷允許(溢出中斷必須開啟,否則無法計(jì)數(shù))
  141.         TR0=1;      //啟動(dòng)定時(shí)器T0
  142.         EX0=1;      //T0的外部中斷允許
  143.         EX1=1;      //T1的外部中斷允許
  144.         P1=0Xf3;    // P1口低四位0011,對應(yīng)南北紅燈亮,東西黃燈亮
  145.         while(1)
  146.         {
  147.                 key(); //調(diào)用按鍵掃描程序
  148.                 display(); //調(diào)用顯示程序
  149.         }       
  150. }
  151. void T0_server() interrupt 1   //T0中斷服務(wù)程序
  152. {
  153.         b++;
  154.         if(b==10)          // 定時(shí)器中斷次數(shù)。
  155.         {
  156.                 b=0;
  157.                 sec_dx--;
  158.                 sec_nb--;
  159.                 //南北黃燈閃爍判斷               
  160.                 if(sec_nb==3&&time==0)
  161.                 {
  162.                         yellowled_nb=1;//南北黃燈亮
  163.                         delay(300);
  164.                         yellowled_nb=0;
  165.                 }
  166.                 if(sec_nb==2&&time==0)
  167.                 {
  168.                         yellowled_nb=1;//南北黃燈亮
  169.                         delay(300);
  170.                         yellowled_nb=0;
  171.                 }
  172.                 if(sec_nb==1&&time==0)
  173.                 {
  174.                         yellowled_nb=1;//南北黃燈亮
  175.                         delay(300);
  176.                         yellowled_nb=0;
  177.                 }                 
  178.                 //東西黃燈閃判斷            
  179.                 if(sec_dx==3&&time==1)
  180.                 {
  181.                         yellowled_dx=1;//南北黃燈亮
  182.                         delay(300);
  183.                         yellowled_dx=0;
  184.                 }                
  185.                 if(sec_dx==2&&time==1)
  186.                 {
  187.                         yellowled_dx=1;//南北黃燈亮
  188.                         delay(300);
  189.                         yellowled_dx=0;
  190.                 }
  191.                 if(sec_dx==1&&time==1)
  192.                 {
  193.                         yellowled_dx=1;//南北黃燈亮
  194.                         delay(300);
  195.                         yellowled_dx=0;
  196.                 }                       
  197.                 if(sec_dx==0||sec_nb==0) //東西或南北先到達(dá)1S時(shí)即開始重新計(jì)時(shí)
  198.                 {
  199.                         sec_dx=settime_dx;
  200.                         sec_nb=settime_nb; //第一次循環(huán)結(jié)束重置
  201.                         if(time==1)    //借助time 實(shí)現(xiàn)判斷東西通行還是南北通行
  202.                         {
  203. ……………………

  204. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
基于51單片機(jī)交通燈的設(shè)計(jì).zip (94.47 KB, 下載次數(shù): 32)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:34643 發(fā)表于 2020-5-30 06:56 | 顯示全部樓層
看上去效果應(yīng)該不錯(cuò)
回復(fù)

使用道具 舉報(bào)

ID:162664 發(fā)表于 2020-5-30 22:39 | 顯示全部樓層
給你一個(gè)建議:
把 ”軟件延時(shí)“ 這個(gè)函數(shù)去掉。如果做的東西永遠(yuǎn)都是只有寥寥幾個(gè)功能當(dāng)我沒說,實(shí)際項(xiàng)目應(yīng)用的功能太多,程序因?yàn)檫@個(gè)函數(shù)沒辦法實(shí)現(xiàn)多任務(wù)的偽并行。
回復(fù)

使用道具 舉報(bào)

ID:753618 發(fā)表于 2020-5-31 16:14 | 顯示全部樓層
gxslxxm 發(fā)表于 2020-5-30 22:39
給你一個(gè)建議:
把 ”軟件延時(shí)“ 這個(gè)函數(shù)去掉。如果做的東西永遠(yuǎn)都是只有寥寥幾個(gè)功能當(dāng)我沒說,實(shí)際項(xiàng)目 ...

謝謝,因?yàn)槭莿傞_始學(xué)習(xí),很多功能還不大熟練,您說的有道理。
回復(fù)

使用道具 舉報(bào)

ID:753618 發(fā)表于 2020-5-31 16:20 | 顯示全部樓層
51mcu 發(fā)表于 2020-5-30 06:56
看上去效果應(yīng)該不錯(cuò)

借您的寶地做一個(gè)說明:T0中斷服務(wù)程序需要做一點(diǎn)說明。b應(yīng)該是溢出中斷次數(shù),因?yàn)槌踔凳?cb0,相當(dāng)于定時(shí)50ms=0.05s溢出中斷一次,b+1,當(dāng)b=10,即定時(shí)0.5s時(shí),數(shù)碼管數(shù)值減1.
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表