该代码适用于 LED 立方体,我想添加新功能。当有人点击连接到 PORTB0 的按钮时,当前的灯光效果应该改变。
我尝试了一些东西,但它不起作用。
程序为ATmega16,代码用Atmer Studio 6编写
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");
}
}
}
连接到 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 个循环时间增加一次效果。如果您一直按住按钮,效果将继续变化。您可能需要修改代码,使其在开关关闭一段时间后才再次增加效果,这样无论按住多长时间,每次按下都只会增加一次。对于上面的代码,您可以使用“presscount”常量来查看它的作用。
希望有帮助。