Могу ли я использовать Arduino для генерации ультразвуковых импульсов частотой 8 МГц в пьезодисках?

void setup()
{
    pinMode(freqOutputPin, OUTPUT);
    Serial.begin(9600);

    // Установите режим CTC Таймера 2 без предварительного масштабирования. OC2A переключается на сравнение совпадений
    //
    // WGM22:0 = 010: Режим CTC, переключение OC
    // биты 1 и 0 WGM2 находятся в TCCR2A,
    // Бит 2 WGM2 находится в TCCR2B
    // COM2A0 устанавливает OC2A (контакт 11 Arduino на Uno или Duemilanove) для переключения на сравнение совпадений
    //
    TCCR2A = ((1 << WGM21) | (1 << COM2A0));

    // Установка таймера 2. Без предварительного масштабирования (т. е. деление предварительного масштаба = 1)
    //
    // CS22:0 = 001: использовать тактовую частоту процессора без предварительного масштабирования
    // Все биты CS2 2:0 находятся в TCCR2B
    TCCR2B = (1 << CS20);

    // Убедитесь, что регистр сравнения-соответствия Прерывание для таймера 2 отключено
    TIMSK2 = 0;
    // Это значение определяет выходную частоту
    OCR2A = ocr2aval;

    Serial.print("Period    = ");
    Serial.print(period); 
    Serial.println(" microseconds");
    Serial.print("Frequency = ");
    Serial.print(freq); 
    Serial.println(" Hz");
}

void loop(){}

Я работаю над проектом, в котором мне нужен ультразвуковой импульс частотой 8 МГц каждую секунду, а излучателем является пьезодиск. Пожалуйста, помогите мне с кодом.

, 👍1

Обсуждение

Если вы используете Arduino на базе AVR, прочитайте [Таймеры и счетчики](https://www.gammon.com.au/timers) Ника Гаммона., @Edgar Bonet

Это интересная статья, но, похоже, она посвящена обнаружению импульсов, а не их созданию. Я что-то пропустил?, @Hack Saw

на самом деле мне нужно и излучение, и обнаружение, но в настоящее время я работаю над испусканием импульсов с помощью Arduino и пьезо-дисков, но я не так хорош в кодировании, @Danish

какой код вы уже пробовали?, @MichaelT

я встроил код выше, @Danish

@Danish, а почему это не работает? Что оно делает? Чего вы ожидаете от этого?, @frarugi87


1 ответ


Лучший ответ:

1

Под импульсом 8 МГц я предполагаю, что вы имеете в виду импульс длительностью 0,125 мкс каждую секунду. «Частота» здесь может вводить в заблуждение.

Поскольку ATmega328 в Arduino Uno работает только на частоте 16 МГц, у вас есть только один дополнительный цикл, прежде чем вам придется его снова выключить. Для отладки и разработки на такой скорости абсолютно необходим хороший осциллограф.

Я бы попытался установить выходной контакт через регистр, а затем сразу же отключить его. Используйте cli(), чтобы предотвратить прерывания во время желаемого импульса.

void setup() {
  DDRC |= (1 << DDRC0);   //Устанавливаем PC0 как выход (аналоговый контакт 0)
}
void loop() {
  cli();                  //Отключаем прерывания
  PORTC = 0b00000001;     //Устанавливаем ВЫСОКИЙ аналоговый вывод 0
  PORTC = 0b00000000;     //Устанавливаем НИЗКИЙ аналоговый вывод 0
  sei();                  //Снова разрешаем прерывания
  delay(1000);            //Задержка на 1000мс до следующего импульса
}

Остерегайтесь, что это также установит НИЗКИЙ уровень на всех других контактах порта C (аналоговые контакты с 1 по 5).

Это

  PORTC |= (1 << PORTC0);     //Устанавливаем ВЫСОКИЙ аналоговый вывод 0
  PORTC &= ~(1 << PORTC0);     //Устанавливаем НИЗКИЙ аналоговый вывод 0

будет чище и повлияет только на аналоговый вывод 0, но для выполнения может потребоваться более одного тактового цикла. К сожалению, у меня нет достаточно быстрого осциллографа, чтобы проверить это. Если он слишком быстрый (например, вы получаете импульс длительностью 0,06125 мкс), вы можете вставить еще один PORTC = 0b00000001;, прежде чем снова его выключить. Вполне вероятно, что оптимизация компилятора может просто удалить это при компиляции, поэтому вам, возможно, придется установить какой-то другой регистр, чтобы тратить этот такт впустую.

,

Ваш второй фрагмент — это то, что вам нужно. Почти гарантированно будут сгенерированы правильные инструкции sbi и cbi на любом уровне оптимизации (за исключением, может быть, нулевого уровня). Каждая из этих инструкций выполняется за два такта, поэтому вы получаете импульс шириной ровно два такта., @Edgar Bonet