Я пытаюсь получить поворотный датчик для управления скоростью 7-сегментного дисплея, отсчитываемого от 0-9, с помощью микропроцессора Atmel (ATmega328P Xplained mini). Моя проблема заключается в том, что всякий раз, когда я запускаю программу, дисплей просто подсчитывается все быстрее и быстрее, пока вы не увидите просто «8», иногда кажется, что я могу сохранить скорость, поворачивая поворотный энкодер CCW, а иногда и никакого эффекта вообще. Поскольку я не настолько разбираюсь в программировании, и особенно это не так, я надеюсь, что кто-то способен и хочет помочь.Atmel микропроцессор и скорость вращения поворотного энкодера 7-сегментного дисплея
Вот мой код:
#include <avr/io.h>
void Display (uint8_t x)
{
static uint8_t tabel[] =
{0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000010,0b11111000,0b10000000,0b10010000};
PORTD = tabel[x];
}
int GetInput (void)
{
uint8_t x = PINC&1;
uint8_t y = (PINC>>1)&1;
if (x == 0 && y == 0) {return 0; }
else if (x == 1 && y == 0) {return 1;}
else if (x == 0 && y == 1) {return 2;}
else {return 3;}
}
int main(void)
{
DDRD = 0xFF; // set PortD as an output
DDRC = 0x00; // set PortC as an input
PORTB = 0x03; // Activate Pull-up resistors
float d = 9000;
int tick = 0;
int i = 0;
int input, state = 0; // initial state
int oldInput = 0;
while (1)
{
input = GetInput();
if (oldInput == 0 && input == 1)
{
d = (d * 1.1);
//slower
}else if (oldInput == 0 && input == 2)
{
d = (d * 0.9);
//faster
}else if (oldInput == 1 && input == 0)
{
d = (d * 0.9);
//faster
}else if (oldInput == 1 && input == 3)
{
d = (d * 1.1);
//slower
}else if (oldInput == 2 && input == 0)
{
d = (d * 1.1);
//slower
}else if (oldInput == 2 && input == 3)
{
d = (d * 0.9);
//faster
}else if (oldInput == 3 && input == 1)
{
d = (d * 0.9);
//faster
}else if (oldInput == 3 && input == 2)
{
d = (d * 1.1);
//slower
}
oldInput = input;
switch (state)
{
case 0: //ini
Display(0);
state = 1;
break;
case 1: //count
if (i == 9)
{
i = 0;
Display(i);
}
else
{
i++;
Display(i);
}
state = 2;
break;
case 2: // delay
if (tick < d)
{
state = 2;
tick++;
}
else
{
state = 1;
tick = 0;
}
break;
case 3: //reset/destroy
break;
}
}
}
Микро будет проходить через цикл много раз перед первым таймером, а умножение на 0,9 каждый раз быстро запустит d до 0. Как только он достигнет 0, независимо от того, сколько раз вы умножаетесь на 1.1, оно будет оставаться на 0 и вы больше никогда не будете ждать в «случае 2:». –
Если вы можете объяснить, что означают битовые шаблоны для кодировщика и как вы хотите, чтобы они повлияли на время, я мог бы предложить альтернативу. –
Между каждым нажатием на поворотный кодер значение бита проходит через: 2-3-1-0 для CW и 1-3-2-0 для CCW, оно должно просто считаться, например. На 10% быстрее при повороте CW и на 10% медленнее при повороте CCW. Фактически я просто хотел, чтобы он менялся один раз между каждым щелчком (например, если значение идет от 0-1 или 1-0), но расширило код, когда это не сработало, а затем я потерялся. – Nicolai