Понадобился генератор прямоугольных импульсов с независимой регулировкой частоты и скважности.
Диапазон 0,1 - 1000 Гц, шаг регулировки 0,1 Гц. Длительность импульсов от 10 мкс, шаг регулировки 10 мкс. Частота и длительность выводятся на дисплей, в герцах и миллисекундах. Макс. скважность 50%.
Хотел все реализовать в Atmega328, поскольку она все равно есть в устройстве, хотя и до этого я никогда не программировал вообще.
Все, что я смог придумать - это сделать предделитель таймера на 1, установить прерывание по совпадению на 16 (отсчитали 1 микросекунду) и в прерывании изменять переменную х+1. Соответственно сравнивая с двумя другими переменными - подавать 1 или 0 на ножку МК.
Вроде бы худо-бедно работает, но при этом дисплей жутко тупит - секунд по 5 выводятся данные. Если вызывать прерывание по совпадению на 126 (160-34 цикла) - тогда все приемлемо, но длительность импульса конечно будет меняться с шагом 100 мкс. а не 10. Режим СТС не подходит, да и шаг изменения будет 16000000\256= 62500; 1\62500=0,000016 мкс., а хочется кратно10-ти.
Собственно, вопрос: как реализовать такой генератор на МК? Поможет ли ускорить работу МК такие ухищрения как собственный кварц для таймера, или подключение дисплея напрямую без регистра сдвига?
Гуглится очень много подобных тем, но решения вопроса нет ни в одной.
Вот кусочек моего индусского кода:
void WorkOn() {
OCR0A=126; // Количество импульсов соответствующих 10 микросекундам. 16 МГц /(160 - 34)
TIMSK0=(1<<OCIE0A);
TCCR0B=0x01; //Предделитель тактовой частоты - 1.
UpdateFrequency();//обновление переменных
}
ISR (TIMER0_COMPA_vect){ // Генератор импульсов.
TCNT0=0;//обнуляем регистр TCNT1
Timer0Count=Timer0Count+1; // Счетчик таймера, 1 ед. = 10 Микросекунд.
if (Timer0Count == DelayTime){ // Если счетчик таймера соответствует паузе между импульсами.
PORTB |= 1<<3; // Начало импульса.}
if (Timer0Count == PeriodTime){ // Если счетчик таймера соответствует периоду.
PORTB &= ~(1<<3); }// Конец импульса.
Timer0Count=0;} // Сброс счетчика.
}
void UpdateFrequency() {
PeriodTime = 1000000/Frequency; // Период = 1000000 микросек./частота(Гц)*10
PulseTimeMax = PeriodTime/2; // Максимальная скважность - 50%.
if (PulseTime > PulseTimeMax) // Если была увеличена частота и скважность стала более 50%
{PulseTime = PulseTimeMax;}
DelayTime=PeriodTime-PulseTime;
}



