找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

一個(gè)關(guān)于C語言for循環(huán)做的延時(shí)問題

  [復(fù)制鏈接]
ID:284226 發(fā)表于 2022-10-1 11:47 | 顯示全部樓層 |閱讀模式
void delay_ms() //12M晶振,12T為1us
{
unsigned int  i;
    for(i=0; i<32767; i++);
}
上面用的芯片是89C52,仿真用keil51,發(fā)現(xiàn)i<32767軟件仿真時(shí)查看軟件正常的延時(shí)161ms,但是一旦設(shè)為i<32768,一下子就變成1.2s的延時(shí)了,燒錄代碼到芯片,查看LED也是變成1.2s延時(shí)。想請教各位大佬為什么會出現(xiàn)這個(gè)問題。
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2022-10-1 13:37 | 顯示全部樓層
unsigned int  i,i的最大值就是32767,你整個(gè)32768,就亂了。
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2022-10-1 17:16 | 顯示全部樓層
不要希望這種延時(shí)能一直準(zhǔn)確無異于異想天開受程序其它影響甚大否則的話就不需要中斷了
回復(fù)

使用道具 舉報(bào)

ID:41656 發(fā)表于 2022-10-1 17:42 | 顯示全部樓層
keil仿真要設(shè)置正確的時(shí)鐘
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2022-10-1 18:42 | 顯示全部樓層
進(jìn)調(diào)試模式看看運(yùn)行一次走多少步
回復(fù)

使用道具 舉報(bào)

ID:91150 發(fā)表于 2022-10-1 21:15 | 顯示全部樓層
coody_sz 發(fā)表于 2022-10-1 13:37
unsigned int  i,i的最大值就是32767,你整個(gè)32768,就亂了。

    ?
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2022-10-2 00:41 | 顯示全部樓層
這一類的問題,論壇里  問得很多,我也答過很多,你要有心 搜索一下 都能搜到。
delay 函數(shù)本來 就不準(zhǔn), 你用 int / unsigned int   就更不靠譜,
你想要 靠譜 一點(diǎn)的話,必須用 unsigned char
void delay()
{
unsigned char  i,j;
        for(i=0;i<200;i++)          //雙循環(huán)粗調(diào)整
        {
         for(j=0;j<150;j++);
         }
        for(i=0;i<50;i++);       //單循環(huán)微調(diào)整
}
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2022-10-2 03:52 | 顯示全部樓層

沙發(fā)說的沒錯(cuò),uint 的取值范圍是0到32767,你要設(shè)32768時(shí),變量值溢出了。因?yàn)橛肋h(yuǎn)到不了32768,所以你這個(gè)延時(shí)就亂了。你把變量類型改為u32 就可以了
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2022-10-2 06:58 | 顯示全部樓層
無論是否寫錯(cuò)希望這種延時(shí)的準(zhǔn)確是癡心妄想,否則要時(shí)鐘芯片何用。
回復(fù)

使用道具 舉報(bào)

ID:284226 發(fā)表于 2022-10-2 11:41 | 顯示全部樓層
感謝各位大佬指點(diǎn),但是unsigned int 不是16位的嗎?65536?
是的,我發(fā)現(xiàn)一旦改成32768,單步調(diào)試一看轉(zhuǎn)匯編代碼就不對了。比32767時(shí)匯編就多少很多步,多用了幾個(gè)R寄存器。
但是呢,我寫成i--居然就正常了。不太理解為什么會這樣。感謝大佬提供新的思路。
回復(fù)

使用道具 舉報(bào)

ID:121859 發(fā)表于 2022-10-2 13:42 | 顯示全部樓層
你看看反匯編代碼就知道了,32767時(shí),是按正常匯編語言代碼來編制的延時(shí)程序,如果是32768則不然,“無符號”在程序代碼處理方式上有很大不同的。
當(dāng)為32767時(shí),代碼如下:
C:0x0003    E4       CLR      A
C:0x0004    FF       MOV      R7,A
C:0x0005    FE       MOV      R6,A
C:0x0006    0F       INC      R7
C:0x0007    BF0001   CJNE     R7,#0x00,C:000B
C:0x000A    0E       INC      R6
C:0x000B    BE7FF8   CJNE     R6,#0x7F,C:0006
C:0x000E    BFFFF5   CJNE     R7,#0xFF,C:0006
C:0x0011    22       RET      
當(dāng)為32768時(shí)代碼如下:
C:0x0003    900000   MOV      DPTR,#0x0000
C:0x0006    AF82     MOV      R7,DP0L(0x82)
C:0x0008    AE83     MOV      R6,DP0H(0x83)
C:0x000A    E4       CLR      A
C:0x000B    FC       MOV      R4,A
C:0x000C    FD       MOV      R5,A
C:0x000D    FB       MOV      R3,A
C:0x000E    7A80     MOV      R2,#P0(0x80)
C:0x0010    F9       MOV      R1,A
C:0x0011    F8       MOV      R0,A
C:0x0012    D3       SETB     C
C:0x0013    12001C   LCALL    C?SLCMP(C:001C)
C:0x0016    4003     JC       C:001B
C:0x0018    A3       INC      DPTR
C:0x0019    80EB     SJMP     C:0006
C:0x001B    22       RET      
                 C?SLCMP:
C:0x001C    EB       MOV      A,R3
C:0x001D    9F       SUBB     A,R7
C:0x001E    F5F0     MOV      B(0xF0),A
C:0x0020    EA       MOV      A,R2
C:0x0021    9E       SUBB     A,R6
C:0x0022    42F0     ORL      B(0xF0),A
C:0x0024    E9       MOV      A,R1
C:0x0025    9D       SUBB     A,R5
C:0x0026    42F0     ORL      B(0xF0),A
C:0x0028    EC       MOV      A,R4
C:0x0029    6480     XRL      A,#P0(0x80)
C:0x002B    C8       XCH      A,R0
C:0x002C    6480     XRL      A,#P0(0x80)
C:0x002E    98       SUBB     A,R0
C:0x002F    45F0     ORL      A,B(0xF0)
C:0x0031    22       RET      
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2022-10-2 17:04 | 顯示全部樓層
這是單片機(jī)內(nèi)核指令體系太過于原始的問題,跟c語言有個(gè)毛關(guān)系???
回復(fù)

使用道具 舉報(bào)

ID:491577 發(fā)表于 2022-10-2 20:15 | 顯示全部樓層
延時(shí)函數(shù)不要自己寫,STC燒錄軟件有現(xiàn)成的,直接使用就好。多長時(shí)間都可以。比如:
89C52單片機(jī),12M主頻
1000ms延時(shí):
void Delay1000ms()                //@12.000MHz
{
        unsigned char i, j, k;

        _nop_();
        i = 8;
        j = 154;
        k = 122;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
2000ms延時(shí)
void Delay2000ms()                //@12.000MHz
{
        unsigned char i, j, k;

        _nop_();
        i = 16;
        j = 51;
        k = 249;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
回復(fù)

使用道具 舉報(bào)

ID:382454 發(fā)表于 2022-10-2 22:08 | 顯示全部樓層
延時(shí)用官方的程序計(jì)算。
回復(fù)

使用道具 舉報(bào)

ID:276663 發(fā)表于 2022-10-2 22:45 | 顯示全部樓層
編譯器對代碼的處理方式不同導(dǎo)致的。
回復(fù)

使用道具 舉報(bào)

ID:1046742 發(fā)表于 2022-10-5 22:51 | 顯示全部樓層
延時(shí)用官方的程序計(jì)算。
回復(fù)

使用道具 舉報(bào)

ID:284226 發(fā)表于 2022-10-6 15:47 | 顯示全部樓層
嗯,不管他了。知道有這么個(gè)問題就好了,感謝各位大佬指點(diǎn)
回復(fù)

使用道具 舉報(bào)

ID:1047187 發(fā)表于 2022-10-10 17:46 | 顯示全部樓層
51單片機(jī)做不了精準(zhǔn)延時(shí),用定時(shí)器也只是比for語句好一點(diǎn)
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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