Пьезозуммер с PWM на arduino uno с atmega328p в C на регистрах + аналоговый поток на регистрах

У меня есть небольшой проект в университете, где я должен использовать таймеры, чтобы генерировать ШИМ сигнал и получить его в пьезо зуммер, когда еще что-то переворачивается определенное значение с помощью регистров, дело в том, что мы работали над некоторыми микроконтроллерами, так что я не знаю библиотеки для Arduino Uno с схема ATmega328P и я хочу попросить некоторую помощь на этом. Кроме того, я должен использовать регистры вместо функции analogRead (), которая считывает данные с датчика температуры.

Имея следующий код, который работает для моей настройки:

#include <LiquidCrystal.h>         

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Цифровые контакты, к которым вы подключаете LCD
const int inPin = 0; 
const int buzzer=9;// A0 is the sensor
void setup()
{
  pinMode(buzzer,OUTPUT); // DDRA=0b00000001;
  lcd.begin(16,2);
}
void loop()
{
  int value = analogRead(inPin); //  считывает значение с датчика <= to be written on registers
  lcd.setCursor(0,1);
  float millivolts = (value / 1024.0) * 5; 
  float celsius = (millivolts-0.5)*100;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(celsius);
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print((celsius * 9)/5 + 32); //turning the celsius into fahrehait
  lcd.print("F");
  delay(1000);
  if(celsius>30.0){tone(buzzer,1000);delay(1000);noTone(buzzer);delay(1000);} //<= on registers
}

, 👍1

Обсуждение

Шаг первый: прочитайте спецификацию ATmega328P. В нем есть *вся* необходимая вам информация., @Majenko

Итак, ваш вопрос: как преобразовать приведенный выше код для использования регистров?, @Gerben


1 ответ


1

На самом деле все упомянутые вызовы функций используют для работы Специальные регистры функций (SFR) и, следовательно, аппаратную периферию Arduino в фоновом режиме. Но я думаю, что это упражнение для того, чтобы научиться самостоятельно настраивать и использовать эти периферийные устройства. Выполнение этого для всего кода-довольно большая задача для одного вопроса на этом сайте. Поэтому я дам вам подсказки и укажу вам на соответствующие регистры. Тогда вам необходимо прочитать спецификацию ATmega328P (микроконтроллера на Arduino Uno). Он содержит подробные описания почти для каждой функции и SFR микроконтроллера.

  1. ШИМ: Я думаю, вы хотите использовать ШИМ для создания сигнала от вашего зуммера. Это не классический случай использования ШИМ (так как вам не нужно менять рабочий цикл, а частоту, чтобы получать разные тона). Тем не менее, вы достигаете его с помощью того же оборудования. Для аппаратной ШИМ вам необходимо настроить таймер. Uno имеет 3 таймера, где Timer0 уже настроен в среде IDE Arduino для таких функций, как задержка (), millis() и тому подобное. Поэтому я предлагаю вам использовать Timer1. Он имеет 3 управляющих регистра, называемых TCR1A - TCR1C. Вы хотите, чтобы таймер находился в режиме CTC (Очистить таймер при сопоставлении)(Биты режима генерации сигналов установлены на 4, режим CTC для OCR1A). Таймер будет отсчитываться с заданной частотой (опишем это позже), пока не достигнет значения, которое вы записали в регистр OCR1A (Сравните совпадение). Затем он будет сброшен. Если вы установили биты COM1Ax в регистре TCR1A на правильные значения, вы можете настроить его для переключения вывода OC1A при сопоставлении).

    Таким образом, в этом режиме таймер сбросится на заданное вами значение счетчика и переключит для вас выходной вывод OC1A. Таким образом, он генерирует прямоугольную волну с переменной частотой, которой вы можете управлять, записывая различные значения в регистр OCR1A.

    Но нам также нужно настроить частоту, с которой будет отсчитываться таймер. Это делается с помощью битов выбора тактовой частоты CS10-CS12 в регистре TCR1B. Значение 0 для всех битов означает, что таймер остановлен. Посмотрите на соответствующую таблицу в описаниях регистров Timer1 в таблице данных. Вы хотите подключить таймер к внутренним системным часам. С помощью этих битов вы можете настроить прескалер. Это определяет, сколько тактовых импульсов необходимо, чтобы таймер насчитал 1. Без прескалера таймер будет отсчитывать каждый тактовый импульс. При битовых значениях 0 1 1 вы получите прескалер 64, поэтому таймер будет отсчитывать 1 каждые 64 тактовых импульса. Это устанавливает диапазон частот, который у вас есть со счетчиком. Внутренние системные часы работают на частоте 16 МГц в Uno (вы можете выполнить математику с помощью прескалера, чтобы рассчитать требуемую частоту).

  2. Аналоговый считыватель, он же АЦП: Для считывания аналогового напряжения используется АЦП (аналого-цифровой преобразователь). Он имеет SFR ADMUX, ADCSRA, регистры результатов преобразования ADCL и ADCHи ADCSRB. Сначала мы хотим установить опорное напряжение для нашего преобразования. Когда мы устанавливаем биты REFS1 и REFS0 в регистре ADMUX равными 01, мы используем Vcc в качестве опорного напряжения, которого в большинстве случаев достаточно. Биты MUX3 - MUX0 в одном регистре выбирают один из выводов АЦП для преобразования рекламы (у нас есть только 1 АЦП в ATmega328P, но мы можем подключить его к нескольким выводам АЦП один за другим). Теперь в реестре ADCSRA: бит ADEN включит АЦП, с помощью ADSC мы сможем начать преобразование. С битами ADPS2 - ADPS0 мы можем выбрать прескалер тактовой частоты для АЦП. Это определяет, с какой скоростью работает АЦП. Для максимального разрешения вы должны поддерживать частоту в диапазоне от 50 до 200 кГц.

    Вы можете начать конвертацию, написав 1 в ADSC. Затем вы можете опросить бит ADIF в том же регистре. Он будет установлен на 1, когда АЦП завершит преобразование. Затем вы можете прочитать результат преобразования из регистров ADCL и ADCH (для младшего байта и старшего байта 10-битного результата). После этого вы должны сбросить бит ADIF, записав в него 1.

  3. ЖК-дисплей: Я не знаю, нужно ли вам также заменить библиотеку LiquidCrystal своим собственным кодом, поскольку в ней не используются специальные периферийные устройства (только цифровые контакты). Цифровые контакты управляются с помощью регистров DDRx, PORTx и PINx. Google "манипуляция портом arduino" для получения дополнительной информации. И тогда вы сможете использовать функции из библиотеки с его помощью.

,