该代码是为LED立方体,我想添加新的功能。当有人点击连接到PORTB0的按钮时,应该改变当前的灯光效果。
我试了试,但不起作用。
该程序是为ATmega16编写的,代码是用Atmer Studio6编写的
code
发布于 2012-08-17 11:19:18
连接到B0的电路是什么样子的?
假设开关的一端到B0,另一端到地,您的方向和上拉值是正确的,但您的if语句应该在按下按钮时查找PINB位0,使其从1变为0。在上拉打开的情况下,未按下按钮时位为1,按下按钮时位为0。
在您的代码中,您将输入视为一个“边沿”,但实际上它是一个“电平”。我的意思是,从CPU的角度来看,按下按钮会在很长一段时间内改变输入信号。您希望更改过渡上的效果
这里还有另一个问题,那就是开关去抖动。当开关被按下时,它不会直接从off转到on。在转换过程中会有一些噪音,看起来就像你的代码按下了很多按钮。
去弹跳可以在硬件或软件中完成。在软件中,我会在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‘常量来看看它是做什么的。
希望这能有所帮助。
发布于 2012-08-17 02:20:05
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");
}
}
}https://stackoverflow.com/questions/11992781
复制相似问题