dovechan 发表于 2016-3-24 21:29:56

关于中断 按键的疑问?

想做这么一个程序,达到以下目的。

有红灯,绿灯各一个
按钮A ,B ,C各一个,

程序启动
1.灯不亮
2.按下C键,红灯闪烁,再按C键无动作
3.按下A键,红灯常亮,要一按下A键立即切换(用中断实现吗?)
4.按下B键,还原到步骤1循环。

可增加
按下C键后,按B键到步骤1.

研究了好久都没法实现,请各位大神指教!!

janeasy 发表于 2016-3-24 22:32:48

不用中断应该也能实现,但好像没有绿灯什么事~

dovechan 发表于 2016-3-24 23:32:34

janeasy 发表于 2016-3-24 22:32 static/image/common/back.gif
不用中断应该也能实现,但好像没有绿灯什么事~

哈哈哈 打漏了!!

想做这么一个程序,达到以下目的。

有红灯,绿灯各一个
按钮A ,B ,C各一个,

程序启动
1.灯不亮
2.按下C键,红灯闪烁,再按C键无动作
3.按下A键,红灯常亮,要一按下A键立即切换(用中断实现吗?)
4.再按下C键,红灯灭,绿灯亮。
5.按下B键,回到步骤1循环。



研究了好久都没法实现,请各位大神指教!!

janeasy 发表于 2016-3-25 11:22:17

//红灯6,绿7,按键ABC,依次8,9,10

bool isBtnPressed={0,0,0},isBtnCAC =0; //按C后按A标记
byte delayTimes=0;//闪烁计数
int FlashDelay=500; //闪烁间隔时间(ms)

void setup() {
for(byte i=6;i<11;i++){
    pinMode(i,INPUT);
    if (i<8) pinMode(i,OUTPUT);
}
}

void loop() {//B键后 数据清零
if (isBtnPressed) {
    for(byte i=0;i<3;i++){
      isBtnPressed=0;
      if (i>0)digitalWrite(i+5,LOW);
    }
    isBtnCAC =0;
} // C A C键 关红亮绿
else if (isBtnPressed && isBtnPressed && isBtnCAC){
    digitalWrite(7,HIGH);
    digitalWrite(6,LOW);
}
else if ((isBtnPressed && !delayTimes)|| isBtnPressed) {
    digitalWrite(6,!digitalRead(6) | isBtnPressed);//闪烁或常亮
    isBtnCAC=isBtnPressed && isBtnPressed;//按C后A,标志
    isBtnPressed=!(isBtnPressed && isBtnPressed);//按C后A,清除C标志                                                
}
// 读取按键
for(byte i=0; i<3;i++){
    if (digitalRead(i+8)){//读取按键
      delay(50);
      delayTimes = ++delayTimes % (FlashDelay /50);   //闪烁延时计次
      if (digitalRead(i+8)) isBtnPressed=1;
    }
}
delay(50);
delayTimes = ++delayTimes % (FlashDelay /50);//闪烁延时计次
}

dovechan 发表于 2016-3-31 11:35:40

本帖最后由 dovechan 于 2016-3-31 11:41 编辑

janeasy 发表于 2016-3-25 11:22 static/image/common/back.gif
//红灯6,绿7,按键ABC,依次8,9,10

bool isBtnPressed={0,0,0},isBtnCAC =0; //按C后按A标记


非常感激!!对我很有帮助!!
试了一下,能实现原本设想的功能。
但是步骤4,按下C键,红灯灭,绿灯亮,这一步也是要求立即切换可以实现吗?
因为根据您写的程序,我试了一下,步骤4按下C键,有时不能立刻切换,要再按几次。
设想是需要立刻切换的,帖子没写清楚,抱歉!
能麻烦您为我修改一下吗??

janeasy 发表于 2016-3-31 15:00:04

本帖最后由 janeasy 于 2016-4-1 18:19 编辑

dovechan 发表于 2016-3-31 11:35 static/image/common/back.gif
非常感激!!对我很有帮助!!
试了一下,能实现原本设想的功能。
但是步骤4,按下C键,红灯灭,绿灯 ...

测试了一下,逻辑上有个错误,正好在熟悉位运算就改了一下

byte delayTimes=0, BtnPressed=0; //闪烁计数 // 按键ABC对应 1-3 位,4位CA键标记,7、8位 led状态
int FlashDelay=500; //闪烁间隔时间(ms),50的整数倍

void setup() {
for(byte i=6;i<11;i++){
    pinMode(i,INPUT);
    if (i<8) pinMode(i,OUTPUT);
}
Serial.begin(9600);
}
void loop() {//B键后 数据清零
if (BtnPressed >> 1 & 1)BtnPressed=0;//B键清零
if (BtnPressed & 1 && BtnPressed >>2 &1){//A 和 C按键处理 // 下一行:清除led状态 | 绿灯 | 红灯 | CAC键标记
      BtnPressed = BtnPressed & 0x3f | (BtnPressed >> 3 & 1) << 7 | !(BtnPressed >> 3 & 1)<< 6 | 8;
      if (BtnPressed >>3) BtnPressed= BtnPressed & 0xfb;//按C后A,清除C标记
}else if ((!delayTimes && BtnPressed >>2 &1) || BtnPressed == 1)
      BtnPressed = BtnPressed & 0xbf | (!digitalRead(6) | BtnPressed & 1) << 6;//清除红灯状态 | 闪烁 | 常亮
digitalWrite(6,BtnPressed >> 6 & 1); 第六位状态
digitalWrite(7,BtnPressed >> 7 & 1); 第七位状态
// 读取按键
for(byte i=0; i<3;i++){
    if (digitalRead(i+8)){//读取按键
      delay(50);
      delayTimes = ++delayTimes % (FlashDelay /50);   //闪烁延时计次
      if (digitalRead(i+8)){
      BtnPressed = BtnPressed | (1<< i);
      // 按键状态调试输出
       break;
      }
    }
}
delay(50);
delayTimes = ++delayTimes % (FlashDelay /50);//闪烁延时计次
}

这部分可以用来输出按键状态,放在上面调试输出的位置,没啥问题可以不用
Serial.print("KeyStatus:");
for(byte j=0;j<4;j++)
   Serial.print(BtnPressed >> (3-j) & 1);
Serial.println();

dovechan 发表于 2016-4-1 20:50:27

janeasy 发表于 2016-3-31 15:00 static/image/common/back.gif
测试了一下,逻辑上有个错误,正好在熟悉位运算就改了一下

byte delayTimes=0, BtnPressed=0; //闪烁 ...

有错误信息提示,不能编译

Arduino:1.6.7 (Windows 10), 开发板:"Arduino/Genuino Uno"

sketch_apr01a:18: error: stray '\265' in program

   digitalWrite(6,BtnPressed >> 6 & 1); 第六位状态

   ^

sketch_apr01a:18: error: stray '\332' in program

sketch_apr01a:18: error: stray '\301' in program

sketch_apr01a:18: error: stray '\371' in program

sketch_apr01a:18: error: stray '\316' in program

sketch_apr01a:18: error: stray '\273' in program

sketch_apr01a:18: error: stray '\327' in program

sketch_apr01a:18: error: stray '\264' in program

sketch_apr01a:18: error: stray '\314' in program

sketch_apr01a:18: error: stray '\254' in program

sketch_apr01a:19: error: stray '\265' in program

   digitalWrite(7,BtnPressed >> 7 & 1); 第七位状态

   ^

sketch_apr01a:19: error: stray '\332' in program

sketch_apr01a:19: error: stray '\306' in program

sketch_apr01a:19: error: stray '\337' in program

sketch_apr01a:19: error: stray '\316' in program

sketch_apr01a:19: error: stray '\273' in program

sketch_apr01a:19: error: stray '\327' in program

sketch_apr01a:19: error: stray '\264' in program

sketch_apr01a:19: error: stray '\314' in program

sketch_apr01a:19: error: stray '\254' in program

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino: In function 'void loop()':

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino:14:31: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]

       BtnPressed = BtnPressed & 0x3f | (BtnPressed >> 3 & 1) << 7 | !(BtnPressed >> 3 & 1)<< 6 | 8;

                               ^

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino:17:70: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]

       BtnPressed = BtnPressed & 0xbf | (!digitalRead(6) | BtnPressed & 1) << 6;//清除红灯状态 | 闪烁 | 常亮

                                                                      ^

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino:17:31: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]

       BtnPressed = BtnPressed & 0xbf | (!digitalRead(6) | BtnPressed & 1) << 6;//清除红灯状态 | 闪烁 | 常亮

                               ^

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino:24:51: warning: operation on 'delayTimes' may be undefined [-Wsequence-point]

       delayTimes = ++delayTimes % (FlashDelay /50);   //闪烁延时计次

                                                   ^

C:\Users\dove\AppData\Local\Temp\arduino_6ad822af81492744739d797a46934c03\sketch_apr01a.ino:33:47: warning: operation on 'delayTimes' may be undefined [-Wsequence-point]

   delayTimes = ++delayTimes % (FlashDelay /50);//闪烁延时计次

                                             ^

exit status 1
stray '\265' in program

报告将会包含更多的信息
"在编译时,输出详细信息"
在 文件>首选项 中启用

janeasy 发表于 2016-4-1 21:01:08

复制后斜线没有了,在第六位和第七位(18,19行)几个黑字前加上//或删除汉字。
页: [1]
查看完整版本: 关于中断 按键的疑问?