新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機延時問題20問

        單片機延時問題20問

        作者: 時間:2013-01-30 來源:網絡 收藏

        #define uchar unsigned char //宏定義,方便以后程序的書寫

        #define uint unsigned int

        sbit P1_0 = P1 ^ 0; //位變量定義

        void Delay(uint t)

        {

        uchar i;

        while(--t)

        {

        for(i = 0; i 125; i++) //延時1MS,在這里我們用的晶振是是12M,根據機器周期的計算,我們

        {;} //可算得本次循環延時約1MS

        }

        }

        void main(void)

        {

        while(1)

        {

        P1_0 = 0; //點亮LED燈

        Delay(1000); //應單片執行程序的時間很快,所以必須延時,要不看不到實驗現象

        P1_0 = 1; //熄滅LED燈

        }

        補充提問:我是讓P1.0先低然后延時之后再高,即燈先亮再滅,然后開始循環的

        答:應該這樣寫

        while(1)

        {

        P1_0 = 0; //點亮LED燈

        Delay(1000); //應單片執行程序的時間很快,所以必須延時,要不看不到實驗現象

        P1_0 = 1; //熄滅LED燈

        Delay(1000);

        補充問題回復:問題恰恰就錯在這了,循環完一遍之后燈由滅到亮根本沒有時間延時,即第一次循環中燈還沒來的機滅呢,就進入到第二輪循環中的亮了,所以原因就在這,這錯誤太低級了,以后引以為鑒吧

        9、函數的問題

        void delay(uchar i)

        {

        uchar j;

        while(i--)

        {

        for(j=125;j>0;j--)

        ;

        }

        }

        這個函數中的i,j的大小有**嗎?

        答:這個函數中j的大小和你定義的數據類型有關,因為你定義的為無符號字符型,為單字節數據,所以最大為255。.

        如果你需要增大,可以改變j的數據類型定義,如unsigned int (2字節)可以到65535;無符號長整形unsigned long(4字節) 可以到4294967295。 而上面所所256是-1,而你定義的是無符號字符型。

        10、請教一個AVR的問題

        外部晶振用的是8MHz,延時1微秒的程序如下:

        void delay_us(unsigned int delay_counter)//延時1us

        {

        do

        {

        delay_counter--;

        }

        while(delay_counter>1);

        }

        請問,為什么能延時1微秒啊?

        答:8MHZ表示單片機的運行周期為1/8us,也就是0.125us執行一步

        你使用的是軟件延時

        那么包括程序的提取,執行等都要花費時間

        比如,你提取這個函數可能花去一步,那現在就使用了0.125us啦

        接著你執行這個函數,在單片機內部,運算是通過寄存器的移來移去實現的

        這都需要時間,可能你看到的就一句counter--這個指令,可能會花費好幾個時鐘周期來實現

        舉個例子:

        c=a+b,只有一句,但實際上花費的時間并不短

        mov a,#data1;//數據data1放入a寄存器

        mov b,#data2;//數據data2放入b寄存器

        add a,b;//寄存器a的值與b相加,結果放入a

        mov c,a;//將a的值放入c

        這樣才是單片機內部真正執行的指令,這需要花費至少4個時鐘周期,而不是1個

        至于晶體管級的我就不解釋了,你得好好學習匯編才能理解單片機的運作。

        至于這個函數為什么能延時1ms,這個是靠經驗來判斷的,最直接的方法就是用示波器看,以上均為推論。

        11、PIC單片機的延時問題 晶振4Mhz:

        void delay()

        {

        unsigned int d=1000;

        while(--d){;}

        }

        此函數在4M晶體下產生10003us的延時,也就是10MS。

        問題:我剛算了一下他應該執行了999條指令,1條單周期的指令也才1US,那就是999us,為什么會有10ms的延時?

        1:for(x=100;--x;){;} : 2: for(x=0;x100;x++){;} 2句話相同

        第一句:X的值范圍是不是 1~99?為什么?

        第二句:X的范圍是不是0~99?為什么?這么算的。我知道符號在前在后的區別。2句話應該是不一樣的才對啊!

        答:

        問題1:“我剛算了一下他應該執行了999條指令”因為你算錯了。延時時間是由產生的匯編代碼所決定的,C語言語句只是個假象,千萬不要以為C語言一行就是一條指令!此處由于涉及到雙字節減法,因此會有額外的判斷,編譯結果每次循環耗費幾十個周期毫不奇怪。

        問題2:前一句x從100開始遞減,遞減至1時退出循環。后一句x從0開始遞增,遞增到100時退出循環。所謂“2句話”相同僅僅是指這兩個循環體的循環次數相同。實際上兩個循環的執行過程是完全不同的,所消耗時間也有可能不同。

        12、stc單片機的延時問題 ,STC10F08XE單片機,晶振22.1184M

        void delay(unsigned long uldata)

        {

        unsigned int j = 0;

        unsigned int g = 0;

        for (j=0;j5;j++)

        {

        for (g=0;g

        {

        _nop_();

        _nop_();

        _nop_();

        }

        }

        }

        當uldata=1時延時多少秒?

        請給出具體算法…………

        答:用keil轉換成匯編語句,然后對照指令表計算就行了

        13、我想用單片機連接不斷地向電腦發數,如下:

        while (1)

        {

        send_char('9');

        delay(n);

        }

        如每發送一個數,應延時多少微妙好呢?即一般最短能延時多少微米呢?如延時太長的話,那發送很多數據不就用很長時間嗎?

        答:不做太多的串口處理分析,只順著你的問題和你的方法說說:

        先考慮下串口的速率 假設9600,那么發送一個字符要多久?

        (9600bit/S) / 10bit(一個字符1+8+1) = 960字符/秒 約 1ms/byte

        也就是說你如果在1ms內發送超過一個字符就沒意義了,硬件速度達不到。

        while(1)

        {

        send_char('9');

        delay(n);

        }

        這個循環是執行周期也就十幾微秒+delay()的延遲,所以任何小于1040微秒的延遲對串口硬件來說沒意義,上一個還沒處理完,下一個就來了根本執行不了嘛。

        如果你send_char()里面有while(!TI);TI = 0;這樣的語句或有串口中斷TI的處理的話,那么實際上你的delay()已經在發送函數里了,while(!TI);這部就是延遲等待嗎?那根本不需要主函數去延遲了,直接發就行了。

        51單片機相關文章:51單片機教程


        c語言相關文章:c語言教程


        單片機相關文章:單片機教程


        單片機相關文章:單片機視頻教程


        單片機相關文章:單片機工作原理


        晶振相關文章:晶振原理


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 萍乡市| 永昌县| 水富县| 红桥区| 镇平县| 广饶县| 罗山县| 九寨沟县| 秦安县| 伊金霍洛旗| 连南| 灯塔市| 武宁县| 新干县| 涟水县| 芦溪县| 乌拉特前旗| 安福县| 阿荣旗| 工布江达县| 策勒县| 汝城县| 通榆县| 伊吾县| 龙岩市| 晋城| 利川市| 鄂托克前旗| 行唐县| 惠东县| 商南县| 阿荣旗| 铜鼓县| 延长县| 西乌珠穆沁旗| 开平市| 陆丰市| 安多县| 天峻县| 依安县| 石楼县|