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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7285|回復: 8
收起左側

51單片機 外部中斷 定時器0 定時器1 三個無法正常工作

[復制鏈接]
ID:251195 發表于 2018-5-6 01:00 | 顯示全部樓層 |閱讀模式
50黑幣
  1. /*預處理命令*/
  2. #include<reg52.h>    //包含單片機寄存器的頭文件
  3. #include<intrins.h> //包含_nop_()函數定義的頭文件
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  7. sbit LED1 = P1^0;      //定義LED燈,通過LED顯示調光效果
  8. sbit LED2 = P1^1;           //用來對比PWM
  9. sbit LED3 = P1^2;

  10. sbit IRIN= P3^2;         //紅外接收器數據線

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

  14. unsigned char time;  //定義周期 該數字X基準定時時間 如果是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程序到此結束

  59. void Countup()                           //設置關斷時間
  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;                    //紅外接收器數據初始化為高電平        
  74.         EX0 = 1;                  //使能 INT0 外部中斷
  75.         IT0 = 1;               //觸發方式為脈沖負邊沿觸發   相當于IT0=1;
  76.         
  77.         TMOD =0x11;              //定時器設置 0.01ms in 12M crystal
  78.         TH0=0xff;
  79.         TL0=0xa4;      //定時器0定時0.01mS
  80.          
  81.         TH1 = (65535-50000)/256;
  82.         TL1 = (65535-50000)%256;         //定時器1定時50mS

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

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

  88. }
  89. /*******************************************************************/
  90. void main()
  91. {
  92.     char i;
  93.         time = 10;               // 時間可以調整 這個是10調整 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);                //顯示初始時間
  104.         write_date(':');
  105.         write_fm(7,ms,mg);
  106.         write_date(':');
  107.         write_fm(10,ss,sg);
  108.         
  109.         while(!TR1);        //等待紅外啟動
  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顯示時間00:00:59
  126.                 if(sec == 0 && min == 0 && hour == 0)
  127.                         {        
  128.                                 TR1 = 0;                        //停止計時
  129.                                 LED1 = 1;           //PWM燈關閉
  130.                         }

  131.         }

  132. }
  133. /**********************************************************/
  134. void IR_IN() interrupt 0 using 0                                 //外部中斷觸發,接收到紅外信號
  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.                    //確認IR信號出現
  146.         while (!IRIN)            //等IR變為高電平,跳過9ms的前導低電平信號。
  147.                 delay(1);
  148.         
  149.         for (j=0;j<4;j++)         //收集四組數據
  150.         {
  151.                 for (k=0;k<8;k++)        //每組數據有8位
  152.                 {
  153.                         while (IRIN)            //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
  154.                         {delay(1);}
  155.                         while (!IRIN)          //等 IR 變為高電平
  156.                                 delay(1);
  157.                         while (IRIN)           //計算IR高電平時長
  158.                         {
  159.                                 delay(1);
  160.                                 N++;           
  161.                                 if (N>=30)                                  //超時數據接收完畢
  162.                                 {
  163.                                         EX0=1;
  164.                                         return;
  165.                                 }                  //0.14ms計數過長自動離開。
  166.                         }                        //高電平計數完畢               
  167.                         IRCOM[j]=IRCOM[j] >> 1;     //數據最高位補“0”           位操作
  168.                         if(N>=8)
  169.                         {
  170.                                 IRCOM[j] = IRCOM[j] | 0x80;                  //數據最高位補“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次,高四位變為低四位
  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; //串口發送0
  204.                 case 0x03:
  205.                         time = 10;break;  //串口發送01
  206.                 case 0x18:
  207.                         min = min+2;break;  //串口發送02           設置關斷時間
  208.                 case 0x55:
  209.                         time = 30;break;  //串口發送03
  210.                 case 0x08:
  211.                         ET1=1;TR1=1;break;  //串口發送04                        計時開始
  212.                 case 0x13:
  213.                         time = 50;break;  //串口發送05
  214.                 case 0x51:
  215.                         LED1 = 1;break;  //串口發送06                         關斷LED1;
  216.                 case 0x42:
  217.                         time = 70;break;  //串口發送07
  218.                 case 0x52:
  219.                         LED1 = 0;break;  //串口發送08      開啟LED1
  220.                 case 0x41:
  221.                         time = 90;break;  //串口發送09
  222.         
  223.                 default :
  224.                         break;
  225.         }

  226.          EX0 = 1;
  227. }


  228. //定時器0中斷函數
  229. void tim0(void) interrupt 1 using 1
  230. {               
  231.         TH0=0xff;
  232.         TL0=0xa4;     //設置中斷時間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. /***************延時函數*****************************/
  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. }

復制代碼

回復

使用道具 舉報

ID:251195 發表于 2018-5-6 01:02 | 顯示全部樓層
我在想是不是中斷里面寫太多內容了
回復

使用道具 舉報

ID:155507 發表于 2018-5-6 07:33 | 顯示全部樓層
你關閉中斷比較長。

中斷響應時間越短,實時性就越好。
如果我們關中斷,那么所有類型的中斷不論什么條件和時間都不會進入它自己的中斷程序去執行工作了。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:319344 發表于 2018-5-6 08:02 | 顯示全部樓層
雖然還沒看太懂,不過還是覺得發現了一些問題,外部中斷服務函數使用的工作組0,別用0,0是程序不在中斷服務函數里執行時用的,改為1或2,還有兩個定時器的優先級如果不設置的話有一個默認的,那個是不是滿足你的要求?

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:319344 發表于 2018-5-6 08:23 | 顯示全部樓層
你的程序想實現的是開始時等待紅外啟動定時器1,啟動后,1602會顯示59秒,由于啟動了計時,當減到0后燈就滅了,也可以設置延遲兩分鐘滅,對吧?我覺得你那不是PWM,就是一個周期性閃爍的燈

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:323222 發表于 2018-5-6 08:36 | 顯示全部樓層
這個是不是定時器沒有開
回復

使用道具 舉報

ID:323183 發表于 2018-5-6 09:20 | 顯示全部樓層
中斷里做得東西太多了,或是卡在那個地方死循環了

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:251195 發表于 2018-5-7 15:46 | 顯示全部樓層
wenzedong 發表于 2018-5-6 08:23
你的程序想實現的是開始時等待紅外啟動定時器1,啟動后,1602會顯示59秒,由于啟動了計時,當減到0后燈就滅 ...

我沒有啟動之前,是可以對PWM燈的亮度進行設置變化的,定義的那個59秒 我只是想測試一下,定時關斷PWM燈
回復

使用道具 舉報

ID:251195 發表于 2018-5-7 15:48 | 顯示全部樓層
angmall 發表于 2018-5-6 07:33
你關閉中斷比較長。

中斷響應時間越短,實時性就越好。

我關斷的是某一個功能的中斷,這樣會影響其他功能中斷嗎?比如說我關閉外部中斷0 EX0 = 0;這樣會影響定時器0、1的中斷程序執行?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 毛片免费在线观看 | 精品在线一区二区三区 | 91精产国品一二三区 | 欧美一区二区三区在线观看 | 久久高清免费视频 | av网站免费在线观看 | 男人天堂手机在线视频 | 久久天天躁狠狠躁夜夜躁2014 | 成人在线免费 | 欧美性猛片aaaaaaa做受 | 亚洲欧美精品在线观看 | 精品中文字幕一区 | 成人自拍av| 国产伦精品一区二区三区照片91 | 欧美一区二区三区免费电影 | 成人欧美一区二区三区在线播放 | 亚洲啪啪| 欧美一区二区三区在线观看 | 成人精品国产一区二区4080 | 天天色官网| 欧美群妇大交群中文字幕 | 久热精品在线播放 | 国产日韩一区二区三区 | 欧美又大粗又爽又黄大片视频 | 国产欧美日韩在线一区 | 无码日韩精品一区二区免费 | av网站免费| 天天干天天爱天天 | 隔壁老王国产在线精品 | 久久久久久久久久性 | 在线观看国产www | 国产一区二区三区免费 | 日韩成人中文字幕 | 久在线视频 | 国产视频中文字幕 | 国产视频一区二区在线观看 | 欧美大片一区二区 | 精品一二三区 | 国产91亚洲精品 | 一级毛片视频 | 亚洲视频一区二区三区 |