gpt4 book ai didi

c - Atmel 微处理器和旋转编码器控制 7 段显示器的速度

转载 作者:行者123 更新时间:2023-11-30 15:26:06 24 4
gpt4 key购买 nike

我正在尝试使用 Atmel (ATmega328P Xplained mini) 微处理器使用旋转编码器来控制从 0-9 计数的 7 段显示器的速度。我的问题是,每当我运行程序时,显示屏计数的速度越来越快,直到您只能看到“8”,有时我似乎可以通过逆时针旋转旋转编码器来降低速度,有时根本没有效果。由于我在编程方面没有那么丰富的经验,尤其是在这方面,我希望有人有能力并且愿意提供帮助。

这是我的代码:

#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;
}
}
}

最佳答案

首先尝试更改 GetInput 函数以返回更有用的值。请注意,PINC 的位 0 和位 1 已组合形成您正在重建的整数。

int GetInput (void)
{
// array to convert grey scale bit patterns to direction indicators.
// Rows indexed by lastValue, columns indexed by thisValue, and the
// content is -1 for CCW, +1 for CW, 0 for no motion. Note that 0 is
// also used for an invalid transition (2 bits changed at once), but a
// different value could be used for fault detection.
static const int tableGreyToDirection[4][4] =
{
0 , -1, 1 , 0 , // lastValue==0
1 , 0 , 0 , -1, // lastValue==1
-1, 0 , 0 , 1 , // lastValue==2
0 , 1 , -1, 0 // lastValue==3
};

static uint8_t lastValue = 0; // A valid default starting value
uint8_t thisValue = (PINC & 0b00000011); // Use the bottom two bits as a value from 0..3
int result = tableGreyToDirection[lastValue][thisValue];
lastValue = thisValue;
return result;
}

然后您可以大大简化循环中的测试。

while (1)
{
// Check the direction of the encoder: -1 = CCW, +1 = CW, anything else = no motion.
input = GetInput();
if(0 < input)
{
// Motion is CW, so increment the delay (within reasonable bounds).
if(8900 > d) d += 100;
}
else if(0 > input)
{
// Motion is CCW, so decrement the delay (within reasonable bounds).
if(100 < d) d -= 100;
}

// Keep the rest as it is...
}

建议将 d 更改为 uint16_t 并稍微整理一下。进一步的技巧包括使用#define 为常量提供可读的名称。例如。在我的说明表中,您可以使用:

#define ENCODER_CW 1
#define ENCODER_CCW -1
#define ENCODER_NEITHER 0

...

static const int tableGreyToDirection[4][4] =
{
ENCODER_NEITHER, ENCODER_CCW, ENCODER_CW, ENCODER_NEITHER, // lastValue==0
...

我相信您可以自己填写。

关于c - Atmel 微处理器和旋转编码器控制 7 段显示器的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27505715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com