查看: 265|回复: 13

小弟求助程序设计相关问题

[复制链接]

该用户从未签到

发表于 2020-8-7 16:31 | 显示全部楼层 |阅读模式
小弟求助,谢谢各位大哥,loop中的函数出了问题,假设现在进入到了第一个if,但是只执行了if里的前一半,就跳入了第二个if,并且将第二个if的程序完全执行了。我只想他一次执行两个if中的一个





#include<LiquidCrystal.h>

const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7; //LCD1602引脚定义
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const int SW = 10, CW = 9, ACW = 8; //旋转编码器引脚:按键、顺时针、逆时针
int PIN[2] ={CW,ACW};
bool oldState[2];

bool mode = 1;    //高频械式1,低频模式0; 500Hz~80KHz对应高频模式,1~500Hz为低频模式

float STEP = 1200;    //初始频率调节步长,可选值为:0.1、1、10、100、1000
float frq =40000;  //初始输出信号频率,可选范围 1Hz~80KHz
float temp;
byte TP = 0b01010101;


void setup() {
  Serial.begin(9600);
  initInterrupt();          //初始化中断设置
  DDRC = 0xFF;              //将A0~A7均设为输出模式
  pinMode(SW,INPUT_PULLUP);
  pinMode(PIN[0],INPUT_PULLUP);
  pinMode(PIN[1],INPUT_PULLUP);
  oldState[0]=digitalRead(PIN[0]);
  oldState[1]=digitalRead(PIN[1]);
  lcd.begin(16,2);
  lcd.print("Freq:");
  lcd.print(frq);
  lcd.setCursor(0,1);
  lcd.print("Step:");
  lcd.print(STEP);

}


void loop()
{
  if(isChanged(0))//判断为逆时针旋转时
  {
    frq=41200;
    temp = 31250/frq*(1+255*mode);
    ICR1 = int(temp);
    TCNT1=0;
    lcd.setCursor(5,0);
    lcd.print(frq);
    lcd.print("      ");
    delay(5000);
    frq=1000;
    temp = 31250/frq*(1+255*mode);
    ICR1 = int(temp);
    TCNT1=0;
    lcd.setCursor(5,0);
    lcd.print(frq);
    lcd.print("       ");
  }
  if(isChanged(1))//判断为顺时针旋转编码器
  {
    frq=38860;
    temp = 31250/frq*(1+255*mode);
    ICR1 = int(temp);
    TCNT1=0;
    lcd.setCursor(5,0);
    lcd.print(frq);
    lcd.print("       ");
    delay(5000);
    frq=3000;
    temp = 31250/frq*(1+255*mode);
    ICR1 = int(temp);
    TCNT1=0;
    lcd.setCursor(5,0);
    lcd.print(frq);
    lcd.print("       ");
  }
  //判断按键是否按下
  if(!digitalRead(SW)){
    delay(140);
    if(!digitalRead(SW)){
      STEP*=10;
      if(STEP>1000)
        STEP=0.1;
    }
    lcd.setCursor(5,1);
    lcd.print(STEP);
    lcd.print("      ");
  }
}
//判断iPin脚电平是否变化,是返回1,否则返回0
bool isChanged(int iPin){   
  bool newState = digitalRead(PIN[iPin]);
  if(newState!=oldState[iPin]){
    oldState[0]=newState;
    oldState[1]=newState;
    return 1;
  }
  else
    return 0;
}

void initInterrupt(){
  TCCR1A = 0;     //普通模式
  TCCR1B = 1<<WGM13 | 1<<WGM12 | 0<<CS12 | 0<<CS11 | 1<<CS10; //CTC模式:ICR1触发,初始分频:cpu主频16MHz
  ICR1 = int(8000000/frq);         //寄存器,计数器达到该值时产生中断信号
  TIMSK1 |= 1<<ICIE1;   //允许捕捉事件中断
}

//中断函数
ISR(TIMER1_CAPT_vect){
  TP = ~TP;
  PORTC = TP;
}

该用户从未签到

发表于 2020-8-7 19:43 | 显示全部楼层

回帖奖励 +1 金币

其他先不去管,你是凭借什么说第一个if只执行了一半?
  • TA的每日心情
    开心
    2020-9-30 06:28
  • 签到天数: 89 天

    [LV.6]常住居民II

    发表于 2020-8-8 14:53 | 显示全部楼层
    问题解决了吗?

    该用户从未签到

     楼主| 发表于 2020-8-8 15:22 | 显示全部楼层
    开在边缘 发表于 2020-8-7 19:43
    其他先不去管,你是凭借什么说第一个if只执行了一半?

    实验现象表明。。。。

    该用户从未签到

     楼主| 发表于 2020-8-8 15:23 | 显示全部楼层
    ifeue 发表于 2020-8-8 14:53
    问题解决了吗?

    还没呢……..

    该用户从未签到

     楼主| 发表于 2020-8-8 15:24 | 显示全部楼层
    开在边缘 发表于 2020-8-7 19:43
    其他先不去管,你是凭借什么说第一个if只执行了一半?

    我这个程序是控制超声波的频率的,可以知道发出的声波频率是多少,所以知道只执行了一半
  • TA的每日心情
    开心
    2020-9-30 06:28
  • 签到天数: 89 天

    [LV.6]常住居民II

    发表于 2020-8-8 16:07 | 显示全部楼层
    pwtxx 发表于 2020-8-8 15:24
    我这个程序是控制超声波的频率的,可以知道发出的声波频率是多少,所以知道只执行了一半 ...

    1. 你用的是特殊的旋转编码器吗?编码器有硬件防抖吗?你的两个if里都有5秒的delay。所以一个loop循环里绝大部分时间都在这5秒的delay上了。你怎么知道编码器的动作被正确读取到了呢?

    2. 你的以下这段代码没有软件防抖,同时也无法正确判断编码器的旋转方向呀

    //判断iPin脚电平是否变化,是返回1,否则返回0
    bool isChanged(int iPin){   
      bool newState = digitalRead(PIN[iPin]);
      if(newState!=oldState[iPin]){
        oldState[0]=newState;
        oldState[1]=newState;
        return 1;
      }
      else
        return 0;
    }

    该用户从未签到

     楼主| 发表于 2020-8-8 17:01 | 显示全部楼层
    ifeue 发表于 2020-8-8 16:07
    1. 你用的是特殊的旋转编码器吗?编码器有硬件防抖吗?你的两个if里都有5秒的delay。所以一个loop循环里 ...

    是那种机械的旋转编码器

    该用户从未签到

     楼主| 发表于 2020-8-8 17:04 | 显示全部楼层
    ifeue 发表于 2020-8-8 16:07
    1. 你用的是特殊的旋转编码器吗?编码器有硬件防抖吗?你的两个if里都有5秒的delay。所以一个loop循环里 ...

    频率输出在lcd上,好像确实没有防抖,偶尔会分不清顺逆时针,不过大部分时间都是正确的,确实也要加入防抖

    该用户从未签到

     楼主| 发表于 2020-8-8 17:45 | 显示全部楼层
    ifeue 发表于 2020-8-8 16:07
    1. 你用的是特殊的旋转编码器吗?编码器有硬件防抖吗?你的两个if里都有5秒的delay。所以一个loop循环里 ...

    我也不太懂判断顺逆的原理,不过确实可以判断:
    旋转编码器是一个可实现精确数字调节的器件,有必要学会如何使用它。
    如下图所示,其中1和2针脚形成独立的开关,按下旋钮即可导通。

    当旋钮静止时,K2和K3同时处于打开或闭合状态。

    若K2和K3处于打开状态,则顺时针旋转旋钮一小格,K2和K3都将变成闭合状态,只不过K3会先于K2闭合;再顺时针旋转一小格,K2和K3又会变成打开状态,K3仍先于K2打开。如果旋扭是逆时针方向旋转,则K2会先于K3打开或闭合。

    K2和K3状态改变先后的时间差非常小,通常只有通过单片机中断或高速查询来判断,从而确定旋转的方向。本例用到了查询的方式。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    arduinoUNO 用两个PIN控制一个spi设备(RFID)
    arduinoUNO 用两个PIN控制
    我已经测试,MRFC522的chipSelectPin 是正常的。当pin为低电平时可以正enable并都读写
    PIR和光线控制的小夜灯
    PIR和光线控制的小夜灯
    解答网友PIR和光线控制的小夜灯的提问, 1:光线暗和人走近RGB灯亮,或的逻辑关系。
    终于成功做出一个有界面的oled天气显示屏了!(小白流泪
    终于成功做出一个有界面的
    啊啊啊!忙活了一个月,终于做出来一个界面比较友好的天气oled显示屏了,在此感谢
    步进电机播放音乐
    步进电机播放音乐
    硬件:使用arduino uno板子与步进电机驱动器TB6600实物图 因为我这里用的是方波,才
    我的ESP8266继电器也不工作
    我的ESP8266继电器也不工
    代码是下的某音上的爆改车间主任控制灯泡的那一集 #define BLINKER_WIFI #define BLIN
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表