极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 5769|回复: 5

【求助】Arduino使用外部中断时发生的问题

[复制链接]
发表于 2016-4-1 11:11:31 | 显示全部楼层 |阅读模式
我要做个视频监控的程序,开发中发现中断有点问题,特来求助各位大神。

主程序的循环会驱动电击自动转动摄像头,利用外部中断来进行抓拍,抓拍时要保证清晰所以电机要暂停转动,所以按下抓拍按钮要设定延时来保证电机停止图像稳定。那么,问题来了,启动抓拍的时候,电机停止了,但是抓拍动作没有执行。

采用2号口(0号中断)作为抓拍输入,设为上拉电阻模式,低电平有效。
拍照动作输出端有两个,是12、13,高电平有效,程序设定是12号先开启高电平,等待2秒,然后13号开启高电平驱动摄像头抓拍动作。

出现的问题是,输入端按下按钮以后,12号开启了高电平,但不管等多久13号都不会开启高电平。我又修改了程序不用中断,循环调用的方式却可以正常。不知为什么?

源代码如下:

/*

*/
int CPinIn=2;//click
int NPinIn=6;//+
int SPinIn=7;//-

int KPinOut1=12;//1
int KPinOut2=13;//2

int MPinOutA=10;//machine+
int MPinOutV=11;//machine-

int APinInF=A0;//
int APinInT=A1;//dealy time
//=======================================
int vNStatus=0;
int vSStatus=0;
int vCStatus=0;

int vFStatus=0;
int vTStatus=0;

int vK1Status=0;
int vK2Status=0;

int vMAStatus=0;
int vMVStatus=0;
//===============================================
void setup() {
  // declare the ledPin as an OUTPUT:
  pinMode(CPinIn, INPUT_PULLUP);  
  pinMode(NPinIn, INPUT_PULLUP);  
  pinMode(SPinIn, INPUT_PULLUP);  

  pinMode(KPinOut1, OUTPUT);  
  pinMode(KPinOut2, OUTPUT);
  
  pinMode(MPinOutA, OUTPUT);  
  pinMode(MPinOutV, OUTPUT);  

  digitalWrite(KPinOut1,LOW);
  digitalWrite(KPinOut2,LOW);

  attachInterrupt(CPinIn-2,sTakePicC,LOW);
}
//===============================================
void loop() {

  vCStatus=digitalRead(CPinIn);
  vNStatus=digitalRead(NPinIn);
  vSStatus=digitalRead(SPinIn);
  
  vFStatus=analogRead(APinInF);
  vTStatus=analogRead(APinInT);

  if(vNStatus==LOW && vSStatus==LOW)
  {
    vFStatus=0;//stop
    sMachRun(MPinOutA,MPinOutV);
  }
  else if(vNStatus==LOW)
  {
    sMachRun(MPinOutA,MPinOutV);//N
  }
  else if(vSStatus==LOW)
  {
    sMachRun(MPinOutV,MPinOutA);//S
  }
  else
  {
    vFStatus=0;//stop
    sMachRun(MPinOutA,MPinOutV);
  }

  if(vTStatus>=0&&vTStatus<=1000)
  {
    sTakePicDelay();
  }
  else
  {
    digitalWrite(KPinOut1,LOW);
    digitalWrite(KPinOut2,LOW);
  }
            
}
//===============================================
void sMachRun(int pinOut1,int pinOut2)
{
  analogWrite(pinOut1,vFStatus/4);
  analogWrite(pinOut2,0);

}

void sTakePicDelay()
{
  delay(vTStatus*10+1);
  sTakePic();
}

void sTakePicC()
{
  detachInterrupt(CPinIn-2);
  sTakePic();
  attachInterrupt(CPinIn-2,sTakePic,LOW);
}

void sTakePic()
{   
    analogWrite(MPinOutA,0);
    analogWrite(MPinOutV,0);
    digitalWrite(KPinOut1,HIGH);
    delay(2000);
    digitalWrite(KPinOut2,HIGH);
    delay(500);
    digitalWrite(KPinOut1,LOW);
    digitalWrite(KPinOut2,LOW);
   
}
回复

使用道具 举报

发表于 2016-4-4 09:50:49 | 显示全部楼层
wangsheng108 发表于 2016-4-2 13:34
能说说详情吗?怎么不能调用,调用了以后无效,还是会怎样?

对于delay来说,它的原理应该是记录一个开始的系统通电时间(mills),然后不断地读取系统中断时间,当时间差达到你设定的那个值之后跳出读取的循环,继续执行你的程序。
但是在中断函数里,系统的通电时间是不增加的(就一直保持一个数),所以无论你设定delay多少,应该都不会继续下一步
因此认为delay在中断函数里是无效的
回复 支持 1 反对 0

使用道具 举报

发表于 2016-4-1 21:45:27 | 显示全部楼层
中断过程中不允许调用delay函数和mills函数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-2 13:34:46 | 显示全部楼层
zjz5717 发表于 2016-4-1 21:45
中断过程中不允许调用delay函数和mills函数

能说说详情吗?怎么不能调用,调用了以后无效,还是会怎样?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-6 11:20:36 | 显示全部楼层
zjz5717 发表于 2016-4-4 09:50
对于delay来说,它的原理应该是记录一个开始的系统通电时间(mills),然后不断地读取系统中断时间,当时 ...

谢谢了
回复 支持 反对

使用道具 举报

发表于 2019-4-30 10:06:23 | 显示全部楼层
zjz5717 发表于 2016-4-4 09:50
对于delay来说,它的原理应该是记录一个开始的系统通电时间(mills),然后不断地读取系统中断时间,当时 ...

你好,想你请教一个问题,我在中断函数里面用一个millis函数记录一下时间点可以吗,会对中断服务程序有影响吗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2020-7-8 12:54 , Processed in 0.049171 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表