欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: STC15單片機沒有按照設置的定時時間進入中斷 [打印本頁]

作者: karolyte    時間: 2020-10-20 10:03
標題: STC15單片機沒有按照設置的定時時間進入中斷
現在手上使用的一款IAP15W4K58S4單片機,需要使用到的中斷有定時器T0中斷和串口中斷,使用內部時鐘22.1184Mhz,配置如下:

/*配置并啟動T0,定時時間是5ms*/
void Timer0Init()
{   
    AUXR |= 0x80;                          //定時器時鐘1T模式
    TMOD &= 0xF0;                          //清零T0的控制位
    TH0 = 0xFF;
    TL0 = 0xC9;
    ET0 = 1;                               //使能T0中斷
    TF0 = 0;
    TR0 = 1;                               //啟動T0
}

/*配置串口*/
void UART_init()
{
    SCON = 0x50;    //01010000 SM0.SM1 = 01(最普遍的8位通信),REN = 1(允許接收)
    AUXR |= 0x01;                //串口1選擇定時器2為波特率發生器
        AUXR |= 0x04;                //定時器2時鐘為Fosc,即1T
    T2L = 0xC0;                //設定定時初值
        T2H = 0xFD;                //設定定時初值
        AUXR |= 0x10;                //啟動定時器2

    //下面的代碼設置中斷
    ES = 1;         //開串口1中斷

}


在主函數中的調用如下:
void main()
{
    port_mode();
    Timer0Init();                        //配置T0定時器定時時間5ms,打開T0定時器開始計時
    UART_init();
    EA = 1;                                 //開總中斷
    InitLcd1602();

//    LcdShowStr(0,0,Fun1);
    LcdShowStr(3,0,"F");
    LcdShowStr(8,0,"A-");
    LcdShowStr(0,1,"B-");
    LcdShowStr(8,1,"C-");
    Delay_ms(10);
    ClearZeroKeyAction();   

    while(1)
    {   
        KeyDriver();                        //按鍵驅動里包含了按鍵執行相關的動作
        weigh();                  
        ValueToString(str,val_ShiWu);       //轉為字符串格式的電壓值
//        LcdShowStr(0,1,str);                //顯示到液晶上
        UartSend();
    }
}


現在在軟件仿真中發現,這個定時器中斷并沒有按照設定好的時間即5ms進入中斷,而是只有大約一半的時間就進入了,而且不管怎么更改這個定時時間,它都是維持這個5ms一半的時間進入,就是說跟更改這個定時時間沒關系,但是它也進入中斷,執行了中斷函數,現在查找這個寄存器配置感覺也沒有錯誤,不知道問題出在什么地方?懇請壇友幫忙指正!

作者: g2363451687    時間: 2020-10-20 16:06
    TH0 = 0xFF;     TL0 = 0xC9;改這里,一個是高位一個是地位,兩位拼成一個16位數據,改這個數據就可以了
作者: g2363451687    時間: 2020-10-20 16:08
  TH0 = 0xFF;
    TL0 = 0xC9;這兩個八位數據一個高位一個低位拼成一個16位數據,改這個就行
作者: wulin    時間: 2020-10-20 16:20
22.1184MHz時鐘1T模式不可能設置為5ms定時時長。要改為12T模式。
void Timer0Init(void)                //5毫秒@22.1184MHz
{
        AUXR &= 0x7F;                //定時器時鐘12T模式
        TMOD &= 0xF0;                //設置定時器自動重裝模式
        TL0 = 0x00;                //設置定時初值
        TH0 = 0xDC;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
}


作者: dzbj    時間: 2020-10-20 16:31
不解 沒看到中斷服務程序 那產生了中斷也沒程序接收 有什么用呢 你發的程序里只有T0的初始化 初始化的作用只是開寄存器和給初值 等于你開了中斷但沒有使用中斷啊
作者: karolyte    時間: 2020-10-20 16:35
dzbj 發表于 2020-10-20 16:31
不解 沒看到中斷服務程序 那產生了中斷也沒程序接收 有什么用呢 你發的程序里只有T0的初始化 初始化的作用 ...

使用中斷了下面就是中斷服務函數
/*T0中斷服務函數,執行配置時間定時*/
void Timer0()interrupt 1
{   
        KeyScan();
}

/*串口1中斷服務函數*/
void UART1()interrupt 4
{
    if(RI)
    {
        RI = 0;
        cmdIndex = SBUF;
        cmdArrived = 1;     
    }
    if(TI)
    {
        TI = 0;
        if(cndtxd > 0)
        {
            SBUF = *ptrtxd;
            cndtxd--;
            ptrtxd++;
        }
    }
}
作者: karolyte    時間: 2020-10-20 16:36
g2363451687 發表于 2020-10-20 16:08
TH0 = 0xFF;
    TL0 = 0xC9;這兩個八位數據一個高位一個低位拼成一個16位數據,改這個就行

這個怎么改?這個本身就是計算出來的初值
作者: karolyte    時間: 2020-10-20 16:36
wulin 發表于 2020-10-20 16:20
22.1184MHz時鐘1T模式不可能設置為5ms定時時長。要改為12T模式。
void Timer0Init(void)                //5毫秒@22.1184 ...

改過了,還是不管用的
作者: karolyte    時間: 2020-10-20 16:43
這是用邏輯分析儀抓取的TF0的位數據,間隔還是2ms多,就好像這個T0設置的時間沒有用,我設置的是5ms,但是它也進入中斷了。

作者: karolyte    時間: 2020-10-20 16:45
g2363451687 發表于 2020-10-20 16:06
TH0 = 0xFF;     TL0 = 0xC9;改這里,一個是高位一個是地位,兩位拼成一個16位數據,改這個數據就可以 ...

這個本身就是計算出來的初值
作者: dzbj    時間: 2020-10-20 19:40
karolyte 發表于 2020-10-20 16:35
使用中斷了,下面就是中斷服務函數
/*T0中斷服務函數,執行配置時間定時*/
void Timer0()interrupt 1

你沒設置定時器T0的重裝模式
作者: karolyte    時間: 2020-10-20 23:11
dzbj 發表于 2020-10-20 19:40
你沒設置定時器T0的重裝模式

這個重裝模式已經在配置函數里設置過了,不需要在中斷服務函數里再重新設置了
作者: karolyte    時間: 2020-10-21 08:21
wulin 發表于 2020-10-20 16:20
22.1184MHz時鐘1T模式不可能設置為5ms定時時長。要改為12T模式。
void Timer0Init(void)                //5毫秒@22.1184 ...

已經改為12T模式了,但是結果跟之前一樣
作者: karolyte    時間: 2020-10-21 08:23
會不會是內存不足的原因導致的呢?
作者: amandv    時間: 2020-10-21 19:32
你的程序定時是5uS啊,仿真軟件有時因為單片機設置的問題并不準確.
作者: karolyte    時間: 2020-10-21 21:53
amandv 發表于 2020-10-21 19:32
你的程序定時是5uS啊,仿真軟件有時因為單片機設置的問題并不準確.

是的,我寫錯了,已經改過來的,但是問題還是那樣,沒有改變
作者: wulin    時間: 2020-10-22 06:48
karolyte 發表于 2020-10-20 16:36
改過了,還是不管用的

定時器是單片機的一項基礎功能,并且使用上也沒有什么難度。樓主發的程序不完整,難以準確判斷問題所在。樓主發的定時器設置參數是5us不是5ms。中斷函數根本就不可能正常運行。
作者: karolyte    時間: 2020-10-22 08:05
wulin 發表于 2020-10-22 06:48
定時器是單片機的一項基礎功能,并且使用上也沒有什么難度。樓主發的程序不完整,難以準確判斷問題所在。 ...

是的,我寫的5us,發錯了,不過現在改過來了,但是問題還是老樣子,就是說不管你把時間改成什么樣,它總是維持5ms一半的時間(也就是說2.1ms、2.2ms)這個樣子進入中斷,改這個定時時間不管用。
作者: wulin    時間: 2020-10-22 08:40
karolyte 發表于 2020-10-22 08:05
是的,我寫的5us,發錯了,不過現在改過來了,但是問題還是老樣子,就是說不管你把時間改成什么樣,它總是 ...

你的故障描述不可思議,肯定程序有錯。你把完整程序發上來幫你看看。
作者: liren_sky    時間: 2020-10-22 08:59
把你的程序發上來,設置沒有問題了。
作者: karolyte    時間: 2020-10-22 17:02
wulin 發表于 2020-10-22 06:48
定時器是單片機的一項基礎功能,并且使用上也沒有什么難度。樓主發的程序不完整,難以準確判斷問題所在。 ...

這個就似源碼,可以看一下

作者: wulin    時間: 2020-10-23 08:02
karolyte 發表于 2020-10-22 17:02
這個就似源碼,可以看一下

樓主的程序不能通過編譯,有3段子程序沒有被調用,1項地址空間溢出錯誤以及其它40多項錯誤。
要分步查找錯誤。先屏蔽一部分模塊,調試正常后逐一添加模塊,這樣比較容易找到問題點。
特別提示:使用IAP15Wxx單片機和STC15Wxx單片機是有區別的,STC15W的EEPROM地址是固定的,IAP15W的EEPROM地址是放在用戶程序區剩余區域。如安排不當會造成寫EEPROM數據時破壞用戶程序而發生不可預測的錯誤。
作者: karolyte    時間: 2020-10-23 08:45
wulin 發表于 2020-10-23 08:02
樓主的程序不能通過編譯,有3段子程序沒有被調用,1項地址空間溢出錯誤以及其它40多項錯誤。
要分步查找 ...

不能通過編譯?為啥在我這里可以通過編譯啊,現在只能分步查找錯誤了,謝謝你!
作者: 長風007    時間: 2020-10-23 18:02
我需要看一下你的KeyScan();和KeyDriver();這兩個函數!
作者: robinsonlin    時間: 2020-10-23 18:41
STC有個非常好用的工具,STC-ISP。  我以前也是自己改定時器初值,很多次都是把參數弄錯了 。 后來直接用這個軟件生產的代碼,幾乎沒有在定時器初值,和設置上出過錯。  

stc.jpg (305.4 KB, 下載次數: 97)

stc.jpg

作者: karolyte    時間: 2020-10-23 22:27
長風007 發表于 2020-10-23 18:02
我需要看一下你的KeyScan();和KeyDriver();這兩個函數!

/*按鍵驅動,根據掃描按鍵的狀態,確定哪個按鍵執行動作*/
  1. void KeyDriver()
  2. {
  3.     unsigned char i,j;
  4.     static unsigned char xdata backup[5][4] = {       //按鍵值備份,保存前一次的值
  5.         {1,1,1,1},{1,1,1,1},
  6.         {1,1,1,1},{1,1,1,1},
  7.         {1,1,1,1}
  8.     };
  9.    
  10.     for(i = 0;i < 5;i++)                        //循環檢測4*4矩陣鍵盤
  11.     {
  12.         for(j = 0;j < 4;j++)
  13.         {
  14.             if(backup[i][j] != KeySta[i][j])
  15.             {
  16.                 if(backup[i][j] != 0)          //只有當按鍵是按下時才返回鍵碼值
  17.                 {
  18.                     KeyAction(KeyCodeMap[i][j]);
  19.                 }                                                   
  20.                 backup[i][j] = KeySta[i][j];
  21.             }
  22.         }
  23.     }
  24. }

  25. /*按鍵掃描,增加一行鍵盤*/
  26. void KeyScan()
  27. {
  28.     unsigned char i;
  29.     static unsigned char keyout = 0;                //矩陣按鍵掃描輸出索引
  30.     static unsigned char xdata keybuf[5][4] = {           //鍵盤狀態緩存
  31.         {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
  32.         {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},
  33.         {0xFF,0xFF,0xFF,0xFF}
  34.     };
  35.    
  36. /*掃描輸入,將每行4個鍵盤的當前狀態移入緩存*/   
  37.     keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
  38.     keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
  39.     keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
  40.     keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
  41. /*根據每個鍵盤緩存區中的低四位,判斷鍵盤當前的狀態并更新按鍵的狀態*/
  42.     for(i = 0;i < 4;i++)
  43.     {
  44.         if((keybuf[keyout][i] & 0x0F) == 0x00)
  45.         {
  46.             KeySta[keyout][i] = 0;
  47.         }
  48.         else if((keybuf[keyout][i] & 0x0F) == 0x0F)
  49.         {
  50.             KeySta[keyout][i] = 1;
  51.         }
  52.     }

  53. /*改變輸出*/   
  54.     keyout++;
  55.     if(keyout > 4)
  56.         keyout = 0;
  57.                
  58.     switch(keyout)
  59.     {
  60.         case 0:KEY_OUT_5 = 1;KEY_OUT_4 = 0;break;
  61.         case 1:KEY_OUT_4 = 1;KEY_OUT_3 = 0;break;
  62.         case 2:KEY_OUT_3 = 1;KEY_OUT_2 = 0;break;
  63.         case 3:KEY_OUT_2 = 1;KEY_OUT_1 = 0;break;
  64.         case 4:KEY_OUT_1 = 1;KEY_OUT_5 = 0;break;
  65.         default:break;
  66.     }
  67. }
復制代碼

作者: jokez7    時間: 2020-10-23 22:34
你定時器工作模式設置錯誤,應該設置成模式1    TMOD=0x01;
作者: jokez7    時間: 2020-10-23 22:41
你定時器工作模式設置錯誤,設置在模式0,是13位計數器,應該設置成模式1;TMOD&=0xf0;TMOD|=0x01;
作者: jokez7    時間: 2020-10-23 22:44
你T0工作模式設置錯誤,應設置成模式1

void Timer0Init()
{   
    AUXR |= 0x80;                          //定時器時鐘1T模式
    TMOD &= 0xF0;                          //清零T0的控制位
    TMOD|=0x01;            //工作模式1
    TH0 = 0xFF;
    TL0 = 0xC9;
    ET0 = 1;                               //使能T0中斷
    TF0 = 0;
    TR0 = 1;                               //啟動T0
}

作者: karolyte    時間: 2020-10-24 17:28
robinsonlin 發表于 2020-10-23 18:41
STC有個非常好用的工具,STC-ISP。  我以前也是自己改定時器初值,很多次都是把參數弄錯了 。 后來直接用這 ...

是的,我也是用這個工具設置的參數,發現不是這里的問題,因為我把模型設置為STC89C52就沒有問題
作者: karolyte    時間: 2020-10-24 17:29
jokez7 發表于 2020-10-23 22:34
你定時器工作模式設置錯誤,應該設置成模式1    TMOD=0x01;

我用的是STC15系列的單片機,模式1不是自動重載的,也試過這種模式,沒有用的,我發現把模型設置為STC89C52就沒問題,是不是模型的問題呀?
作者: karolyte    時間: 2020-10-24 17:30
jokez7 發表于 2020-10-23 22:41
你定時器工作模式設置錯誤,設置在模式0,是13位計數器,應該設置成模式1;TMOD&=0xf0;TMOD|=0x01;

我使用的是STC15系列的單片機,模式配置跟51系列的不太一樣哦
作者: karolyte    時間: 2020-10-24 17:31
jokez7 發表于 2020-10-23 22:44
你T0工作模式設置錯誤,應設置成模式1

void Timer0Init()

謝謝您,這個是STC89C51系列的模式配置方式,我使用的是STC15系列的單片機
作者: Y_G_G    時間: 2020-10-24 19:09
哥們你整這玩意好幾天了都沒有搞定嗎?這根本不是什么特困難的事呀
你始終沒有把完整的代碼和仿真圖上傳上來,都N個網友分析來分析去,誰也不知道是你什么代碼
這個是很基礎的東西,手頭上要是有個學習板和一個LED,可以自己單獨寫一個定時器中斷程序,LED每1秒取反一次,不需要什么工具就可以看出來你定時器設定的時間對不對
這只是一個仿真問題,很多人可能覺得:仿真都不行,那實物更不行了,實際上卻是:用了STC的單片機,在時間一類的仿真結果一定是和實際結果不一樣的,那還不如直接燒錄驗證

作者: karolyte    時間: 2020-10-25 23:11
Y_G_G 發表于 2020-10-24 19:09
哥們你整這玩意好幾天了都沒有搞定嗎?這根本不是什么特困難的事呀
你始終沒有把完整的代碼和仿真圖上傳上 ...

STC的單片機,在時間一類的仿真結果確實是和實際結果不一樣的,但不至于相差太多,這個我也嘗試過了,現在的問題是我仿真STC89C52的定時器中斷,就沒有問題,但是仿真STC15的定時器中斷就有問題
作者: karolyte    時間: 2020-10-27 09:05
Y_G_G 發表于 2020-10-24 19:09
哥們你整這玩意好幾天了都沒有搞定嗎?這根本不是什么特困難的事呀
你始終沒有把完整的代碼和仿真圖上傳上 ...

昨天又試了下,發現在KEIL中模型選擇89C2就可以正常使用,但是只能使用定時器的16位計數的12T模式,當然這跟使用的模型有關,但是選擇STC15系列的模型,定時器就不能正常計數,是不是我這個KEIL軟件有問題啊,還有就是STC官方給出的范例,頭文件調用的是“reg51.h”,這個頭文件里有缺省的15系列的寄存器,所以在程序里要進行sfr和初始化,那么15系列的現在也有專用的頭文件了,里面就包含了這些寄存器的sfr,調用這個頭文件庫應該跟之前的調用"reg51.h"再sfr和初始化效果是一樣的吧?
作者: Y_G_G    時間: 2020-10-27 09:43
karolyte 發表于 2020-10-25 23:11
STC的單片機,在時間一類的仿真結果確實是和實際結果不一樣的,但不至于相差太多,這個我也嘗試過了,現 ...

這個時間不一樣就是不一樣的,沒有什么多不多的問題,編程是一個嚴謹的東西,不是說差不多或者什么的就可以了
在實際應用中,最終要求的結果一定是以實際測試的結果為準的,不管你仿真出來怎樣的數據,最終還是要實際測試的,那仿真的意義何在呢?
如果你一定要仿真,那也沒有問題,但是,你始終沒有代碼出來,都是靠網友去猜的,這就是為什么一個一直搞不定有原因
KEIL不管是用STC什么型號,它都是以8051為內核運行的,這15系列和89系列還T0定時器上的應用是一樣的,進入T0定時器中斷的時序是這樣的:1:關閉TR0,2:賦值兩個定時器的值,3開啟TR0并返回

作者: AAA實在    時間: 2020-10-27 10:26
karolyte 發表于 2020-10-27 09:05
昨天又試了下,發現在KEIL中模型選擇89C2就可以正常使用,但是只能使用定時器的16位計數的12T模式,當然 ...

使用15W你要用   15W.H  頭文件   用51.h  是不行的
作者: robinsonlin    時間: 2020-10-27 11:52
仿真的坑很多的,測試定時器,我一般都是在定時器里面這樣做的
void t1int() interrupt 3       
{
        P10 = 1;

        SysTick++;
  if(SysTick%1000 == 0)SysTickSec++;       

        if(DIR==0)
        {
                  if(MotoTick<=60)
                        {                               
                                switch(MotoTick)
                                {
                                        case 0:
                                                PWM_Init(7200);
                                        break;
                                        case 10:
                                                PWM_Init(5400);
                                                break;
                                        case 25:
                                                PWM_Init(4200);
                                                break;
                                        case 35:
                                                PWM_Init(5400);
                                                break;
                                        case 50:
                                                PWM_Init(7200);
                                                break;
                                }
                                MotoTick++;
                        }
                        else
                        {
                                MotoTick = 0;
                                DIR = 1;
                        }
        }
        else if(DIR==1)
        {
                  if(MotoTick<=55)
                        {
                                switch(MotoTick)
                                {
                                        case 0:
                                                PWM_Init(7200);
                                        break;
                                        case 10:
                                                PWM_Init(5400);
                                        break;
                                        case 25:
                                                PWM_Init(4200);
                                        break;
                                        case 30:
                                                PWM_Init(5400);
                                        break;
                                        case 45:
                                                PWM_Init(7200);
                                        break;
                                }
                                MotoTick++;
                        }
                        else
                        {
                                MotoTick = 0;
                                DIR = 0;
                        }
        }
  P10 = 0;
}

用示波器看看P10的波形,定時器周期和定時器效率都一目了然了。畢竟是做實物,不要在軟件層面去糾結。退一萬步說,你用的是有版權的軟件么?
作者: karolyte    時間: 2020-10-27 14:40
Y_G_G 發表于 2020-10-27 09:43
這個時間不一樣就是不一樣的,沒有什么多不多的問題,編程是一個嚴謹的東西,不是說差不多或者什么的就可以 ...

不是說不發代碼,您需要看的代碼是那一部分的,我這邊截取一下給您發過來
作者: 單片機研究協會    時間: 2020-10-27 21:15
能不能實測一下這個單片機的FLASH容量是多少,我之前測試過是55K,然后沒燒錄幾次程序芯片就壞了,不知道是個例還是全部這樣,我之前用的型號是IAP15W4K58S4
作者: karolyte    時間: 2020-10-27 21:39
AAA實在 發表于 2020-10-27 10:26
使用15W你要用   15W.H  頭文件   用51.h  是不行的

使用的15W.H的頭文件
作者: karolyte    時間: 2020-10-27 21:52
robinsonlin 發表于 2020-10-27 11:52
仿真的坑很多的,測試定時器,我一般都是在定時器里面這樣做的
void t1int() interrupt 3       
{

受教了,受教了!
作者: karolyte    時間: 2020-10-27 21:54
單片機研究協會 發表于 2020-10-27 21:15
能不能實測一下這個單片機的FLASH容量是多少,我之前測試過是55K,然后沒燒錄幾次程序芯片就壞了,不知道是 ...

沒燒錄幾次程序芯片就壞了嗎?這也太出乎意料了,你怎么知道是芯片壞的呢?
作者: karolyte    時間: 2020-10-27 21:54
單片機研究協會 發表于 2020-10-27 21:15
能不能實測一下這個單片機的FLASH容量是多少,我之前測試過是55K,然后沒燒錄幾次程序芯片就壞了,不知道是 ...

這個怎么測試它的FLASH容量呢?
作者: wanan06    時間: 2020-10-27 22:03
設置標志位
作者: karolyte    時間: 2020-10-27 22:04
robinsonlin 發表于 2020-10-27 11:52
仿真的坑很多的,測試定時器,我一般都是在定時器里面這樣做的
void t1int() interrupt 3       
{

高手,我得趕緊弄個示波器來,這個邏輯分析儀不是也一樣用嗎?




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1