Attiny13 Тактовая частота и АЦП
Я работаю с Attiny13 AVR, который запрограммирован Arduino UNO через SPI.
Я нашел ядро для attiny13 и содержимое файла boards.txt следующим образом;
#attiny13.name=Attiny13 @ 128 KHz (internal watchdog oscillator)
#attiny13.upload.using=arduino:arduinoisp
# attiny13.upload.protocol=avrispv2
# attiny2313at1.upload.using=pololu
#attiny13.upload.maximum_size=1024
#attiny13.upload.speed=250 # important for not losing connection to a slow processor
#attiny13.bootloader.low_fuses=0x7B
#attiny13.bootloader.high_fuses=0xFF
#attiny13.bootloader.unlock_bits=0x3F
#attiny13.bootloader.lock_bits=0x3F
#attiny13.build.mcu=attiny13
#attiny13.build.f_cpu=128000
#attiny13.build.core=core13
########################
attiny13e.name=Attiny 13A standalone 9.6Mhz
attiny13e.upload.using=arduino:arduinoisp
attiny13e.upload.maximum_size=1024
attiny13e.upload.speed=19200
attiny13e.maximum_data_size=64
attiny13e.bootloader.low_fuses=0x7A
attiny13e.bootloader.high_fuses=0xFF
attiny13e.bootloader.path=empty
attiny13e.bootloader.file=empty
attiny13e.bootloader.unlock_bits=0xFF
attiny13e.bootloader.lock_bits=0xFF
attiny13e.build.mcu=attiny13
attiny13e.upload.tool=avrdude
attiny13e.build.f_cpu=9600000L
attiny13e.build.core=core13
Когда я программирую attiny13, я выбираю "Attiny 13A standalone 9.6Mhz" в качестве целевой платы.
Итак, я ожидаю, что он будет работать на частоте 9,6 МГц.
Я установил регистр TCCR0B следующим образом, чтобы получить "Без предварительного масштабирования"
TCCR0B |= _BV(CS00);
TCCR0B &= ~_BV(CS01);
TCCR0B &= ~_BV(CS02);
Также установите режим ШИМ как "Быстрый ШИМ", изменив регистр TCCR0A.
TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(WGM01);
TCCR0A &= ~_BV(WGM02);
С этими настройками я должен получить частоту ШИМ 9,6 МГц /256 = 37,5 КГц. Однако, когда я подключаю выход ШИМ к MOSFET для вождения и светодиодной ленты, я получаю и слышу жужжание от MOSFET.
Это побуждает меня думать, что мои часы не работают на частоте 9,6 МГц, так как 37,5 КГц не является слышимой частотой.
Итак, я сделал еще один быстрый поиск по теме тактовой частоты и нашел следующую веб-страницу;
https://www.avrprogrammers.com/howto/sysclk-prescaler
Если я не ошибся, на этой странице написано, что моя тактовая частота по умолчанию делится на 8.
Чтобы иметь возможность получить делитель, мне нужно сбросить все биты.
Я так и сделал и сбросил все биты CLKPS.
CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
Итак, теоретически, я должен получить тактовую частоту 9,6 МГц с делителем 1.
Когда я использую все эти вышеупомянутые настройки, я больше не слышу жужжащий звук.
Однако на этот раз возникла другая проблема.
Я использую потенциометр для управления яркостью. При установке делителя часов на "1" поведение потенциометра изменилось. Аналоговый вход не сразу считывает значение, когда я поворачиваю потенциометр, поэтому мне нужно немного повернуть его, чтобы получить минимальную яркость, и она достигает максимальной яркости, прежде чем я достигну другого конца потенциометра. Поэтому я считаю, что с АЦП что-то не так.
Под названием "Аналого-цифровой преобразователь" я нашел следующую информацию;
По умолчанию схема последовательного приближения требует входную тактовую частоту от 50 кГц до 200 кГц, чтобы получить максимальное разрешение. Если требуется более низкое разрешение, чем 10 бит, входная тактовая частота для АЦП может быть выше, чем 200 кГц, чтобы получить более высокую частоту дискретизации.
Итак, моя тактовая частота составляет 9,6 МГц, и мне нужно установить прескалер между 9,6 МГц /20 кГц = 48 и 9,6 МГц /50 кГц = 192 для регистра ADCSRA. Я выбрал коэффициент деления 128, который требует установки всех трех битов ADPS2, ADPS1 и ADPS0.
ADCSRA != 1<< ADPS2;
ADCSRA != 1<< ADPS1;
ADCSRA != 1<< ADPS0;
Это должно установить все три бита и поддерживать частоту АЦП в диапазоне от 50 кГц до 200 кГц.
Тем не менее, я все еще получаю такое же поведение от потенциометра.
Где я не прав?
1 ответ
ADCSRA != 1<< ADPS2;
ADCSRA != 1<< ADPS1;
ADCSRA != 1<< ADPS0;
три пустых утверждения, которые не имеют никакого эффекта. (Каждый из них повторяет логический результат.) Вы хотели написать
ADCSRA |= 1<< ADPS2;
ADCSRA |= 1<< ADPS1;
ADCSRA |= 1<< ADPS0;
или же
ADCSRA |= 1<< ADPS2 | 1<< ADPS1 | 1<< ADPS0;