是否可以将16位值与8位比较匹配进行比较ISR

时间:2015-06-10 12:46:36

标签: c avr isr attiny

我正在尝试制造一个比ATtiny85 8位定时器/计数器更高分辨率的伺服控制器。到目前为止,我已经设法在21'000μs的时间范围内在我的伺服(1μs/步)上获得大约2000个位置。我还设法以不同的速度顺序移动5个伺服,但现在我想将它们同步移动。

我最大的问题是我不知道应该如何实现它!我已经浏览了其他伺服代码,包括伺服8位库,并试图找到一种方法。似乎大多数示例使用比较匹配ISR来“同时”移动伺服器,我的问题是我有一个16位整数,我想比较。

有没有办法做一些魔术,所以我可以使用8位比较匹配ISR和我的16位整数?或者你们有没有人提出如何在不使用比较匹配ISR的情况下将我的伺服同步移动的其他建议?

我希望我的问题有意义!

由于我还没有任何代码可以显示(只有没有比较ISR的有缺陷的尝试没有意义)我发布链接到我的TinyServo代码,如果它有帮助。

编辑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:

这是我认为代码应该如何工作的说明: enter image description here

......但事实并非如此!

1 个答案:

答案 0 :(得分:1)

如果您在脉搏期间没有其他任何事情可做,您可以使用忙碌 循环而不是中断:

main()

这将为您提供4个时钟周期的分辨率,或0.5μs的分辨率 8 MHz时钟。

将脉冲发送到5个伺服系统最多需要10 ms。以来 你每隔21毫秒重复一次脉冲,这就留下了11毫秒 计算下一组位置,这应该是充足的。你可以 设定一个计时器,每隔21毫秒唤醒你,然后你的int main(void) { static uint16_t pos[] = {4000, 3000, 3800, 2600, 3400}; uint8_t i; /* Wake up every 21 ms. */ setup_timer(); sleep_enable(); for (;;) { /* Update the servos. */ for (i = 0; i < 5; i++) pulse(pos[i], i); /* Compute the next set of positions. */ ... /* Wait for timer interrupt. */ sleep_cpu(); } } 可以 看起来像:

<?php    
    $userinput = $_POST['Sample_name'];
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "ProcessTrackingSystem";

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_errno) {
        printf("Connect failed: %s\n", $conn->connect_error);
        exit();
    }
    $result = mysqli_query($conn, "SELECT * FROM ProcessTrackingSystem.ProcessDetails WHERE Sample_name = '$userinput'") or die(mysqli_error($conn));
    echo "<table class='table' border='1' >";
    echo "<tr><th>Sample Name</th><th>SO ID</th></tr>";
    while ($row = mysqli_fetch_assoc($result)) {
        echo "<tr>";
        echo "<td>{$row['Sample_name']}</td>";
        echo "<td>{$row['SO_ID']}</td>";
        echo "</tr>";
    }
    echo "</table>";
    mysqli_free_result($result);
    $conn->close();
    ?>