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

QQ登錄

只需一步,快速開始

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

stc單片機(jī)怎么用定時(shí)器寫有參延時(shí)器?

[復(fù)制鏈接]
ID:72649 發(fā)表于 2021-10-7 08:26 | 顯示全部樓層 |閱讀模式
怎么用stc單片機(jī)寫有參延時(shí)子程序,可以調(diào)用單位為秒的延時(shí),miao(s),調(diào)用時(shí)可以1-n秒。
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2021-10-7 15:52 | 顯示全部樓層
首先,針對(duì)你的標(biāo)題, 延時(shí),不要用定時(shí)器。

其次,如果沒有必要不要用有參延時(shí)子程序,一旦有參,就不會(huì)精準(zhǔn)。(建議)

延時(shí)子程序,需要牽涉到  系統(tǒng)主頻,以及你的編譯軟件(尤其是STC的單片機(jī)),其實(shí)精準(zhǔn)的延時(shí)最好用匯編寫,尤其是STC的單片機(jī),理由下面會(huì)講。
主頻就不說了,應(yīng)該能理解,下面將延時(shí)子程序的時(shí)間計(jì)算。
延時(shí)主要就是讓程序在某地反復(fù)做一些沒意義的事情,延緩下一步操作開始的時(shí)間,常用的方法是:
while(--i);          編譯的時(shí)候,一般會(huì)轉(zhuǎn)成匯編    DJNZ   R7,$     或者 DJNZ    07,$
R7, 是寄存器地址,  07 是直接地址,  在STC不同型號(hào)下 這個(gè)操作的時(shí)鐘數(shù)是不同的。
比如  STC89 , 這個(gè)操作是 24個(gè)時(shí)鐘 相當(dāng)于 2個(gè)NOP
STC 15 系列, 如果 DJNZ R7  那么是 4個(gè)時(shí)鐘,即 4個(gè)NOP,  DJNZ 07 那么就是5個(gè)時(shí)鐘,即5個(gè)NOP
STC 8 系列, 則是 3個(gè)時(shí)鐘, 最后0的時(shí)候 2個(gè)時(shí)鐘, 即 3或 2 個(gè)NOP
現(xiàn)在發(fā)現(xiàn) 要 計(jì)算延時(shí)時(shí)間的復(fù)雜程度了吧? 不同的型號(hào)的STC 要寫不同的延時(shí)函數(shù),
這還只是 針對(duì) while(--i); 的, 如果你 調(diào)皮 用 for 來寫延時(shí)函數(shù), 好要牽涉到  DEC 或者 INC 還要牽涉到 CJNE 這些匯編代碼的時(shí)鐘周期。所以,如果你會(huì)匯編,可以考慮 用匯編寫 延時(shí) ,然后 PUBLIC 讓C程序調(diào)用,這樣比較精準(zhǔn)。  如果不會(huì), 那么建議,延時(shí)的時(shí)間種類不多的話,就用STC的ISP軟件自帶的延時(shí)計(jì)算,做幾個(gè)延時(shí)子函數(shù),會(huì)更好一點(diǎn)。
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2021-10-7 16:14 | 顯示全部樓層
居然忘了正事……
帶參延時(shí)程序?qū)懛ǎ?br />
首先,用STC-ISP自帶的的 延時(shí)程序生成器 生成出 5微秒延時(shí)子程序,delay5us();  1毫秒延時(shí)子程序,delay1ms();
然后,制作如下兩個(gè)帶參子程序:
void  delay_us(unsigned char i)      // 這里一定要用char 不然精準(zhǔn)度會(huì)差很多
{
        while(i--)   delay5us();
}

void  delay_ms(unsigned char i)      // 這里一定要用char 不然精準(zhǔn)度會(huì)差很多
{
        while(i--)   delay1ms();
}

那么,主程序中只要:
delay_ms(10);         //就是延時(shí)10毫秒

delay_us(10);      //就是延時(shí)50微秒

切記,作為基準(zhǔn)的延時(shí)子函數(shù),盡量不要小于4微秒,不然精準(zhǔn)度會(huì)差很多,傳參在微秒級(jí)別必須用單字節(jié)(char) , 毫秒級(jí)別的,可以酌情雙字節(jié)。

回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2021-10-7 16:44 | 顯示全部樓層
  1. void Miao(u8 Sec)
  2. {
  3.         while(Sec)
  4.         {
  5.                 if(!u16_Delayms_Pre)//在一微秒定時(shí)器中減一,直到零
  6.                 {u16_Delayms_Pre = 1000;
  7.                         Sec--;
  8.                 }
  9.         }
  10. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:881715 發(fā)表于 2021-10-7 17:08 來自觸屏版 | 顯示全部樓層
188610329 發(fā)表于 2021-10-7 15:52
首先,針對(duì)你的標(biāo)題, 延時(shí),不要用定時(shí)器。

其次,如果沒有必要不要用有參延時(shí)子程序,一旦有參,就不 ...

老師為什么有參數(shù)不會(huì)很精準(zhǔn)
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2021-10-7 17:16 | 顯示全部樓層
創(chuàng)造生活 發(fā)表于 2021-10-7 17:08
老師為什么有參數(shù)不會(huì)很精準(zhǔn)

傳參牽涉到很多 代碼, 比如:
PUSH  07
MOV  R7,#10
CALL delay
POP  07

而這些,都是占用時(shí)鐘數(shù)的,你要精準(zhǔn)的話,要把這些時(shí)間都算上去,而這些可能就要超過1微秒的時(shí)間了,你說你延時(shí) 2微秒,光這些準(zhǔn)備時(shí)間就1~2 微秒了,你的核心延時(shí)程序怎么寫法才能精準(zhǔn)?所以,沒有10微秒以上延時(shí),是非常不建議傳參延時(shí)的。
回復(fù)

使用道具 舉報(bào)

ID:951974 發(fā)表于 2022-12-21 14:55 | 顯示全部樓層
188610329 發(fā)表于 2021-10-7 15:52
首先,針對(duì)你的標(biāo)題, 延時(shí),不要用定時(shí)器。

其次,如果沒有必要不要用有參延時(shí)子程序,一旦有參,就不 ...

簡(jiǎn)直是胡說八道啊,,應(yīng)該是能不用延時(shí)就不用延時(shí),延時(shí)就是在浪費(fèi)CPU,一直在做無用功。所以最好一個(gè)延時(shí)都不用。這樣才能增強(qiáng)實(shí)時(shí)性。
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2022-12-23 11:30 | 顯示全部樓層
樓主,STC官方例子就有定時(shí)器0~4的用法。舉個(gè)例子:
#define         MAIN_Fosc                24000000UL        //定義主時(shí)鐘

//========================================================================
// 函數(shù): u8        Timer0_Config(u32 time)
// 描述: timer0初始化函數(shù).
// 參數(shù): time: 時(shí)間us.
// 返回: 0: 初始化正確, 1: 重裝值過大, 初始化錯(cuò)誤.
// 版本: V1.0, 2018-3-5
//========================================================================
u8        Timer0_Config(u32 time)        //time值是時(shí)間(單位us)
{
        TR0 = 0;        //停止計(jì)數(shù)
        TMOD &= 0xf0;
       
        time = (u32)(((float)MAIN_Fosc * (float)time)/1000000UL);        //重裝的是時(shí)間(us), 計(jì)算所需要的系統(tǒng)時(shí)鐘數(shù).
        if(time >= (65536UL * 12))        return 1;        //值過大, 返回錯(cuò)誤
        if(time < 65536UL)        AUXR |= 0x80;                //1T mode
        else
        {
                AUXR &= ~0x80;        //12T mode
                time = time / 12;
        }
        time = 65536UL - time;
        TH0 = (u8)(time >> 8);
        TL0 = (u8)(time);

        ET0 = 1;        //允許中斷
//        PT0 = 1;        //高優(yōu)先級(jí)中斷
        TMOD = (TMOD & ~0x03) | 0;        //工作模式, 0: 16位自動(dòng)重裝, 1: 16位定時(shí)/計(jì)數(shù), 2: 8位自動(dòng)重裝, 3: 16位自動(dòng)重裝, 不可屏蔽中斷
        TR0 = 1;        //開始運(yùn)行
        return 0;
}

初始化調(diào)用:
        Timer0_Config(10000);        //定時(shí)時(shí)間 us

//========================================================================
// 函數(shù): void timer0_ISR (void) interrupt TIMER0_VECTOR
// 描述:  timer0中斷函數(shù).
// 參數(shù): none.
// 返回: none.
// 版本: V1.0, 2016-5-12
//========================================================================
void timer0_ISR (void) interrupt TIMER0_VECTOR
{
   P32 = ~P32;
}

回復(fù)

使用道具 舉報(bào)

ID:308903 發(fā)表于 2023-1-3 10:02 | 顯示全部樓層
用 ISP自帶的
回復(fù)

使用道具 舉報(bào)

ID:1060350 發(fā)表于 2023-1-4 21:40 | 顯示全部樓層
編寫一段關(guān)于延時(shí)的函數(shù),主要利用for循環(huán),代碼如下: void delay_ms(unsigned int ms) { unsigned int i; unsigned char j;     for(i=0;i<ms;i++)     {         for(j=0;j<200;j++);         for(j=0;j<102;j++);     }  }
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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