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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10967|回復: 17
打印 上一主題 下一主題
收起左側

51單片機定時器中斷進不去

  [復制鏈接]
跳轉到指定樓層
樓主
ID:326418 發表于 2018-5-9 23:12 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
寫了一段單片機外部中斷計數控制定時器輸出0.5khz方波驅動無源蜂鳴器的程序,但是無論下載到開發板上還是isis7模擬,又或者在keil里調試,都無法進入定時器中斷。看著想了一天改了一天,實在是不知道為什么,編程能力真的太菜了。。。。剛注冊,有什么不知道的規矩沒遵守還請見諒,如果帖子違反了版規,我自行刪除。
下面是我的程序。。
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. void delay(uint z);
  5. sbit k0=P3^2;
  6. sbit spk=P0^0;
  7. uchar a=0;

  8. void int0() interrupt 0
  9. {
  10.        if(k0==0)
  11.       {
  12.             a++;
  13.             if(a>3)
  14.             {
  15.                    a=0;
  16.             }
  17.       }
  18. }
  19. void timer0() interrupt 1
  20. {
  21.        spk=!spk;
  22.        TH0=0xFC;
  23.        TL0=0x18;
  24. }
  25. void delay(uint z)
  26. {
  27.        uint x,y;
  28.        for(x=z;z>0;x--)
  29.        for(y=245;y>0;y--);
  30. }
  31. void main()
  32. {  
  33.        TMOD=0X11;
  34.      //IE=0x83;
  35.        EA=1;
  36.        EX0=1;
  37.        IT0=1;
  38.   
  39.    
  40. ET0=1;
  41.      
  42. PT0=1;
  43.      
  44. PX0=0;
  45.      
  46. TH0=0xFC;
  47.      
  48. TL0=0x18;
  49.      
  50. if(a>2)     //就是這里,keil里調試發現a>2的時候還是無法進入定時。
  51.      
  52. {
  53.            
  54. TR0=1;
  55.            
  56. delay(50000);
  57.            
  58. delay(50000);
  59.            
  60.   delay(50000);
  61.            
  62. delay(50000);
  63.      
  64.      
  65.   TR0=0;
  66.      
  67. }
  68. else TR0=0;
  69. while(1);
  70. }
復制代碼


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

使用道具 舉報

來自 2#
ID:326418 發表于 2018-5-10 23:30 | 只看該作者
我要再補一段函數的問題。。。
#include <reg52.h>

sbit MDA = P2^0;   //步進電機驅動口
sbit MDB = P2^1;
sbit MDC = P2^2;
sbit MDD = P2^3;
sbit SEN = P3^2;   //傳感器接口
sbit BUZ = P3^7;   //蜂鳴器
unsigned char time0 = 0; //定時器溢出次數
unsigned char time1 = 0;
unsigned char wei = 0;  //電機驅動指針
unsigned char num = 0;  //計數值
unsigned char flagd = 0; //方向標志
unsigned char second = 0; //秒數

//延時函數
void delay_ms(unsigned int s)
{                           
   unsigned int k;
   while(s--)
   {
     for(k=0; k<120; k++);
   }
}


void main(void)
{
unsigned char flags = 0;
TMOD = 0X11;     //工作模式1:16位計時器
TH0 = (65536-50000)/256;  //T0初值:50ms
TL0 = (65536-50000)%256;
TH1 = (65536-1000)/256;   //T1初值:1ms
TL1 = (65536-1000)%256;
IT0 = 1;      //外部中斷0下降沿觸發
      
EA = 1;       //中斷初始化
ET0  = 1;
ET1  = 1;
EX0 = 1;
PT0=1;
PT1=1;
PX0=0;

while(1)
{
}
}
//外部中斷服務函數
void INT0_ISR(void) interrupt 0
{
EX0 = 0;
delay_ms(10);
if(SEN == 0)  //確認低電平有效
{
  num++;   //遞增
  if(num == 3) //達到3次
  {
   TR0 = 1; //開始工作
   TR1 = 1;
   flagd = 0;
   second = 0;
   return;
  }
  else
  {
   EX0 = 1; //未達3次,使能中斷
  }
}
}

//T0中斷服務函數
void T0_ISR(void) interrupt 1
{
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
time0++;      
if(time0 == 20)    //計時1s
{
  time0 = 0;  
  second++;
  if((second == 60)&&(flagd == 0)) //計時達到60秒
  {
   flagd = 1;     //反向
   second = 0;
  }
  else if((second == 60)&&(flagd == 1)) //反轉60秒,關閉
  {
   flagd=0;
   second=0;
   TR0 = 0;
   TR1 = 0;
   num = 0;
   EX0 = 1;
  }
}
}
//T1中斷服務函數
void T1_ISR(void) interrupt 3
{
TH1 = (65536-1000)/256;
TL1 = (65536-1000)%256;
BUZ = !BUZ;
time1++;
if(time1 == 10) //10ms輸出一個驅動脈沖
{
  time1 = 0;
  if(flagd == 0)  //正轉
  {
   wei = (wei+1)%4; //正向輸出驅動脈沖
  }
  else if(flagd==1)    //反轉
  {
   wei = (wei+3)%4; //反向輸出驅動脈沖
  }
  P2 = 0XFF;     //輸出驅動脈沖
  P2 &= ~(1<<wei);
}
}
這段程序有一個問題,在keil里調試的時候,發現如果定時器0和1在運行中,P3^2口繼續得到信號,EX0在定時器中斷程序運行結束后未被置位,這時P3^2口得到信號就無法進入外部中斷服務程序。
而如果在定時器0和1運行時不給P3^2口信號,定時器中斷程序結束后,這時P3^2口繼續得到信號是可以進入外部中斷程序的。
還有一點是我把程序下進開發板,發現無法運行,怎么給信號都不驅動蜂鳴器和步進電機,但是在keil里調試或在isis7里模擬,是可以輸出方波的。
抓狂中。。。。。

回復

使用道具 舉報

板凳
ID:213173 發表于 2018-5-10 06:29 | 只看該作者
改成這樣試試
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uint z);
sbit k0=P3^2;
sbit spk=P0^0;
uchar a=0;
bit b=0;
void int0() interrupt 0
{
        if(k0==0)
        {
                a++;
                if(a>=3)
                {
                        a=0;
                        b=1;
                }
        }
}
void timer0() interrupt 1
{
        spk=!spk;
//        TH0=0xFC;
//        TL0=0x18;
}

void delay(uint z)
{
        uint x,y;
//        for(x=z;z>0;x--)
        for(x=z;x>0;x--)
                for(y=245;y>0;y--);
}

void main()
{  
        TMOD= 0x02;                //設置定時器模式2,8位自動重載
        TL0 = 0x06;                //設置定時初值,250us
        TH0 = 0x06;                //設置定時重載值
        EA=1;
        EX0=1;
        IT0=1;
        ET0=1;
        PT0=1;
        PX0=0;
//        TH0=0xFC;
//        TL0=0x18;
/*        if(a>2)     //就是這里,keil里調試發現a>2的時候還是無法進入定時。
        {
                TR0=1;
                delay(50000);
                delay(50000);
                delay(50000);
                delay(50000);
                TR0=0;
        }
        else TR0=0;*/
        while(1)
        {
                if(b==1)
                {
                        b=0;
                        TR0=1;
                        delay(50000);
                        delay(50000);
                        delay(50000);
                        delay(50000);
                        TR0=0;
                        spk=1;//恢復初態
                }
        }
}

評分

參與人數 1黑幣 +8 收起 理由
DisTanCeRaIn + 8 很給力!

查看全部評分

回復

使用道具 舉報

地板
ID:289989 發表于 2018-5-10 08:56 | 只看該作者
你這個,我也不是很懂~但是感覺你在第一次判斷a>2時是不成立的,進入else  后面有個while(1)這個不就停這了么?

評分

參與人數 1黑幣 +8 收起 理由
DisTanCeRaIn + 8 很給力!

查看全部評分

回復

使用道具 舉報

5#
ID:164602 發表于 2018-5-10 09:00 | 只看該作者
你的程序,我研究了,修改了一下,可以通過外部中斷按鍵讓蜂鳴器發聲音了。
由于不明白你的a變量是干什么用的,就沒有動這個部分。目前的現象是:
先按鍵,按下第二次,蜂鳴器就開始響了,關不了。不知道你是不是這樣設置的。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uint z);
sbit k0=P3^2;
sbit spk=P0^0;
uchar a=0;

void int0() interrupt 0
{
       if(k0==0)
      {
            a++;
            if(a>3)
            {
                   a=0;
            }
      }
}
void timer0() interrupt 1
{
       spk=!spk;
       TH0=0xFC;
       TL0=0x18;
}
void delay(uint z)
{
       uint x,y;
       for(x=z;z>0;x--)
       for(y=245;y>0;y--);
}
void main()
{  
       TMOD=0X11;
     //IE=0x83;
       EA=1;
       EX0=1;
       IT0=1;
  
   
ET0=1;
     
PT0=1;
     
PX0=0;
     
TH0=0xFC;
     
TL0=0x18;
     

while(1)
{
if(a>2)     //就是這里,keil里調試發現a>2的時候還是無法進入定時。
     
{
           
TR0=1;
           
delay(50000);
           
delay(50000);
           
  delay(50000);
           
delay(50000);
     
     
  TR0=0;
     
}
else TR0=0;
}
}

這是另外一個修改的程序,可以通過按鍵,按若干次,可以讓蜂鳴器一會兒響,一會兒不響,不知道能你有沒有用。也給你吧:
#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int

void delay(uint z);

sbit k0=P3^2;
sbit spk=P0^0;

uchar a=0;

void Delay10ms(unsigned char c)
{
    unsigned char a,b;
    for(;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

void main()
{  
        TMOD = 0x01;                //設置定時器模式
        TL0 = 0x30;                //設置定時初值
        TH0 = 0xF8;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 0;                //定時器0開始計時
        ET0=1;
    EA=1;
    EX0=1;
    IT0=1;
          PT0=0;
    PX0=1;
     
        while(1)
        {
        if(a>2)     //就是這里,keil里調試發現a>2的時候還是無法進入定時。
        {
           
                TR0=1;
           
                Delay10ms(100);
           
     
                TR0=0;
     
        }
        else TR0=0;
       
        }
}

void int0() interrupt 0
{
                        Delay10ms(5);
            a++;
            if(a>3)
            {
                   a=0;
            }
                        IE0=0;
}

void timer0() interrupt 1
{
       spk=!spk;
        TL0 = 0x30;                //設置定時初值
        TH0 = 0xF8;                //設置定時初值
       
}




評分

參與人數 2黑幣 +68 收起 理由
admin + 60 回帖助人的獎勵!
DisTanCeRaIn + 8 很給力!

查看全部評分

回復

使用道具 舉報

6#
ID:318783 發表于 2018-5-10 09:57 | 只看該作者
程序有錯啊
回復

使用道具 舉報

7#
ID:326418 發表于 2018-5-10 19:06 來自手機 | 只看該作者
wulin 發表于 2018-5-10 06:29
改成這樣試試
#include
#define uchar unsigned char

大佬,你改的程序我試了一下,很成功。請教一下,用定時器模式2,進入定時器中斷,主程序在運行的同時定時器也在運行嗎?
回復

使用道具 舉報

8#
ID:326418 發表于 2018-5-10 19:18 來自手機 | 只看該作者
Yubug 發表于 2018-5-10 08:56
你這個,我也不是很懂~但是感覺你在第一次判斷a>2時是不成立的,進入else  后面有個while(1)這個不就停這 ...

是的,我改了一下程序。
while(1)
{
      if(a>2)
      {
           TR0=1;
           delay(50000);
           delay(50000);
           delay(50000);
           delay(50000);
           TR0=0;
       }
      else TR0=0;
}
這樣是會在a累加到3的時候進入定時器中斷,但是新問題是進去后出不來了。。。我需要進入定時器中斷,運行一段時間后退出中斷。二樓用定時器模式二寫的程序成功了。
回復

使用道具 舉報

9#
ID:326418 發表于 2018-5-10 19:49 來自手機 | 只看該作者
HC6800-ES-V2.0 發表于 2018-5-10 09:00
你的程序,我研究了,修改了一下,可以通過外部中斷按鍵讓蜂鳴器發聲音了。
由于不明白你的a變量是干什么 ...

感謝認真的回復!變量a是計算外部中斷次數的,外部中斷設置為下降沿觸發,每當按下一次k0變量a自加1,加到3清零。你的第一部分確實是解決了進不了定時器中斷的問題,但是我發現進去了中斷出不來了。。。第二部分我試了一下,看到外部中斷優先級高,退出定時器中斷是要外部中斷打斷,如果沒有外部中斷打斷是退出不了定時器0的。我原先的設置是定時器優先級高,外部中斷加到3進入定時器中斷,延時一會后退出定時器中斷。
回復

使用道具 舉報

10#
ID:326418 發表于 2018-5-10 20:01 | 只看該作者

是的。。。。樓上指出了。。。
回復

使用道具 舉報

11#
ID:326418 發表于 2018-5-11 11:03 來自手機 | 只看該作者
DisTanCeRaIn 發表于 2018-5-10 23:30
我要再補一段函數的問題。。。
#include


在keil調試模式里仔細研究了一下,發現IT0是置1的,也就是說外部中斷用下降沿觸發,而外部中斷子程序里在進入外部中斷后有一個10毫秒的按鍵防抖,而在定時器中斷程序運行時,給P3^2口發信號是會使IE0置1的,等到T0T1的程序運行結束后,因為IE0為1,直接進入了外部中斷程序,而這時的SEN是不為0的,所以運行到delay_ms(10);后就直接退出了外部中斷,這樣外部中斷就被關閉而不能再進入了,需要按下復位才能再次開啟。
我現在把按鍵防抖去掉了,再在定時器0中斷程序的else if里補上一句IE=0;后,調試成功了。
當然補上IE=0;后不去掉按鍵防抖也是可以的。
回復

使用道具 舉報

12#
ID:326418 發表于 2018-5-11 14:45 來自手機 | 只看該作者
又有新問題,我覺得我問題多到爆炸。。。我在調試和模擬控制蜂鳴器和步進電機的程序時是完全沒有問題的,達到了我的要求,但是下載進開發板后,剛開始是可以成功運行,等蜂鳴器和電機停止后再怎么給信號都不啟動了。我還以為我燒錄了改過前的hex文件,仔細排查后確實是改進后的。。
回復

使用道具 舉報

13#
ID:327624 發表于 2018-5-11 15:33 | 只看該作者
程序問題
回復

使用道具 舉報

14#
ID:213173 發表于 2018-5-11 17:51 | 只看該作者
DisTanCeRaIn 發表于 2018-5-10 19:06
大佬,你改的程序我試了一下,很成功。請教一下,用定時器模式2,進入定時器中斷,主程序在運行的同時定 ...

只要開啟定時器,定時器就與主程序分別運行,只有開啟了定時器中斷,當定時器發生中斷請求時CPU才會暫停運行主程序執行中斷任務,完成中斷任務后再回到暫停點繼續運行主程序。所以中斷任務里不要執行過多代碼。

評分

參與人數 1黑幣 +8 收起 理由
DisTanCeRaIn + 8 十分感謝!

查看全部評分

回復

使用道具 舉報

15#
ID:327962 發表于 2018-5-12 13:08 來自手機 | 只看該作者
你試著把if(a>2)這塊寫到int0()函數里
回復

使用道具 舉報

16#
ID:328160 發表于 2018-5-12 13:44 來自手機 | 只看該作者
去單片機小精靈找一下代碼
回復

使用道具 舉報

17#
ID:328266 發表于 2018-5-12 16:29 | 只看該作者
#include <reg52.h>

sbit MDA = P2^0;   //步進電機驅動口
sbit MDB = P2^1;
sbit MDC = P2^2;
sbit MDD = P2^3;
sbit SEN = P3^2;   //傳感器接口
sbit BUZ = P3^7;   //蜂鳴器
unsigned char time0 = 0; //定時器溢出次數
unsigned char time1 = 0;
unsigned char wei = 0;  //電機驅動指針
unsigned char num = 0;  //計數值
unsigned char flagd = 0; //方向標志
unsigned char second = 0; //秒數

//延時函數
void delay_ms(unsigned int s)
{                           
   unsigned int k;
   while(s--)
   {
     for(k=0; k<120; k++);
   }
}


void main(void)
{
unsigned char flags = 0;
TMOD = 0X11;     //工作模式1:16位計時器
TH0 = (65536-50000)/256;  //T0初值:50ms
TL0 = (65536-50000)%256;
TH1 = (65536-1000)/256;   //T1初值:1ms
TL1 = (65536-1000)%256;
IT0 = 1;      //外部中斷0下降沿觸發
      
EA = 1;       //中斷初始化
ET0  = 1;
ET1  = 1;
EX0 = 1;
PT0=1;
PT1=1;
PX0=0;

while(1)
{
}
}
//外部中斷服務函數
void INT0_ISR(void) interrupt 0
{
EX0 = 0;
delay_ms(10);
if(SEN == 0)  //確認低電平有效
{
  num++;   //遞增
  if(num == 3) //達到3次
  {
   TR0 = 1; //開始工作
   TR1 = 1;
   flagd = 0;
   second = 0;
   return;
  }
  else
  {
   EX0 = 1; //未達3次,使能中斷
  }
}
}

//T0中斷服務函數
void T0_ISR(void) interrupt 1
{
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
time0++;      
if(time0 == 20)    //計時1s
{
  time0 = 0;  
  second++;
  if((second == 60)&&(flagd == 0)) //計時達到60秒
  {
   flagd = 1;     //反向
   second = 0;
  }
  else if((second == 60)&&(flagd == 1)) //反轉60秒,關閉
  {
   flagd=0;
   second=0;
   TR0 = 0;
   TR1 = 0;
   num = 0;
   EX0 = 1;
  }
}
}
//T1中斷服務函數
void T1_ISR(void) interrupt 3
{
TH1 = (65536-1000)/256;
TL1 = (65536-1000)%256;
BUZ = !BUZ;
time1++;
if(time1 == 10) //10ms輸出一個驅動脈沖
{
  time1 = 0;
  if(flagd == 0)  //正轉
  {
   wei = (wei+1)%4; //正向輸出驅動脈沖
  }
  else if(flagd==1)    //反轉
  {
   wei = (wei+3)%4; //反向輸出驅動脈沖
  }
  P2 = 0XFF;     //輸出驅動脈沖
  P2 &= ~(1<<wei);
}
}
回復

使用道具 舉報

18#
ID:304501 發表于 2018-5-12 17:16 | 只看該作者
簡單回家吧回家吧
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 男人的天堂久久 | 国产一区二区欧美 | 欧美日韩国产在线观看 | 亚洲精品电影 | 欧美国产一区二区 | 国产婷婷在线视频 | 中文天堂在线一区 | 久久久www成人免费无遮挡大片 | 亚洲成人久久久 | 久久久久高清 | 日本人爽p大片免费看 | 91黄在线观看 | 蜜臀久久99精品久久久久野外 | 中文字幕欧美日韩 | 欧美精品片 | 国产精品久久久久久久午夜片 | 自拍视频网站 | 欧美亚洲视频在线观看 | av性色全交蜜桃成熟时 | 精品久久久久久久久久久久久久久久久 | 久久se精品一区精品二区 | 国产日韩欧美一区 | 中文字幕1区2区 | 精品欧美一区二区在线观看 | 国产高清视频一区 | 欧美国产日韩一区二区三区 | 亚洲成人一级 | 国产视频一区二区 | 久久午夜国产精品www忘忧草 | 欧美中文在线 | 欧美精品乱码久久久久久按摩 | 国产欧美精品一区二区色综合朱莉 | 国产精品一区二区不卡 | 中文字幕 在线观看 | 欧美在线视频网 | 亚洲国产视频一区二区 | 中文字幕高清免费日韩视频在线 | 国产区第一页 | 香蕉一区| 古装人性做爰av网站 | 99精品视频在线观看免费播放 |