Как сделать основанное на времени внутреннее прерывание в коде Arduino? - PullRequest
0 голосов
/ 29 июня 2018

Мне нужно создать систему прерываний, которая обновляет регистр ШИМ каждый интервал времени x. Однако, если посмотреть на функцию attachinterrupt (), то, похоже, не существует опции, основанной на времени, а только вход для обнаружения нарастающего или падающего фронта. Можно ли сделать прерывание с повторяющимся запуском по времени?

Это мой код, мне нужно заменить цикл for и microdelay () на прерывание по времени:

int D4 = 6;

byte arr[] = {0x06, 0x0C, 0x12, 0x18, 0x1E, 0x2A, 0x30, 0x36, 0x3C, 0x40, 0x3C, 0x36, 0x30, 0x2A, 0x1E, 0x18, 0x12, 0x0C, 0x06};

void setup() {
  CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0);
  DDRC = (1<<DDC7)|(1<<DDC6);
  TCCR4A = (0<<COM4A1)|(1<<COM4A0)|(1<<PWM4A);
  TCCR4B = (0<<DTPS41)|(0<<DTPS40)|(0<<CS43)|(0<<CS42)|(0<<CS41)|(1<<CS40); 
  TCCR4D = (0<<WGM41)|(0<<WGM40);
  pinMode(D4, OUTPUT);
}

void loop() {
  OCR4C = 0x40;
 for (int i = 0; i <= sizeof(arr) ; i++ ){

  OCR4A= arr[i];
  delayMicroseconds(100);
 }
}

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Вы можете использовать прерывание по таймеру, которое будет прерывать всю программу с постоянными интервалами, выполнять блок кода, известный как ISR (подпрограмма обработки прерываний), а затем возвращаться туда, где оно остановилось в остальной части программы. Задержки, как правило, плохи, поскольку они мешают процессору делать что-то полезное. Приспособьте к своему соответствующему процессору, он выглядит как Arduino Mega. Думаю, мой добавленный код, вероятно, будет работать, но изначально он предназначен для Atmega 328 на Arduino Uno. Проверьте таблицы!

int D4 = 6,i = 0;

byte arr[] = {0x06, 0x0C, 0x12, 0x18, 0x1E, 0x2A, 0x30, 0x36, 0x3C, 0x40, 0x3C, 0x36, 0x30, 0x2A, 0x1E, 0x18, 0x12, 0x0C, 0x06};

void setup(){
    CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0);
    DDRC = (1<<DDC7)|(1<<DDC6);
    TCCR4A = (0<<COM4A1)|(1<<COM4A0)|(1<<PWM4A);
    TCCR4B = (0<<DTPS41)|(0<<DTPS40)|(0<<CS43)|(0<<CS42)|(0<<CS41)|(1<<CS40); 
    TCCR4D = (0<<WGM41)|(0<<WGM40);
    pinMode(D4, OUTPUT);

    TCCR0A = (1<<WGM01); //setup timer 0 to clear its counter when it reaches the OCR0A
    TCCR0B = (1<<CS00)|(1<<CS01); //prescaler 1/64 to divide the 16 MHz clock by 64
    TIMSK0 = (1<<OCIE0A); //setup the timer to toggle the ISR flag A
    OCR0A = 25; //every 25 counts will represent 100 microseconds
}

ISR(TIMER0_COMPA_vect){ //This is the ISR routine itself, triggered by compare flag A of timer 0
  OCR4A = arr[i];
  ++i;
  if(i>sizeof(arr)) i = 0;
}

void loop(){
    OCR4C = 0x40;
}
0 голосов
/ 30 июня 2018

Я предполагаю, что вы долгое время использовали контроллеры Atmel и очень плохо знакомы с Arduino.

Используйте библиотеку таймера, описанную здесь. https://playground.arduino.cc/Code/Timer1

Или вы можете реализовать программу типа пространства состояний, используя микро. Пример

long nextUpdateTime=micros();
loop(){
    if(nextUpdateTime<micros())
        return;
    nextUpdateTime=micros()+100; //Change 100 to what ever delay you want.
    // Write your required code here. This code will be called every 100 (Or whatever you set) us.
}

Опять же, вы можете просто использовать функцию analogWrite для генерации любого pwm, который вы пытаетесь сгенерировать. Я не уверен, что вы пытаетесь сделать, но я верю, что знание функции поможет. вот ссылка https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/

Надеюсь, это поможет. Хорошего дня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...