コードは LED キューブ用で、新しい機能を追加したいと考えています。誰かが PORTB0 に接続されているプッシュボタンをクリックすると、現在のライト効果が変更されます。
私は何かを試してみますが、うまくいきません。
プログラムは ATmega16 用で、コードは Atmer Studio 6 で書かれています。
B0 に接続された回路はどのように見えますか?
スイッチの片側が B0 になり、もう一方がグランドになったと仮定すると、方向とプルアップの値は適切ですが、if ステートメントは、ボタンが押されたときに PINB のビット 0 が 1 から 0 になるのを探す必要があります。プルアップをオンにすると、ボタンが押されていないときにビットが 1 になり、押されているときにビットが 0 になります。
コードでは、入力を「エッジ」として扱っていますが、実際には「レベル」です。つまり、ボタンを押すと、CPU の観点から入力信号が長時間変化するということです。トランジションの効果を変更したい
ここには、スイッチのデバウンスという別の問題があります。スイッチを押しても、すぐにオフからオンになりません。トランジション中にノイズが発生し、コードに対して何度もボタンを押したように見えます。
デバウンスは、ハードウェアまたはソフトウェアで実行できます。ソフトウェアでは、delay_ms の内部ループで次のようなことを行います。
static unsigned int debounce;
static const unsigned int presscount = 500;
if ((PINB&1)==0) { // switch is pressed
if (debounce < presscount ) {
++debounce;
}
}
else {
if (debounce > 0) {
--debounce;
}
}
if (debounce == presscount ) {
// switch has been pressed long enough
debounce = 0; // reset
i = (i+1)%4;
return;
}
これにより、最大で 500 回のループ時間ごとに効果が増加します。ボタンを押し続けると効果が変化し続けます。スイッチがしばらくオフになるまで効果が再び増加しないようにコードを変更して、押したままの時間に関係なく各プレスが 1 つの増加のみを行うようにすることをお勧めします。上記のコードでは、'presscount' 定数をいじって、その動作を確認できます。
それが役立つことを願っています。
void delay_ms(uint16_t x)
{
uint8_t y, z;
for ( ; x ; x--){
for ( y = 0 ; y < 90 ; y++)
{
for ( z = 0 ; z < 6 ; z++)
{
if(PINB)
{
++i%=4;
return;
}
asm volatile ("nop");
}
}
}