Пьезозуммер с 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 ответ
На самом деле все упомянутые вызовы функций используют для работы Специальные регистры функций (SFR) и, следовательно, аппаратную периферию Arduino в фоновом режиме. Но я думаю, что это упражнение для того, чтобы научиться самостоятельно настраивать и использовать эти периферийные устройства. Выполнение этого для всего кода-довольно большая задача для одного вопроса на этом сайте. Поэтому я дам вам подсказки и укажу вам на соответствующие регистры. Тогда вам необходимо прочитать спецификацию ATmega328P (микроконтроллера на Arduino Uno). Он содержит подробные описания почти для каждой функции и SFR микроконтроллера.
ШИМ: Я думаю, вы хотите использовать ШИМ для создания сигнала от вашего зуммера. Это не классический случай использования ШИМ (так как вам не нужно менять рабочий цикл, а частоту, чтобы получать разные тона). Тем не менее, вы достигаете его с помощью того же оборудования. Для аппаратной ШИМ вам необходимо настроить таймер. 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 (вы можете выполнить математику с помощью прескалера, чтобы рассчитать требуемую частоту).Аналоговый считыватель, он же АЦП: Для считывания аналогового напряжения используется АЦП (аналого-цифровой преобразователь). Он имеет 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.ЖК-дисплей: Я не знаю, нужно ли вам также заменить библиотеку LiquidCrystal своим собственным кодом, поскольку в ней не используются специальные периферийные устройства (только цифровые контакты). Цифровые контакты управляются с помощью регистров
DDRx,PORTxиPINx. Google "манипуляция портом arduino" для получения дополнительной информации. И тогда вы сможете использовать функции из библиотеки с его помощью.
- Печать string and integer LCD
- Как добавить гистерезис к пороговым значениям?
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Ожидаемый инициализатор?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
Шаг первый: прочитайте спецификацию ATmega328P. В нем есть *вся* необходимая вам информация., @Majenko
Итак, ваш вопрос: как преобразовать приведенный выше код для использования регистров?, @Gerben