【问题标题】:atmega16 single port checking in while() loop or if()atmega16 单端口检查 while() 循环或 if()
【发布时间】:2017-08-28 11:32:23
【问题描述】:

Atmega16 PORTC 用于按钮,并重命名为

#define LEFT_S       PINC&(1<<2)
#define RIGHT_S      PINC&(1<<3)
#define UP_S         PINC&(1<<4)
#define DOWN_S       PINC&(1<<5)
#define OK_S         PINC&(1<<6)

我试图把它放在像

这样的循环中
while (OK_S);

if (UP_S);

有什么考虑?

while (OK_S)if (UP_S) 在函数中不起作用。

但是通过函数将键值传递给变量,然后我可以检查它。
当我使用 ch = Key_pressed(); 函数时,while(ch==1) 工作正常。

int Key_pressed(void)
{   
   while(1) {
      if (LEFT_S)  { while (LEFT_S);  return 1; }             
      if (RIGHT_S) { while (RIGHT_S); return 2; }
      if (UP_S)    { while (UP_S);    return 3; }
      if (DOWN_S)  { while (DOWN_S);  return 4; }
      if (OK_S)    { while (OK_S);    return 5; }
   }
}

在Proteus中模拟时会显示上述错误

【问题讨论】:

  • 在我看来你应该得到几个good beginners books to read
  • 很不清楚你在问什么。什么是“不工作”?是什么行为?能举个例子吗?
  • while(..) 是你在那里旋转的循环,if(..) 是验证语句。您可以根据应用程序的需要决定需要执行的操作。
  • A minimal reproducible example 将有助于使这个问题变得更好。

标签: c microcontroller atmega avr-gcc


【解决方案1】:

Key_pressed(); 可能会在内部进行去抖动,您不必担心。

如果您检查引脚状态,您可能会收到数十或数百次假“按键”,因为金属触点会在很短的时间内弹起:

【讨论】:

    【解决方案2】:

    != 运算符的优先级高于 &(按位与)运算符的优先级是错误的 我被用作 而(OK_S != 1) 它的意思是

    while (PINC & ((1 << 6) != 1))
    

    C 编译器更喜欢类似的东西

    while ((PINC & (1 << 6)) != 1)
    

    但正确的做法是

    while ((PINC & (1 << 6)) != (1 << 6))
    

    所以我将宏定义更正为

    #define OK_S (PINC & (1 << 6))
    

    并且工作正常。

    【讨论】:

    • while ((PINC &amp; (1 &lt;&lt; 6)) != (1 &lt;&lt; 6)) 不好。如果将 OK_S 更改为不同的端口,则针对 (1 &lt;&lt; 6) 的测试将失败。测试它总是针对 0 或 false,隐式或显式。宏定义中的括号是必须的。总是。
    • 我现在不想更改端口,请说明如何针对 0 或 false 进行测试。在这种情况下
    • if (S_OK)if (!S_OK)if (S_OK==false)if (S_OK==0)。最后三个是一样的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 2017-04-03
    • 2015-12-15
    • 1970-01-01
    相关资源
    最近更新 更多