Здравствуйте! Подскажите, куда копать. Необходимо сделать низкочастотный генератор на Atmega16 для управления дозировочным насосом. Частота имульсов от 0,25 до 10 гц При этом в этотм контроллере работает аппаратный ШИМ около 7кГц. (Делал канеш проще - посредством ШИМа с МК управлял ГУНом и делил счетчиком.. работает все, но много деталек..) Регулировать частоту можно посредством изменения пост напряжения (ручная регулировка) и программным способом(по датчику температуры).
Спасибо, канеш, но вот delay все будет портить.. Про это я и сам знаю, что можно так. там как то через прерывания надо, что ли.. Подскажите...
Например, есть термопара, она дает разность потенциалов при возрастании температуры. это отлавливает дифференциальный вход АЦП и присваивает это некоей переменной. а от этой переменной зависит частота этого генератора(чем выше температура, тем чаще щелкает) и так же зависит скважность аппаратного ШИМ.
Не знаю, как насчёт delay_ms() (похоже на CAVR), но в том же avr-gcc похожая функция (_delay_ms(double value)) может принимать аргументом только константу, но не переменную. Так что для плавной перестройки тем же _delay_ms() пользоваться уже не получится.
А с каким шагом нужно регулировать-то? Мне почему-то кажется, что тут может даже потребоваться нелинейная зависимость, а логарифмическая. Потому как изменение 0.25Гц -> 0.50Гц - это много, в 2 раза, а вот 9.75 -> 10.00 - это совсем чуть-чуть. Хотя шаг тот же.
Не знаю, как насчёт delay_ms() (похоже на CAVR), но в том же avr-gcc похожая функция (_delay_ms(double value)) может принимать аргументом только константу, но не переменную. Так что для плавной перестройки тем же _delay_ms() пользоваться уже не получится.
А с каким шагом нужно регулировать-то? Мне почему-то кажется, что тут может даже потребоваться нелинейная зависимость, а логарифмическая. Потому как изменение 0.25Гц -> 0.50Гц - это много, в 2 раза, а вот 9.75 -> 10.00 - это совсем чуть-чуть. Хотя шаг тот же.
Да,кст, есть о чем подумать.. но,мне каж ,это не так важно, т.к. планируется туда какой нить ПИ регулятор, а то и просто П.. А шаг чем. меньше, тем лучше.Насколько возможно. Достаточно до 5Герц частоты для насоса. Мне это предстоит выяснить этот диапазон.
Ну да, просто кнопками. В будущем планировал сделать имитатор турбинного счетчика жидкости.Если есть протеус, можно посмотреть работу в симуляторе.
Ага, посмотрел. спасибо, работае в протеусе.. (только для меня IAR незнаком...) У меня есть программка, которая делает многоканальный ШИМ аппаратный.
Код:
#include<avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define FIRST_ADC_INPUT 0x02 // первый канал АЦП, какой поставишь, напр, ADC0 #define LAST_ADC_INPUT 0x03 // последний канал АЦП, хоть 16-й. unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT];
#define ADC_VREF_TYPE 0x60 // регистр ADMUX, настройка опорного наряжения(тут от VCC) //volatile long int_spedometr, f_spedometr; //volatile long int_tahometr, f_tahometr; #define out1 OCR3A //тут и далее в программе все, что в тексте out1 будет сделано для OCR3A #define out2 OCR3B //аналогично можно ппродолжить и дальше , типа, out3, out4.... int main(void) { //порты на выход ШИМ. Конфигурируем порты контроллера PORTE = 0; DDRE = 0x18;
/* Настройка ШИМа на выходе. Для других контроллеров надо делать по своему. Здесь для Atmega1280 & 2560 Тут я скопировал значения для TCCR3n в TCCR4n и оно работает.) Тут регилирется частота ШИМ, вид.(фаст, с коррекц фазы и пр..)*/
//Настройка АЦП ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(2<<ADPS0)|(1<<ADPS1)|(1<<ADPS0); //дальше прерывания и прочее..Не особо в них шарю пока, объяснил бы кто, :) sei(); //начало цикла перебора каналов for(;;); } ISR(ADC_vect) { static unsigned char input_index=0; // читаем результаты конвертации из ADCH в массив [] adc_data[input_index]=ADCH ; // Select next ADC input {if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; } //..Цикл крутиться, каналы перебираются...Назначаем тут скока позволяет контроллер //лишние ADC не надо активировать, а то наводка.. /*Присваивается значение массива значению счетчика */ out2 = adc_data[0]*0.25 ; // /0.3;//Меняя эти значения, изменяется скважность ШИМ. out1 = adc_data[1]; //OCR3C = adc_data[2]; //OCR4A = adc_data[0]; //OCR4B = adc_data[1]; //OCR4C = adc_data[2]; // И т.д. ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE ) )+input_index;
_delay_us(60); // задержка, типа, чтобы успокоилось..ставил 20us, засветка крайних каналов, если ставить светодиоды. ADCSRA|=0x40; //возобновление преобразования.. }
Познания мои в программировании оставляют желать лучшего, но пытаюсь, )) Как бы Вы мне подсказали б , может в общих чертах, как их сопрягнуть.. Вопросы есть. Не получается с разной частотой сделать шим на , например, OCR1, (может и невозможно)
Задача , какжется, несложной.. .. Следуют импульсы (подается солярка) - горит огонь - термопара реагирует - если в диапазоне - продолжаем с той же частотой импульсы +шим на вентилятор наддува. Задали большую температуру - чаще импульсы - и так же меняется скважность для вентилятора (опять же, термопара следит за температурой -если температура падает при увеличении импульсов, чуть меньше на вентилятор(он охлаждает )
Зачем ШИМ, если полупериоды нужны одинаковые? Кто вам сказал, что аппаратный ШИМ 7кГц (у него прямая зависимость от частоты тактов МК и предделителя таймера, например: частота 1000000, предделитель 1024, получаем частоту в 4 Гц)? Вам нужно копать в сторону режима работы таймера сброс по совпадению.
Частоту ШИМа не трогайте, ибо незачем. Настроили таймер на ШИМ- если вентилятор работает как надо, отстаньте от него. Другой таймер настраиваете на сброс при совпадении и в регистр сравнения пихаете нужные значения для генерации необходимых частот.
Частоту ШИМа не трогайте, ибо незачем. Настроили таймер на ШИМ- если вентилятор работает как надо, отстаньте от него. Другой таймер настраиваете на сброс при совпадении и в регистр сравнения пихаете нужные значения для генерации необходимых частот.
Дыг вентилятор и крутится на частототе ШИМ около 7кГц.. это как настроить. Вероятно не так я понят вами, ))
Мне не понятно и не доходит, как это - прерывание по совпадению.. Объясните. плз, а то механизм не совсем ясен.
Есть регистр счета таймера. Считает от 0 до 255 - 0,1,2....254,255,0,1.... и.т.д. Есть регистр, в который вы записали число, предположим 4. Как только число в регистре счета совпадет (станет равным) вашему заданному, взведется флаг прерывания по совпадению. Если соответствующие прерывания разрешены и прерывания вообще, то управление передастся на вектор обработки этих прерываний.
Тут есть маленькая тонкость - максимальный делитель для таймера обычно 1024. При типовых частотах микроконтроллера (допустим, 8МГц) тактироваться таймер будет на частоте около 8кГц - реже не получится. Если таймер 8-битный, то в режиме CTC получится 8000/256=32Гц - это самая "медленная" возможная частота.
Так что надо либо 16-битный таймер использовать, либо в основной программе коэффициент вводить. Срабатывание таймера по совпадению будет этот коэффициент увеличивать, а уж основная программа будет ограничивать этот коэффициент в нужных пределах.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения