這不是一個好主意,在C中使用計數器來實現PWM或任何時間關鍵。儘管C將您的代碼轉換爲特定的機器代碼,但您並不知道需要多少時間。 您的代碼不會不翻譯爲:
make port B high 400 times (PORTB |= (1<<7);)
make port B low 400 times (PORTB &= ~(1<<7);)
,而是像這樣(簡化,人類可讀):
load variable cnt1 to memA;
load 399 to memB
compare mem A to memB
put result to memC
if memC eq "somthing indicating <=" do PORTB |= (1<<7);
if memC something else do PORTB &= ~(1<<7);
load cnt1 to memD and increment;
write memD to cnt1;
load 800 to memE
load cnt1 to memF
compare memF to memE
put result to memG
if memG eq "somthing indicating <=" do memF = 0, write memF to cnt1;
if memG something else go to start;
如果你看看這個但從「C」點你需要做的至少:
1. comare cnt1-399
2. if ok - do/else
3. port high/port low
4. add one to cnt1
5. compare cnt1 and 800
那就要看你編譯器如何去它在優化所有負載和寫入(通常相當好)。 如果你真的瞭解你的編譯器,並且不使用太多的優化(通常很複雜),或者用匯編編寫代碼,你可以控制延遲是什麼。但是,那麼您將不得不使用類似於我對機器代碼解釋的邏輯(彙編器接近人類可讀的機器代碼)。
我認爲解決的辦法因爲你是計時器中斷。對於atmega128這個here有一個很好的教程。
而且你是什麼意思有:
我試圖生成25US佔空比20KHZ信號(50美元)。
你的意思是20kHz信號佔空比爲50%嗎?所以25us低,25 us高?
如果是這種情況,你可以用一個定時器中斷和一個(二進制)計數器來實現。 您可以在提供的鏈接中閱讀有關「8位計時器示例」的內容。
當我用Xmega解決這個問題時,我驚訝於爲了獲得穩定的計算頻率而採取了多少步驟。 (例如,請參閱http://craigbot.blogspot.it/2014/01/stepper-gnomebot.html)。大多數情況下,我只是憑經驗使用高頻單循環和循環內的循環對於較低頻率,將迭代器計數與示波器結果相匹配。它是線性的,所以做起來相當簡單。 – Dribbler
你看過你的程序集輸出,並檢查了編譯器__really__向你扔了多少條指令?或者,你可能想考慮基於定時器的中斷來控制時序。 – MikeD