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

QQ登錄

只需一步,快速開(kāi)始

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

這里想問(wèn)各位大佬一個(gè)51單片機(jī)的問(wèn)題 delay函數(shù)延時(shí)不能達(dá)到預(yù)期的一秒,反而非常快

  [復(fù)制鏈接]
ID:1079470 發(fā)表于 2023-5-23 22:34 | 顯示全部樓層 |閱讀模式
其實(shí)代碼是在視頻上抄的,但是delay函數(shù)延時(shí)不能達(dá)到預(yù)期的一秒,反而非常快,求解答!

代碼如下

void UART_INIT() {

PCON |= 0x80; //波特率不倍速
SCON = 0x40; //8位數(shù)據(jù),可變波特率
TMOD &= 0x0F; //設(shè)置定時(shí)器模式
TMOD |= 0x20; //設(shè)置定時(shí)器模式
TL1 = 0xF3; //設(shè)置定時(shí)初始值
TH1 = 0xF3; //設(shè)置定時(shí)重載值
ET1 = 0; //禁止定時(shí)器中斷
TR1 = 1; //定時(shí)器1開(kāi)始計(jì)時(shí)
TR0 = 1;

}

void UART_SendByte(unsigned int Byte) {
SBUF = Byte;
while(TI == 0);
TI = 0;
}

unsigned int sec = 0;

void main() {
UART_INIT();

while(1) {
UART_SendByte(sec);
sec++;
P2_0 = ~P2_0;
Delay(1000);
}
}
回復(fù)

使用道具 舉報(bào)

ID:1079470 發(fā)表于 2023-5-23 22:35 | 顯示全部樓層
delay函數(shù)放在別的代碼里就沒(méi)有問(wèn)題,這里如果把TMOD換成定時(shí)器0,就會(huì)變得非常慢,總之不管怎么樣都不會(huì)按照1秒的預(yù)期去執(zhí)行
回復(fù)

使用道具 舉報(bào)

ID:744809 發(fā)表于 2023-5-24 09:00 | 顯示全部樓層
delay函數(shù)都沒(méi)貼出來(lái)
回復(fù)

使用道具 舉報(bào)

ID:526543 發(fā)表于 2023-5-24 12:32 | 顯示全部樓層
void Delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 120; j++) {
            // 空循環(huán)進(jìn)行延時(shí)
        }
    }
}
回復(fù)

使用道具 舉報(bào)

ID:1079470 發(fā)表于 2023-5-24 21:04 | 顯示全部樓層
123156fsadf 發(fā)表于 2023-5-24 09:00
delay函數(shù)都沒(méi)貼出來(lái)

void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);
}
回復(fù)

使用道具 舉報(bào)

ID:1031129 發(fā)表于 2023-5-24 21:12 | 顯示全部樓層
delay函數(shù)要貼出來(lái)
回復(fù)

使用道具 舉報(bào)

ID:1079470 發(fā)表于 2023-5-24 22:00 | 顯示全部樓層
2763537317 發(fā)表于 2023-5-24 21:12
delay函數(shù)要貼出來(lái)

貼啦,在您樓上
回復(fù)

使用道具 舉報(bào)

ID:744809 發(fā)表于 2023-5-24 22:41 | 顯示全部樓層
2763537317 發(fā)表于 2023-5-24 21:12
delay函數(shù)要貼出來(lái)

你這個(gè)delay函數(shù)有問(wèn)題,unsigned int 最大只有65535,你delay(1000),xms = 1000*1000,導(dǎo)致溢出了,你用4樓提供的delay試試
回復(fù)

使用道具 舉報(bào)

ID:155507 發(fā)表于 2023-5-24 22:43 | 顯示全部樓層
dhj646315174 發(fā)表于 2023-5-24 21:04
void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);

你是個(gè)變量是unsigned int, 他只能從 0~65535
Delay(1000);
是 1000 * 1000 = 1000000 超過(guò)了65535 當(dāng)然會(huì)快
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2023-5-25 06:26 | 顯示全部樓層
dhj646315174 發(fā)表于 2023-5-24 21:04
void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);

相同的代碼在不同的單片機(jī)運(yùn)行結(jié)果未必相同。標(biāo)準(zhǔn)51系列12T單片機(jī),12MHz晶振條件下運(yùn)行這個(gè)延時(shí)函數(shù)t大致延時(shí)時(shí)間長(zhǎng)度 T=t*9+16us
void delay(unsigned int t)
{      
        while(t--);
}
如果是51增強(qiáng)型1T單片機(jī)運(yùn)行上述這個(gè)延時(shí)函數(shù)大致延時(shí)時(shí)間長(zhǎng)度是上述的1/10?梢詤⒖枷旅娉绦
void Delay_ms(unsigned int t)//1T@12MHz
{
        unsigned int i,j;
        for(i=t;i>0;i--)
                for(j=1200;j>0;j--);
}

何況你xms = xms * 1000;數(shù)據(jù)溢出,while(xms--);中xms實(shí)際只得到16960,根本得不到1秒延時(shí)。
回復(fù)

使用道具 舉報(bào)

ID:879348 發(fā)表于 2023-5-25 10:47 | 顯示全部樓層
定時(shí)可以開(kāi)一個(gè)定時(shí)器,就非常精確了
回復(fù)

使用道具 舉報(bào)

ID:647261 發(fā)表于 2023-5-25 16:22 | 顯示全部樓層
要精確的1秒,除了樓上各位說(shuō)的
還要計(jì)算一下這個(gè)循環(huán)需要的指令周期
不過(guò)要計(jì)算可能不太好算,最好示波器量一下
回復(fù)

使用道具 舉報(bào)

ID:330059 發(fā)表于 2023-5-25 19:46 | 顯示全部樓層
參數(shù)xms是unsigned int類型,范圍是0-65535,Delay(1000)的話函數(shù)內(nèi)部參數(shù)的計(jì)算結(jié)果已經(jīng)大于最大值了,所以會(huì)出現(xiàn)問(wèn)題,可以修改成為unsigned long
回復(fù)

使用道具 舉報(bào)

ID:1079470 發(fā)表于 2023-5-25 21:08 | 顯示全部樓層
感謝樓上各位大佬的講解,這里就不一一回復(fù)了,十分感謝!
回復(fù)

使用道具 舉報(bào)

ID:73833 發(fā)表于 2023-5-27 14:34 | 顯示全部樓層
    使用for循環(huán)配合  ++,--,之類的語(yǔ)句,是很難得到精確的延時(shí)的。
     這里提供一個(gè)方法或許有用:
           開(kāi)一個(gè)可以自動(dòng)重裝的定時(shí)器,設(shè)好定時(shí)時(shí)間,比如10毫秒,再定義  一個(gè)全局變量TIME,僅 把"TIME++;"放在那個(gè)定時(shí)器的中斷函數(shù)里。這就準(zhǔn)備好了。
     在工程的任何地方(函數(shù)里),要延時(shí)都很方便,比如要延時(shí)1秒,只要 TIME=0;while(TIME<100);
這就精確的延時(shí) 了 1秒。
   像STC15W系列單片機(jī)有模式3的定時(shí)器,使用起來(lái)會(huì)更精確,更方便。
    了1秒。  
回復(fù)

使用道具 舉報(bào)

ID:73833 發(fā)表于 2023-5-27 14:45 | 顯示全部樓層
使用for循環(huán)和++,--之類的語(yǔ)句基本很難得到精確的定時(shí)。這里提供一個(gè)方法或許有用。
比如 要定時(shí)一秒:
  開(kāi)一個(gè)能自動(dòng)重裝的定時(shí)器,設(shè)定定時(shí)時(shí)間10毫秒,再定義一個(gè)全局變量TIME,僅把TIME++;放在那個(gè)定時(shí)器的中斷函數(shù)里,基本就OK。
  在任何函數(shù)里可以:TIME=0;While(TIME<100);這就得到1秒的精切延時(shí)。
像STC15W單片機(jī)有模式3的定時(shí)器,用起來(lái)更方便,更精確。
回復(fù)

使用道具 舉報(bào)

ID:712097 發(fā)表于 2023-5-27 15:20 | 顯示全部樓層
用STC-ISP軟件的“軟件延時(shí)計(jì)算器”功能
選擇對(duì)應(yīng)的指令集,以及延時(shí)時(shí)長(zhǎng),就可以了。
以下是STC-Y5指令集(適合STC15系列大部分芯片)12MHz下延時(shí)1000ms(1秒)的函數(shù)

void Delay1000ms()                //@12.000MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 46;
        j = 153;
        k = 245;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
回復(fù)

使用道具 舉報(bào)

ID:1090832 發(fā)表于 2023-8-6 20:30 | 顯示全部樓層
void Delay(unsigned char xms)
{
     unsigned char i,j;
     while(xms--)
     {
           i=2;
           j=199;
          do
          {
               while(--j);
          }while(--i);
     }
}
回復(fù)

使用道具 舉報(bào)

ID:1090832 發(fā)表于 2023-8-6 20:32 | 顯示全部樓層
void Delay(unsigned char xms)
{
     unsigned char i,j;
     while(xms--)
     {
           i=2;
           j=199;
          do
          {
               while(--j);
          }while(--i);
     }
}
那這個(gè)呢,有啥問(wèn)題
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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