繁体   English   中英

如何在不使用任何库的情况下使用 arduino mega2560 控制两个伺服电机和蜂鸣器 function

[英]How can i controll two servo motor and buzzer with arduino mega2560 without using any library function

我尝试了以下代码……我已经成功运行了 1 个伺服和 1 个蜂鸣器,但我无法同时运行 2 个伺服……我的代码没有正常工作……我的伺服引脚是 11 & 12……我的蜂鸣器引脚是 5……这是我的代码和电路图……我图中的 uno 是一个巨型,只是为了确定……同样,我不能使用任何库函数像 pinMode() 或任何用于控制蜂鸣器或伺服的库....所以这是我的图表和代码

这是电路图

#define servo90 3000                                    //OCR1A value for the servo to reach 90 degrees
#define servo0 1000                                     //OCR1A value for the servo to reach 0 degrees
#define servoA90 3000                                    //OCR1A value for the servo to reach 90 degrees
#define servoA0 1000


volatile unsigned long sysTick = 0;                                 //set up a global system tick variable
unsigned long oldSysTickServo = 0;

volatile unsigned long sysTickA = 0;                                 //set up a global system tick variable
unsigned long oldSysTickServoA = 0;

//Buzzer I/O signal is connected to PIN 5

int tune1[] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440};
int dur1[] = {500, 500, 500, 500, 500, 500, 500, 500, 50};



int i, j, n = 10; //n is inialitsed to the number o fnotes in tune 1.
int tmp;
void setup() {
  DDRB = (1 << DDB5); //Set PB 5 (pin 11) to an output
  DDRB = (1 << DDB6);



  //set up a 1ms system tick timer
  cli();                                                //disable global interrupts
  TCCR0A = 0;
  TCCR0B = (1 << CS01) | (1 << CS00);                   //start the timer with a prescale of 64
  TIMSK0 = (1 << OCIE0A);                               //setup the output compare interrupt with OCR0A
  OCR0A = 250;                                          //set up the OCR0A value for exactly 1ms (or as close as the clock will allow)
  sei();                                                //enable global interrupts



  //setup the timer for fast PWM
  TCCR1A = (1 << COM1A1) | (1 << WGM11);                //Enable clear on OC1A
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);   //Set the prescale to 8 bits, Fast PWM with TOP in ICR1
  TCCR1C = 0;                                           //We dont need to do anything here, so make sure its shut off
  ICR1 = 40000;                                         //Set the top value to 40000. This should be a period of 20ms



  OCR1A = servo90;


  // setup the timer for 2nd pwm

  TCCR1A = (1 << COM1B1) | (1 << WGM11);                //Enable clear on OC1B
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);   //Set the prescale to 8 bits, Fast PWM with TOP in ICR1
  TCCR1C = 0;                                           //We dont need to do anything here, so make sure its shut off
  ICR1 = 40000;                                         //Set the top value to 40000. This should be a period of 20ms

  OCR1B = servoA90;


  // bazar timer count
  DDRE = (1 << DDE3);
  TCCR3A = (1 << COM3A1) | (1 << WGM31);
  TCCR3B = (1 << WGM33) | (1 << WGM32) | (1 << CS32);



}



void loop() {


  for (i = 0; i < n; i++) {
    ICR3 = tune1[i];
    OCR3A = tune1[i] / 2;
    TCNT3 = 0;


    for (j = 0; j < dur1[i]; j++) {
      _delay_ms(1);
    }



    ICR3 = 0; OCR3A = 0; TCNT3 = 0;



    //Has half a second passed?
    if (sysTickVal() >= oldSysTickServo + 500)
    {
      oldSysTickServo = sysTickVal();        //store the previous time
      //is the servo currently down?
      if (OCR1A == servo0)
      {
        //the servo is currently at 0 deg
        OCR1A = servo90;     //set the servo to 90deg
      }
      else
      {
        //the servo is currently at 90 deg
        OCR1A = servo0;     //set the servo to 90deg
      }
    }
    //Has half a second passed?
    if (sysTickValA() >= oldSysTickServoA + 500)
    {
      oldSysTickServoA = sysTickValA();        //store the previous time
      //is the servo currently down?
      if (OCR1B == servoA0)
      {
        //the servo is currently at 0 deg
        OCR1B = servoA90;     //set the servo to 90deg
      }
      else
      {
        //the servo is currently at 90 deg
        OCR1B = servoA0;     //set the servo to 90deg
      }
    }
  }




}
ISR(TIMER0_COMPA_vect)
{
  sysTickA++;
  sysTick++;
  //increment the system tick time every 1ms
  TCNT0 = 0;        //reset the timer
}





/**************************************************************************************************************************************/
//Function Name: get sysTick
//Inputs:
//Outputs:
//Hardware:
//Description: return the sytick value without any collitions
unsigned long sysTickValA()
{
  unsigned long val;    //create a variable to store the sysTick value
  cli();                //disable gloabl interrupt
  val = sysTickA;        //read in the current system time
  sei();                //enable global interrupt
  return val;           //return the current system time
}
unsigned long sysTickVal()
{
  unsigned long val;    //create a variable to store the sysTick value
  cli();                //disable gloabl interrupt
  val = sysTick;        //read in the current system time
  sei();                //enable global interrupt
  return val;           //return the current system time
}

不要对 DDRB 进行两次分配,只保留最后一个激活,而是使用两个位都设置的单个分配,例如:

DDRB = (1<<DDB5) | (1<<DDB6)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM