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

標題: 一個關于單片機延時的困惑,想和大家請教 [打印本頁]

作者: laopihappy123    時間: 2020-10-9 21:49
標題: 一個關于單片機延時的困惑,想和大家請教
本帖最后由 laopihappy123 于 2020-10-10 12:06 編輯

學習單片機到現在 總共看到了3種方法進行延時軟延時。
1.定義一個變量 然后while(變量--)
2.用軟件,比如stc-isp或者單片機小精靈生成的一個延時函數
大概是delay1ms()
{
...........
}的樣子
3.最后一種就是用定時器中斷來算了,這個屬于硬件計時了。
平常見大家用的都是第一種比較多,偶爾有第二種的。

問題1 :除了這幾種 不知道還有沒有別的好用的定時方式呢?我有個想法 能不能寫個函數delayms(uint ms)
然后在里面包一個1ms的子函數,用for(i=0;i<ms;i++) 來調用 要多少毫秒來幾次循環不就行了?!

這樣豈不是更加輕松嗎? 我再一想 調用這個1ms子函數應該應該也要耗費時鐘周期的吧?!

問題2 :上述的方式會不會誤差很大呢?我不太懂51單片機的匯編 這個在匯編里應該是JUMP指令吧(?)
但是我又沒有示波器看不到,想到這里,我懊惱起來,就上論壇發了這個帖子,希望能向大家取取經。




作者: 漸入寒冬    時間: 2020-10-10 08:35
單片機運行延時函數的時候進入函數也需要時間,如果要寫一個通過while和for遞增或者遞減變量的延時函數,進入函數需要的時間也需要考慮一下。 而且這種延時不是很準確,如果對延時精度要求不是很高可以用,對精度要求高的情況下,還是使用定時器比較好。
這種通過耗費CPU運行速度的延時,在主時鐘頻率為一個固定值時可以用,但如果主時鐘頻率被更改,CPU的執行速度也會改變,使用這種方法的延時時間也會被改變
作者: Y_G_G    時間: 2020-10-10 09:46
C是做不到一兩個時鐘精度的延時的,除非你在編譯之后再通過匯編來更改,但這并不重要,1mS的延時肯定是不會有太大誤差的
不需要去管匯編的,也不要用小精靈什么的,STC下載器有專門的延時代碼生成,你設定好直接復制就可以用了
STC的8051指令執行時間是很亂的,你只能在STC的下載器那復制
不同單片機型號延時函數是不同的,換了單片機就要更改
作者: gutong    時間: 2020-10-10 09:59
復制來的一些
51單片機的指令有單字節、雙字節和三字節的,它們的指令周期不盡相同,一個單周期指令包含一個機器周期,即12個時鐘周期,所以一條單周期指令被執行所占時間為12*(1/ 晶振頻率)= x μs。常用單片機的晶振為11.0592MHz,12MHz,24MHz。其中11.0592MHz的晶振更容易產生各種標準的波特率,后兩種的一個機器周期分別為1 μs和2 μs,便于精確延時。

接下來列出這三種不同的晶振的延時函數

1、 11.0592MHz

//N ms延時
void delay_ms(uint n)
{
uint i,j;
for(i=n;i>0;i–)
for(y=114;y>0;y–);
}

2、12MHz晶振


//延時n毫秒
void delay_ms(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}
1
2
3
4
5
6
7
8

//延時n秒
void delay_m(unsigned int n)
{
    unsigned int i=0,j=0;
    for(i=0;i<n;i++)
        for(j=0;j<21738;j++);
}
1
2
3
4
5
6
7
8
//延時10*n微秒
void delay_10um(unsigned int n)
{
    while(n--);
}
1
2
3
4
5
3、24MHz晶振

//延時n毫秒
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i

//延時n秒  
void delay_s(unsigned int n)  
{  
    unsigned int i=0,j=0;  
    for(i=0;i<n;i++)  
        for(j=0;j<54053;j++);   
}  
1
2
3
4
5
6
7
//延時10*n微秒  
void delay_10us(unsigned int n)  
{  
    unsigned int i=0;  
    char j=0;  
    for(i=0;i<n;i++)  
        for(j=0;j<2;j++);  
}  
1
2
3
4
5
6
7
8
建議大家封裝為頭文件,可以方便的調用。

接下來介紹幾個自動適應主時鐘的延時函數

//參數:ms,要延時的ms數,自動適應主時鐘  
#define MAIN_Fosc        11059200UL    //定義主時鐘HZ  
typedef unsigned int INT16U;  

void delay_ms(INT16U ms)    //INT16U 等價于 unsigned int  
{  
    INT16U i;  
    do{  
        i=MAIN_Fosc/9600;  
        while(--i);     //96T per loop  
    }while(--ms);       //--ms  ms=ms-1  
}  
1
2
3
4
5
6
7
8
9
10
11
12
//5us 延時函數,自動適應主時鐘  
#define MAIN_Fosc        11059200UL    //定義主時鐘HZ  

void delay5us()  
{  
    #if MAIN_Fosc == 11059200  
        _nop_();  
    #elif MAIN_Fosc == 12000000  
        _nop_();  
    #elif MAIN_Fosc == 22118400  
        _nop_(); _nop_(); _nop_();  
    #elif  
}  
1
2
3
4
5
6
7
8
9
10
11
12
13
單片機中還可自動生成

//11.0592MHZ延時100微秒

void Delay100us()       //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    i = 2;
    j = 15;
    do
    {
        while (--j);
    } while (--i);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//100US

void Delay100us()       //@12.000MHz
{
    unsigned char i, j;

    i = 2;
    j = 39;
    do
    {
        while (--j);
    } while (--i);
}
1
2
3
4
5
6
7
8
9
10
11
12
//100US

void Delay100us()       //@24.000MHz
{
    unsigned char i, j;

    i = 3;
    j = 82;
    do
    {
        while (--j);
    } while (--i);
}
作者: KongQuan    時間: 2020-10-10 10:09
軟件延時,在多事件要處理的情況下,影響響應速度。盡量少用。
當然,如果用操作系統,在任務中,是可以調用系統的延時函數的。
作者: lovezjf234    時間: 2020-10-10 10:49
函數的延時和硬件有很大關系,如果對時間要求比較精確的話,這種函數延時是不可靠的
作者: 1224527279    時間: 2020-10-10 16:15
你的這種延時可以使用,不過只能是使用在延時時間不需要很精確的情況下。
因為for循環中還需要判斷和跳轉之類的操作,所以延時函數執行起來的時間會比預想的時間長,所以你這種方式只能實現大概的延時,而且肯定比預想的時間長,如果碰巧在延時函數執行中遇見了中斷那么延時時間還要另加執行中斷的時間。
時間要求較高的話還是放在中斷里面操作比較穩妥
作者: laopihappy123    時間: 2020-10-10 18:18
1275109681 發表于 2020-10-10 02:18
頂一下

感謝您的回復
作者: laopihappy123    時間: 2020-10-10 18:18
漸入寒冬 發表于 2020-10-10 08:35
單片機運行延時函數的時候進入函數也需要時間,如果要寫一個通過while和for遞增或者遞減變量的延時函數,進 ...

是這樣的 所以還是定時器比較精準
作者: laopihappy123    時間: 2020-10-10 18:19
Y_G_G 發表于 2020-10-10 09:46
C是做不到一兩個時鐘精度的延時的,除非你在編譯之后再通過匯編來更改,但這并不重要,1mS的延時肯定是不會有 ...

這個軟件的確不錯
作者: hmq1208    時間: 2020-10-10 18:19
函數的延時一般要改變硬件系統,所以精確的調整函數的延時是比較難的,容易造成別的軟件也延時
作者: hantu    時間: 2020-10-10 18:25
能,但不精確
作者: TTQ001    時間: 2020-10-11 04:57
還有一種方法可以通過運行NOP指令一定次數來獲得所需的延遲,從而在單片機程序中產生延遲。
作者: kang0512    時間: 2020-10-11 08:05

軟件延時,在多事件要處理的情況下,影響響應速度。盡量少用。
當然,如果用操作系統,在任務中,是可以調用系統的延時函數的。
作者: 單片機研究協會    時間: 2020-10-11 09:43
精確定時用硬件定時器,不精確的定時用指令延時
作者: 123.123.123.    時間: 2020-10-11 12:11
使用定時器延時會更好,比指令延時更加準確,建議使用定時器延時
作者: lovexulu    時間: 2020-10-12 23:06
真心提示,少用延時,因為單片機本身就是資源匱乏。
作者: laopihappy123    時間: 2020-10-13 15:27
lovexulu 發表于 2020-10-12 23:06
真心提示,少用延時,因為單片機本身就是資源匱乏。

那么用硬件定時器嗎...感覺硬件中斷有點麻煩啊
作者: xqleft    時間: 2020-10-13 17:56
laopihappy123 發表于 2020-10-13 15:27
那么用硬件定時器嗎...感覺硬件中斷有點麻煩啊

請問中斷麻煩嗎? 你這邊使用主定時的時候怎么定時的? 還有就時一個案子需要很多定時的時候你怎么用? 還時用延時? 那為什么不用基準的中斷來定時呢,?把所有的定時都在這上面進行計算.這樣多方便啊. 還有就時你們跑主程序while(1)里面的時候都不需要定時?讓它一直不停的指令周期跑?
作者: jiang666lei    時間: 2020-10-13 18:05
我也有此問題,希望解決
作者: Astin    時間: 2020-10-13 19:07
而且肯定比預想的時間長,如果碰巧在延時函數執行中遇見了中斷那么延時時間還要另
作者: lovexulu    時間: 2020-10-13 19:17
laopihappy123 發表于 2020-10-13 15:27
那么用硬件定時器嗎...感覺硬件中斷有點麻煩啊

不,我說的是延時程序,利用for。while空循環之類的定時,少用,可以用內部定時器,配置好之后,使用時填裝裝載值,溢出內部中斷。這種方式單片機可以在計時期間去做其他的事情,長計時可以中斷中自動填裝啟動計時,設置全局變量累計中斷次數,以取得較長時間的定時效果,如果要求精度非常高,請用外部硬件定時器外部中斷。如果只是為了定時,沒有其他的任務處理,那么單片機本身也可以做高精度定時器,請使用外部晶振,另外晶振負載電容一定要匹配。晶振PBC走線外包地過孔。線盡量短。定時精度還是有保證的。
作者: laopihappy123    時間: 2020-10-13 20:25
lovexulu 發表于 2020-10-13 19:17
不,我說的是延時程序,利用for。while空循環之類的定時,少用,可以用內部定時器,配置好之后,使用時填 ...

懂了,謝謝您

作者: kuangleilei    時間: 2020-10-13 23:38
你的方法可行,確實是有用這個方法的,那個τ 寶STM32戰艦等系列賣家給的延遲函數里就有
作者: amandv    時間: 2020-10-15 22:22
看要求,一般程序延時受程序影響,要求準的還是用中斷靠譜




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