找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7302|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī) 外部中斷 定時(shí)器0 定時(shí)器1 三個(gè)無(wú)法正常工作

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:251195 發(fā)表于 2018-5-6 01:00 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
50黑幣
  1. /*預(yù)處理命令*/
  2. #include<reg52.h>    //包含單片機(jī)寄存器的頭文件
  3. #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  7. sbit LED1 = P1^0;      //定義LED燈,通過(guò)LED顯示調(diào)光效果
  8. sbit LED2 = P1^1;           //用來(lái)對(duì)比PWM
  9. sbit LED3 = P1^2;

  10. sbit IRIN= P3^2;         //紅外接收器數(shù)據(jù)線

  11. sbit rs=P0^7;
  12. sbit rw=P0^6;
  13. sbit lcden=P0^5;

  14. unsigned char time;  //定義周期 該數(shù)字X基準(zhǔn)定時(shí)時(shí)間 如果是10 則占空比是10 x 0.01ms /1ms

  15. void delay(unsigned char x) ;
  16. void delay_ms(uint z);

  17. char code dis []={"Countdown set:"};

  18. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
  19.                         0xf8,0x80,0x90};
  20. uchar IRCOM[7];
  21. uchar count,aa,sec=59,min,hour,ss,sg,ms,mg,hs,hg;

  22. //以下是1602程序
  23. void write_com(uchar com)
  24. {
  25.         rs=0;
  26.         lcden=0;
  27.         P2=com;
  28.         delay_ms(5);
  29.         lcden=1;
  30.         delay_ms(5);
  31.         lcden=0;        
  32. }

  33. void write_date(uchar date)
  34. {
  35.         rs=1;
  36.         lcden=0;
  37.         P2=date;
  38.         delay_ms(5);
  39.         lcden=1;
  40.         delay_ms(5);
  41.         lcden=0;        
  42. }

  43. void lcd_init()
  44. {
  45.         rw=0;
  46.         lcden=0;
  47.         write_com(0x38);
  48.         write_com(0x0c);
  49.         write_com(0x06);
  50.         write_com(0x01);        
  51. }
  52. void write_fm(uchar add,uchar data1,uchar data2)
  53. {        
  54.         write_com(0x80+0x40+add);
  55.         write_date(0x30+data1);
  56.         write_date(0x30+data2);
  57. }



  58. //1602程序到此結(jié)束

  59. void Countup()                           //設(shè)置關(guān)斷時(shí)間
  60. {
  61.         if(min == 60)
  62.         {
  63.                 min = 0;
  64.                 hour++;
  65.                 if(hour == 24)
  66.                 {
  67.                         hour =0;
  68.                 }
  69.         }
  70. }

  71. void init()
  72. {

  73.   IRIN=1;                    //紅外接收器數(shù)據(jù)初始化為高電平        
  74.         EX0 = 1;                  //使能 INT0 外部中斷
  75.         IT0 = 1;               //觸發(fā)方式為脈沖負(fù)邊沿觸發(fā)   相當(dāng)于IT0=1;
  76.         
  77.         TMOD =0x11;              //定時(shí)器設(shè)置 0.01ms in 12M crystal
  78.         TH0=0xff;
  79.         TL0=0xa4;      //定時(shí)器0定時(shí)0.01mS
  80.          
  81.         TH1 = (65535-50000)/256;
  82.         TL1 = (65535-50000)%256;         //定時(shí)器1定時(shí)50mS

  83.         ET0 = 1;
  84.         ET1 = 1;                                 //開啟定時(shí)器中斷

  85.         TR0 = 1;
  86.         TR1 = 0;            //定時(shí)器1暫不開啟
  87.         EA =1;              //允許總中斷中斷,

  88. }
  89. /*******************************************************************/
  90. void main()
  91. {
  92.     char i;
  93.         time = 10;               // 時(shí)間可以調(diào)整 這個(gè)是10調(diào)整 8位PWM就是256步
  94.         init();
  95.         lcd_init();
  96.         write_com(0x80);         //顯示初始界面
  97.         i=0;
  98.         while (dis [i]!='\0')
  99.         {
  100.                 write_date(dis [i]);
  101.                 i++;        
  102.         }

  103.         write_fm(4,hs,hg);                //顯示初始時(shí)間
  104.         write_date(':');
  105.         write_fm(7,ms,mg);
  106.         write_date(':');
  107.         write_fm(10,ss,sg);
  108.         
  109.         while(!TR1);        //等待紅外啟動(dòng)
  110.         
  111.         while(TR1)
  112.         {
  113.                 write_fm(0,IRCOM[5],IRCOM[6]);                //顯示紅外鍵值
  114.                 Countup();
  115.                 ss = sec/10;
  116.                 sg = sec%10;
  117.                 ms = min/10;
  118.                 mg = min%10;
  119.                 hs = hour/10;
  120.                 hg = hour%10;                           
  121.                 write_fm(4,hs,hg);
  122.                 write_date(':');
  123.                 write_fm(7,ms,mg);
  124.                 write_date(':');
  125.                 write_fm(10,ss,sg);                   //1602顯示時(shí)間00:00:59
  126.                 if(sec == 0 && min == 0 && hour == 0)
  127.                         {        
  128.                                 TR1 = 0;                        //停止計(jì)時(shí)
  129.                                 LED1 = 1;           //PWM燈關(guān)閉
  130.                         }

  131.         }

  132. }
  133. /**********************************************************/
  134. void IR_IN() interrupt 0 using 0                                 //外部中斷觸發(fā),接收到紅外信號(hào)
  135. {
  136.         unsigned char j,k,N=0;
  137.         unsigned char q=0;
  138.         EX0 = 0;   
  139.         delay(15);
  140.         if (IRIN==1)
  141.         {
  142.                 EX0 =1;
  143.                 return;
  144.         }
  145.                    //確認(rèn)IR信號(hào)出現(xiàn)
  146.         while (!IRIN)            //等IR變?yōu)楦唠娖,跳過(guò)9ms的前導(dǎo)低電平信號(hào)。
  147.                 delay(1);
  148.         
  149.         for (j=0;j<4;j++)         //收集四組數(shù)據(jù)
  150.         {
  151.                 for (k=0;k<8;k++)        //每組數(shù)據(jù)有8位
  152.                 {
  153.                         while (IRIN)            //等 IR 變?yōu)榈碗娖,跳過(guò)4.5ms的前導(dǎo)高電平信號(hào)。
  154.                         {delay(1);}
  155.                         while (!IRIN)          //等 IR 變?yōu)楦唠娖?br />
  156.                                 delay(1);
  157.                         while (IRIN)           //計(jì)算IR高電平時(shí)長(zhǎng)
  158.                         {
  159.                                 delay(1);
  160.                                 N++;           
  161.                                 if (N>=30)                                  //超時(shí)數(shù)據(jù)接收完畢
  162.                                 {
  163.                                         EX0=1;
  164.                                         return;
  165.                                 }                  //0.14ms計(jì)數(shù)過(guò)長(zhǎng)自動(dòng)離開。
  166.                         }                        //高電平計(jì)數(shù)完畢               
  167.                         IRCOM[j]=IRCOM[j] >> 1;     //數(shù)據(jù)最高位補(bǔ)“0”           位操作
  168.                         if(N>=8)
  169.                         {
  170.                                 IRCOM[j] = IRCOM[j] | 0x80;                  //數(shù)據(jù)最高位補(bǔ)“1”
  171.                         }  
  172.                         N=0;
  173.                 }
  174.         }
  175.         
  176.         if(IRCOM[2]!=~IRCOM[3])
  177.         {
  178.                 EX0=1;
  179.                 return;
  180.         }
  181.         
  182.         IRCOM[5]=IRCOM[2] & 0x0F;     //取鍵碼的低四位
  183.         IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位變?yōu)榈退奈?br />
  184.         
  185.         if(IRCOM[5]>9)
  186.         {
  187.                 IRCOM[5]=IRCOM[5]+0x37;
  188.         }
  189.         else
  190.         IRCOM[5]=IRCOM[5]+0x30;
  191.         
  192.         if(IRCOM[6]>9)
  193.         {
  194.                 IRCOM[6]=IRCOM[6]+0x37;
  195.         }
  196.         else
  197.         IRCOM[6]=IRCOM[6]+0x30;

  198.         q= (((IRCOM[6]&0x0f)<<4) + (IRCOM[5]&0x0f));

  199.         

  200.         switch(q)    //判斷按鍵鍵碼值
  201.         {
  202.                 case 0x16:
  203.                         time = 99;break; //串口發(fā)送0
  204.                 case 0x03:
  205.                         time = 10;break;  //串口發(fā)送01
  206.                 case 0x18:
  207.                         min = min+2;break;  //串口發(fā)送02           設(shè)置關(guān)斷時(shí)間
  208.                 case 0x55:
  209.                         time = 30;break;  //串口發(fā)送03
  210.                 case 0x08:
  211.                         ET1=1;TR1=1;break;  //串口發(fā)送04                        計(jì)時(shí)開始
  212.                 case 0x13:
  213.                         time = 50;break;  //串口發(fā)送05
  214.                 case 0x51:
  215.                         LED1 = 1;break;  //串口發(fā)送06                         關(guān)斷LED1;
  216.                 case 0x42:
  217.                         time = 70;break;  //串口發(fā)送07
  218.                 case 0x52:
  219.                         LED1 = 0;break;  //串口發(fā)送08      開啟LED1
  220.                 case 0x41:
  221.                         time = 90;break;  //串口發(fā)送09
  222.         
  223.                 default :
  224.                         break;
  225.         }

  226.          EX0 = 1;
  227. }


  228. //定時(shí)器0中斷函數(shù)
  229. void tim0(void) interrupt 1 using 1
  230. {               
  231.         TH0=0xff;
  232.         TL0=0xa4;     //設(shè)置中斷時(shí)間0.01mS
  233.         count++;
  234.         if(count<=time)
  235.         {
  236.                 LED1 = 0;
  237.         }
  238.         else
  239.         {
  240.                 LED1 =1;
  241.         }
  242.         if(count>=100)  //周期1ms
  243.         {
  244.                 count =0;
  245.         }
  246. }

  247. void timer3() interrupt 3 using 3
  248. {
  249.         TH1 = (65535-50000)/256;
  250.         TL1 = (65535-50000)%256;
  251.         aa++;

  252.         if(aa == 20)
  253.         {
  254.                 aa = 0;
  255.                 sec--;
  256.                 if(sec == 0)
  257.                 {
  258.                         sec = 59;
  259.                         min--;
  260.                         if(min == 0)
  261.                         {
  262.                            min  = 59;
  263.                            hour--;
  264.                            if(hour == 0)
  265.                            {
  266.                                            hour =0;
  267.                            }
  268.                         }
  269.                 }
  270.         }
  271. }
  272. /***************延時(shí)函數(shù)*****************************/
  273. void delay(unsigned char x)    //x*0.14MS
  274. {
  275.         unsigned char i;
  276.         while(x--)
  277.         {
  278.                 for (i = 0; i<13; i++) {}
  279.         }
  280. }



  281. void delay_ms(uint z)
  282. {
  283.         uint x,y;
  284.         for(x=z;x>0;x--)
  285.                 for(y=110;y>0;y--);
  286. }

復(fù)制代碼

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

使用道具 舉報(bào)

沙發(fā)
ID:251195 發(fā)表于 2018-5-6 01:02 | 只看該作者
我在想是不是中斷里面寫太多內(nèi)容了
回復(fù)

使用道具 舉報(bào)

板凳
ID:155507 發(fā)表于 2018-5-6 07:33 | 只看該作者
你關(guān)閉中斷比較長(zhǎng)。

中斷響應(yīng)時(shí)間越短,實(shí)時(shí)性就越好。
如果我們關(guān)中斷,那么所有類型的中斷不論什么條件和時(shí)間都不會(huì)進(jìn)入它自己的中斷程序去執(zhí)行工作了。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

地板
ID:319344 發(fā)表于 2018-5-6 08:02 | 只看該作者
雖然還沒看太懂,不過(guò)還是覺得發(fā)現(xiàn)了一些問(wèn)題,外部中斷服務(wù)函數(shù)使用的工作組0,別用0,0是程序不在中斷服務(wù)函數(shù)里執(zhí)行時(shí)用的,改為1或2,還有兩個(gè)定時(shí)器的優(yōu)先級(jí)如果不設(shè)置的話有一個(gè)默認(rèn)的,那個(gè)是不是滿足你的要求?

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

5#
ID:319344 發(fā)表于 2018-5-6 08:23 | 只看該作者
你的程序想實(shí)現(xiàn)的是開始時(shí)等待紅外啟動(dòng)定時(shí)器1,啟動(dòng)后,1602會(huì)顯示59秒,由于啟動(dòng)了計(jì)時(shí),當(dāng)減到0后燈就滅了,也可以設(shè)置延遲兩分鐘滅,對(duì)吧?我覺得你那不是PWM,就是一個(gè)周期性閃爍的燈

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

6#
ID:323222 發(fā)表于 2018-5-6 08:36 | 只看該作者
這個(gè)是不是定時(shí)器沒有開
回復(fù)

使用道具 舉報(bào)

7#
ID:323183 發(fā)表于 2018-5-6 09:20 | 只看該作者
中斷里做得東西太多了,或是卡在那個(gè)地方死循環(huán)了

評(píng)分

參與人數(shù) 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

8#
ID:251195 發(fā)表于 2018-5-7 15:46 | 只看該作者
wenzedong 發(fā)表于 2018-5-6 08:23
你的程序想實(shí)現(xiàn)的是開始時(shí)等待紅外啟動(dòng)定時(shí)器1,啟動(dòng)后,1602會(huì)顯示59秒,由于啟動(dòng)了計(jì)時(shí),當(dāng)減到0后燈就滅 ...

我沒有啟動(dòng)之前,是可以對(duì)PWM燈的亮度進(jìn)行設(shè)置變化的,定義的那個(gè)59秒 我只是想測(cè)試一下,定時(shí)關(guān)斷PWM燈
回復(fù)

使用道具 舉報(bào)

9#
ID:251195 發(fā)表于 2018-5-7 15:48 | 只看該作者
angmall 發(fā)表于 2018-5-6 07:33
你關(guān)閉中斷比較長(zhǎng)。

中斷響應(yīng)時(shí)間越短,實(shí)時(shí)性就越好。

我關(guān)斷的是某一個(gè)功能的中斷,這樣會(huì)影響其他功能中斷嗎?比如說(shuō)我關(guān)閉外部中斷0 EX0 = 0;這樣會(huì)影響定時(shí)器0、1的中斷程序執(zhí)行?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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