我試圖製作比ATtiny85 8位定時器/計數器分辨率更高的伺服控制器。到目前爲止,我已經在21'000μs的時間範圍內獲得了大約2000個伺服位置(1μs/步)。我也設法按順序移動5個舵機,速度不同,但現在我想將它們同步移動。是否有可能將16位值與8位比較匹配進行比較ISR
我最大的問題是,我不明白我應該怎麼做!我環顧了其他伺服代碼,包括伺服8位庫,並試圖找到一種方法。看起來,大多數例子使用比較匹配ISR來移動舵機「同時」,我的問題是我有一個16位整數,我想比較。
有沒有辦法做一些魔術,所以我可以使用8位比較匹配ISR與我的16位整數?或者是否有人對我如何在不使用比較匹配ISR的情況下同步移動我的舵機提出了一些其他建議?
我希望我的問題有道理!
因爲我還沒有任何代碼可以顯示(只有有缺陷的嘗試沒有比較匹配的ISR,沒有任何意義),我發佈鏈接到我的TinyServo代碼,如果有幫助。
EDIT 1:
這裏是我提到,沒有發佈第一時間代碼的一部分:
void servoMove(void)
{
uint16_t nextPulse = hPulse[0];
timerSetup(); //16-bit setup for counter
for (i = 0; i < sizeof(servo)/sizeof(servo[0]); i++)
{
if ((oTime > nextPulse) && (channel < sizeof(servo)/sizeof(servo[0]))) //check if HIGH pulse (pos) is done
{
PORTB &= ~(1 << servo[channel]);
if (i+1 < sizeof(hPulse)/sizeof(hPulse[0]))
{
nextPulse += hPulse[i+1];
}
channel++;
}
else
{
channel = 0;
oTime = 0; //resets 16-bit variable
tot_overflow = 0; //resets tot_overflow variable
TIFR |= (1 << TOV1); // clear counter1 overflow-flag
TCNT1 = 0; //resets Timer/Counter1
}
}
for (i = 0; i < sizeof(servo)/sizeof(servo[0]); i++)
{
if ((oTime > tPulse - nextPulse) && (channel < sizeof(servo)/sizeof(servo[0])) ) //check if LOW pulse (period) is done
{
PORTB |= (1 << servo[channel]);
nextPulse -= hPulse[i];
channel++;
}
}
}
void servoPosSet(volatile uint16_t pos[], uint8_t size)
{
for (i = 0; i < size; i++)
{
hPulse[i] = pos[i];
}
}
int main(void)
{
TCCR1 |= (1 << CS12); //set Timer/Counter1 prescaler to increment every 1 µs (PCK/8)
for (channel = 0; channel < size); channel++)
{
DDRB |= (1 << servo[channel]); //sets PB0-PB4 as output pins
}
channel = 0;
uint16_t pos[] = {2000, 1500, 1900, 1300, 1700};
uint8_t size = 5;
while(1)
{
servoPosSet(pos);
servoMove();
}
}
編輯2:
這是如何我的圖示認爲代碼應該工作:
...但它不!
在鏈接TinyServo所示的代碼沒有直接說明它是什麼你想不工作。你應該考慮展示你所嘗試過的東西,即使如你所說,它沒有任何意義。 – ryyker
您可以使用整數的較低8位來觸發ISR,在ISR中您可以發送多少次它發生增加另一個8位值。如果這個值匹配你的高8位,那麼你做了這個伎倆。 – Nidhoegger
@ryyker我現在發佈了代碼;-) – CrowStudio