Так какой смысл выкладывать лишь часть исходника без конкретного описания задачи и желать по сути "сделайте за меня ...."?
vda67 писал(а):
... Так вот значение OCR2 меняется от 255 до 0 с дискретностью 1. ...
Допустим начальное значение в OCR2 заносит АЦП. запуск таймера должно дать прерывание Что и с каким интервалом вызывает изменение значения OCR2? и так далее...
Чтобы переписать надо сначала самостоятельно обычным языком задачу четко описать. Затем документацию на МК (и прочую, применяемую в проекте матчасть) внимательно перечитать. Затем снова к словесной задаче вернуться и провести ее реализацию с помощью известного компилятора и данных о матчасти. А тут какая то мешанина с непонятными исходными и средствами получения результатов... Да еще как оказывается это всего лишь "выкусь" какой то части другого проекта...
Посмотрим, что vda67 ответит на предложение выложить полное словестное описание задачи. Пока я вижу в его вопросах сбор вариантов решений для своих задач с разных сайтов вместо самостоятельной разработки конструкции. Зачем к примеру вместо простой функции запуска счетчика в ранее выбранном режиме запихивать функцию с возможностью смены настроек режимов таймера при каждом последующем запуске? Да и обзор режимов таймера по даташиту похоже не делался (или преднамеренно "замутнялся" чтоб никто не догадался чего делается и "супердевайс" в коммерческий оборот не пустил)...
Схема еще не до конца доделана а принцип регулирования фазы включения симмистора в зависимости разности измеренного значения от PC0 и константы. если PC0 < константы то OCR2 уменьшается и если PC0 > константы то OCR2 увеличивался и срабатывание прерывания от таймера изменяли состояние PC4
Изначально OCR2 255
Я почему обратился на PC4 изменения скважности скачками не плавно не мог понять точему.
А инициализация таймера при запуске это пробный код из уроков программирования. Не судите строго.
Должно получится регулятор давления с защитами от кз на выходе и режим плавного пуска.
Пробовал частотник но он не работает с однофазными конденсаторными двигателями.
Да вы правы имитация датчика пока с помощью резистора. В протеусе тоже с помощью резистора в живую с помощью подстроечника
Времени таймера не хватало на 8,5 мс выдавал 7,2мс поставил задержку 0,6мс она и вызвала сбои пришлось разделить сигнал от PC814 на два входа PD2 и PD3 прерывание один на передний второй на спадающий получилось примерно 0,5 мс. В промежутке дал запрет таймеру вроде получилось и в протеусе и в живую. теперь нужно замедлить время изменения OCR2 боюсь что если воспользуюсь делеем скачки опять появятся
Или при использовании делая контролер стоит пока идёт задержка и когда приходит прерывание бросает всё обрабатывает его и дальше возвращается к программе?
Последний раз редактировалось vda67 Ср мар 04, 2026 18:19:07, всего редактировалось 1 раз.
А как к тому же расчет суммы и разности делается? Исходно беззнаковый байт константы и какая то величина данных. Вполне может иметь место "вылет за границы разумного" с искажением конечного результата.
С АЦП байт типа char сравнивается с константой типа char дальше если константа больше то Tz-1, если константа меньше то Tz+ 1 и если константа и с АЦП байт равны то остаётся без изменения Tz при запуске таймера в OCR2 записывается Tz
+/-1 проходят и через 0 и через 0хFF оба варианта можно считать некорректными и соответственно исключить. Проверить корректность момента перезаписи данных в регистр OCR2 - не все режимы могут подходить для задачи при произвольном моменте смены информации. АЦП не 8 разрядный - следовательно или шум поймает или будет более грубое значение давать. При том, что еще вопрос в фиксации значения с потенциометра может иметь место - непрерывно следим или только при фиксации очередного отклонения от предыдущего значения... Да и сам алгоритм... "значение" может заметно и долго отличаться от "константы" и все это время идет изменение по единичке... или другая крайность если сигнал "значения" будет меняться быстрее, чем проводится обработка (частота опросов АЦП), то вполне вероятно и появление "шараханий" - к примеру от +1 сразу в -1 и обратно... Вариантов много... Ни схемы, ни программы... ни описания... похоже бедный таймер тут абсолютно не при делах... Проще для начала программный задатчик - сканер сделать. А уже после отладки программой перейти к выяснению следующей точки.
Согласен да может переваливать для этого я сделал ограничения чтобы не выше 255 и не ниже 1. АЦП я беру только верхний байт Непрерывно следим за двумя каналами РС0 и РС1 Их выводим на дисплей 1602 Схемы на нарисованной нет только только в куски в протеусе целиком схему протеус не берёт в ошибку вылетает кусками берёт Исходник программы могу выслать только не для общего обозрения ато вдруг смеяться будут и лажать куда мол лезешь В регистр OCR2 запись происходит после запуска таймера от прерывания по PD2 по спаду Значение АЦП я жду While пока фраг в 0 не станет Значения в протеусе на дисплее стоят отлично в живую дёргаются наверно слишком быстро информация меняется надо частоту процессора понизить с 8 до 4
Самое вероятное - выбран неверный алгоритм обработки. Но тут уж самому выбирать надо по имеющейся литературе по автоматике/регуляторам под восприятие условий задачи. Качественное описание заметно решению поможет. Но тут уже другой вопрос обсуждать надо,а не работу со счетчиком.
void init_interrupt(char YROVEN) // настройка прерывания { GICR|=(1<<INT0); // включаем прерывания MCUCR|=((YROVEN & 1)<<ISC00)|((YROVEN >>1 & 1)<<ISC01);//устанавливаем тип срабатывания // 1-Любое изменение уровня на выводе INT0, 2-Нисходящий фронт сигнала (смена 1 на 0) на выводе INT0 //3-Восходящий фронт сигнала (смена 0 на 1) на выводе INT0, 0- Нижний уровень на выводе INT0 } void int_StopTimerT2(void) { TCCR2 = 0b00000000; }
{ TCNT2 = 0x00;//обнуляем счетчик таймера Т2 TCCR2 = 0x00; // Сброс регистра конфигурации таймера Т2 TCCR2|=((delitel >>2 & 1)<<CS22)|((delitel >>1 & 1)<<CS21)|((delitel & 1)<<CS20) // Установка делителя: 0-Источника тактирования нет таймер остановлен, // 1-Тактовая частота МК, 2-Тактовая частота МК/8, 3-тактовая частота МК/32, // 4-Тактовая частота МК/64, 5-Тактовая частота МК/128, 6-Тактовая частота МК/256, // 7-Тактовая частота МК/1024. |((rejim_taim >>1 & 1)<<WGM21)|((rejim_taim & 1)<<WGM20)//Режим работы таймера/счётчика // 0-Нормальный режим счётчика, 1-ШИМ с коррекцией фазы, //2- Сброс таймера при совпадении регистров OCR2 и TCNT2 (CTC) и 3-Быстрая ШИМ (Fast PWM). |((rejim_OC2 >>1 & 1)<<COM21)|((rejim_OC2 & 1)<<COM20) // Режим работы вывода OC2: 0-Вывод ОС2 отключён от таймера/счётчика, //1- Состояние вывода меняется на противоположное при совпадении TCNT2 и OCR2 //(только в режимах Normal и CTC) //2-На OC2 устанавливается "0" при совпадении TCNT2 и OCR2 // и устанавливается "1" при сбросе счётчика, //3-На OC2 устанавливается "1" при совпадении TCNT2 и OCR2 //и устанавливается "0" при сбросе счётчика. |((rejim_foc2 & 1)<<FOC2);//устанавливаем тип срабатывания // предназначен для принудительной установки логического уровня на выходе OC2. // Он работает только для режимов Normal и CTC. При установке бита FOC2 в единицу //состояние выхода меняется в соответствии со значениями битов COM21 и COM20. } void int_RazPrerT2(char Kakoe)//разрешения прерываний { TIMSK &=0b00111111;// сброс прерываний таймера Т2 TIMSK|=((Kakoe >>1 & 1)<<OCIE2)|((Kakoe & 1)<<TOIE2); //0-Все прерывания запрещены, 1-Разрешает прерывание по событию переполнение, //2-Разрешает прерывание по событию совпадение, 3-Разрешает прерывания по обоим событиям // sei();// Разрешение работу прерываниям }
void int_pcb(void) { DDRD = 0b11110011;//PD0 PD1 PD4 PD5 PD6 PD7 — настраиваем ножки на выход PD2 PD3 - Вход PORTD = 0b00001100;//РD2 PD3 — подключаем подтягивающие резисторы DDRC = 0b00110000; // Конфигурируем вывод порта PC0-PC3 как вход и PC4 PC5 как выход }
ISR(INT0_vect)// прерывание по ножке PD2 { PORTC &= ~(1 << PC4);// Устанавливаем 0 на его выходе на линии 4 порта C _delay_ms(0.6); int_TimerT2(6,2,0,0);//запукаем таймер Т2 OCR2 -=1;
}
ISR (TIMER2_COMP_vect) // Если произошло прерывание по совпадению таймера Т2 {
if(OCR2 <1) { PORTC &= ~(1 << PC4);// Устанавливаем 0 на его выходе на линии 4 порта C } else { PORTC |=_BV (PC4); //Устанавливаем 1 на выходе PC4 } }
int main(void) { int_pcb(); //Настройка портов sei();// Разрешение работу прерываниям init_interrupt(3); // Включение прерывания по входу PD2 int_RazPrerT2(2);//разрешения прерываний от таймера Т2
Насколько я понял у вопрошающего есть некое устройство с компрессором и датчиком давления... И ему хочется за счет ШИМ регулятора управлять компрессором для поддержания стабильных показаний датчика... К сожалению оказалось, что в реале железо ведет себя не так, как он задумал... Крамолу в поведении макета автор предположил в работе таймера ( о чем и начальный вопрос задал)...
Вот там и проблемы искать надо. Таймер всего лишь честно тот ШИМ сигнал выдает, который ему указали. А вот принцип того,как определяются те "указания" и дает возникающие проблемы. Так что выясняйте, чего там с алгоритмами Вашего ПИД "не по бумажной теории"...
Не всё наоборот как раз получилось в протеусе стало плавно меняться в железе тоже только осталось дребезг с ацп убрать Интересно сколько раз ацп успевает замерить за 10 мс
там и дребезг с ацп убирали... с помощью гистерезиса... и синхронизацию делали через буферизацию... и там же измеряли сколько раз ацп успевает замерить... у нас 70 микросекунд измеряет ацп в Atmega8. и т.д. и т.д. Спойлер
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения