標(biāo)題: 單片機常見中斷及解決方法 [打印本頁]

作者: huangp2001    時間: 2018-10-18 14:44
標(biāo)題: 單片機常見中斷及解決方法
本文通過問答方式展現(xiàn),讀者可以非常明確的了解中斷的意義,內(nèi)容包括部分源程序。

1、單片機延時程序的延時時間怎么算的?
答:如果用循環(huán)語句實現(xiàn)的循環(huán),沒法計算,但是可以通過軟件仿真看到具體時間,但是一般精精確延時是沒法用循環(huán)語句實現(xiàn)的。
如果想精確延時,一般需要用到定時器,延時時間與晶振有關(guān)系,單片機系統(tǒng)一般常選用11.059 2 MHz、12 MHz或6 MHz晶振。第一種更容易產(chǎn)生各種標(biāo)準(zhǔn)的波特率,后兩種的一個機器周期分別為1 μs和2 μs,便于精確延時。本程序中假設(shè)使用頻率為12 MHz的晶振。最長的延時時間可達(dá)216=65 536 μs。若定時器工作在方式2,則可實現(xiàn)極短時間的精確延時;如使用其他定時方式,則要考慮重裝定時初值的時間(重裝定時器初值占用2個機器周期)。

2、求個單片機89S51 12M晶振 用定時器延時10分鐘,控制1個燈就可以
答:可以設(shè)50ms中斷一次,定時初值,TH0=0x3c、TL0=0xb0。中斷20次為1S,10分鐘的話,需中斷12000次。計12000次后,給一IO口一個低電平(如功率不夠,可再加擴展),就可控制燈了。

而且還要看你用什么語言計算了,匯編延時準(zhǔn)確,知道單片機工作周期和循環(huán)次數(shù)即可算出,但不具有可移植性,在不同種類單片機中,匯編不通用。用c的話,由于各種軟件執(zhí)行效率不一樣,不會太準(zhǔn),通常用定時器做延時或做一個不準(zhǔn)確的延時,延時短的話,在c中使用匯編的nop做延時


3、51單片機C語言for循環(huán)延時程序時間計算 ,設(shè)晶振12MHz,即一個機器周期是1us。
for(i=0,i<100;i++)
for(j=0,j<100;j++)
我覺得時間是100*100*1us=10ms,怎么會是100ms
答:
不可能的,是不是你的編譯有錯的啊
我改的晶振12M,在KEIL 4.0 里面編譯的,為你得出的結(jié)果最大也就是40ms,這是軟件的原因,
不可能出現(xiàn)100ms那么大的差距,是你的軟件的原因。
不信你實際編寫一個秒鐘,利用原理計算編寫一個燒進(jìn)單片機和利用軟件測試的秒程序燒進(jìn)單片機,你會發(fā)現(xiàn)原理計算的程序是正確的



4 、51單片機c語言 _nop_()是一個空指令?短時間延時的?空幾個機器周期?
答:這個_nop_()等效與匯編里面的,NOP指令,也就是空一個機器周期,如果是傳統(tǒng)51單片機的話,等于空12個時鐘周期【即一個機器周期】

5、51單片機 延時500ms 用機器周期疊加怎么算?
答:DELAY:
MOV R7,#4
D2:MOV R6,#250
D1:MOV R5,#250
DJNZ R5,$
DJNZ R6,D1
DJNZ R7,D2
RET
假設(shè)晶振為12MHz
剛延時時間為:
250*250*4*2=500MS

6、51單片機C語言程序中延時函數(shù)delay的原理是什么?
現(xiàn)在找到兩個函數(shù)
第一:
void delay(void)  
{  unsigned int i,j;
   for(i=0;i<500;i++)
     { for(j=0;j<121;j++)
{;}   
     }   
}

第二:
void delay(unsigned int k)
{  unsigned int i,j;  
   for(i=0;i<k;i++)
      {  for(j=0;j<121;j++)  
               {;}
      }     
}
現(xiàn)有幾個疑問:
(1):延時函數(shù)的原理?
(2):兩個for循環(huán)的作用?
(3):i、j的取值有什么規(guī)律和依據(jù)?是不是和單片機接的晶振頻率有關(guān)?所能延時的最小單位時間是怎么計算的?
延時時間怎么計算。〖偃缬玫氖茿T89C51RC+11.0592M的晶振呢?
答:
1:原理:僅僅執(zhí)行一些,沒有實質(zhì)性影響的所謂“無意義指令”,比如做比大小啊,做某個int的自加運算啊之類的
2:兩重for的作用:簡單的說,就像高中數(shù)學(xué)中的“乘法原理”一樣,這樣可以很輕易的迅速增加上述“無意義指令”的數(shù)目
3:關(guān)于取值大小:這個如果是在C下變成,這個值不僅僅與晶振、單片機本身運算速度有關(guān),而且還與C的編譯器有關(guān),所以說,這個值雖說是可以精確計算的,但大多數(shù)情況下,程序員用的都是“經(jīng)驗值”——當(dāng)然,如果用匯編編程,情況就不一樣了,因為每一條指令所使用的機器周期是一定的,你當(dāng)然可以根據(jù)所有指令使用的總時間,精確的算出具體延時的總時間

綜合你的的問題,我給你一點建議,就是剛學(xué)單片機的時候,還是一定要老老實實的從匯編編程學(xué)起——這樣,在你以后接觸到C之后,你才能明白,這中間實際上經(jīng)歷了一個什么樣的過程,只有這樣你才能真正理解單片機。當(dāng)然,等最終你完全拿下一種單片機之后,盡量使用C編程,無疑是歷史所肯定的。

7、51單片機,晶振為6M,求一個10ms的延時程序
答:延時有很多種方法,有一種是讓單片機去做無聊的循環(huán),還有一種是用定時器。
第一種的算法是:
晶振的周期T1=1/f; 這里f=6MHz 所以T1=1/6 us;(微秒)
單片機花12個T1去執(zhí)行一個指令,
所以一個機器周期等于12個晶振周期,
T2=12*T1=2us
10ms=1000 0us
所以你要得到10ms的延時就要想辦法讓機器去做5000條“無聊的指令”
所以
DEL: MOV R5,#05H
F1:   MOV R6,#05H
F2:   MOV R7,#32H
F3: DJNZ R7,F3
    DJNZ R6,F2
    DJNZ R5,F1
RET
這種方法是用于對時間要求不高的地方,我說的是其思想,程序中可能有錯的地方
用定時器的方法我不太會就不誤人了 (補充一下就是這個是用匯編寫的,你在主程序中用ACALL DEL調(diào)用就延時了。


8、今天我用單片機做“眨眼的LED”實驗時,程序運行,每次只令燈亮或滅都沒問題,但是一開延時不能出現(xiàn)期盼的燈亮燈滅的現(xiàn)象,這是怎么回事?  
實驗的硬件條件是:STC89C52,編譯環(huán)境:keil 3。

下面是我寫的程序,請教高手。!


#include <reg51.h>   // 文件包含處理
#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,根據(jù)機器周期的計算,我們
     {;}                        //可算得本次循環(huán)延時約1MS
}
}
void main(void)
{
while(1)
    {
    P1_0 = 0;      //點亮LED燈
    Delay(1000);   //應(yīng)單片執(zhí)行程序的時間很快,所以必須延時,要不看不到實驗現(xiàn)象
    P1_0 = 1;      //熄滅LED燈
    }

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

答:應(yīng)該這樣寫
   while(1)
    {
    P1_0 = 0;      //點亮LED燈
    Delay(1000);   //應(yīng)單片執(zhí)行程序的時間很快,所以必須延時,要不看不到實驗現(xiàn)象
    P1_0 = 1;      //熄滅LED燈
    Delay(1000);
補充問題回復(fù):問題恰恰就錯在這了,循環(huán)完一遍之后燈由滅到亮根本沒有時間延時,即第一次循環(huán)中燈還沒來的機滅呢,就進(jìn)入到第二輪循環(huán)中的亮了,所以原因就在這,這錯誤太低級了,以后引以為鑒吧

9、單片機延時函數(shù)的問題
void delay(uchar i)
{
uchar j;
while(i--)
{
  for(j=125;j>0;j--)
  ;
}
}
這個函數(shù)中的i,j的大小有**嗎?

答:這個函數(shù)中j的大小和你定義的數(shù)據(jù)類型有關(guān),因為你定義的為無符號字符型,為單字節(jié)數(shù)據(jù),所以最大為255。.
如果你需要增大,可以改變j的數(shù)據(jù)類型定義,如unsigned int (2字節(jié))可以到65535;無符號長整形unsigned long(4字節(jié)) 可以到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執(zhí)行一步
你使用的是軟件延時
那么包括程序的提取,執(zhí)行等都要花費時間
比如,你提取這個函數(shù)可能花去一步,那現(xiàn)在就使用了0.125us啦
接著你執(zhí)行這個函數(shù),在單片機內(nèi)部,運算是通過寄存器的移來移去實現(xiàn)的
這都需要時間,可能你看到的就一句counter--這個指令,可能會花費好幾個時鐘周期來實現(xiàn)
舉個例子:
c=a+b,只有一句,但實際上花費的時間并不短
mov a,#data1;//數(shù)據(jù)data1放入a寄存器
mov b,#data2;//數(shù)據(jù)data2放入b寄存器
add a,b;//寄存器a的值與b相加,結(jié)果放入a
mov c,a;//將a的值放入c
這樣才是單片機內(nèi)部真正執(zhí)行的指令,這需要花費至少4個時鐘周期,而不是1個
至于晶體管級的我就不解釋了,你得好好學(xué)習(xí)匯編才能理解單片機的運作。
至于這個函數(shù)為什么能延時1ms,這個是靠經(jīng)驗來判斷的,最直接的方法就是用示波器看,以上均為推論。

作者: 362618281    時間: 2019-11-22 10:33
示波器真的是個好東西




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