-
Вложений: 1
Генератор работы форсунок инжекторного двигателя
Создал - работает, но появилось несколько вопросов в программировании.
1. Есть ли вариант работать по ком-порту в фоновом режиме?
2. Аналогичный вопрос по работе с WH1602C?
3. Или как более лучший вариант - генерировать подобные импульсы в фоне?
В моем варианте забирается время на пересылку данных и оно не постоянно, из-за разного объема пересылки.
Пожалуйста, ткните носом где почитать или лучше где есть примеры. И еще, если не тяжело поправьте/укажите - где у меня в коде ошибки?
Вот рабочий вариант и видео с осциллографа. Типа параллельный впрыск.
PHP код:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
unsigned int pauza0, // Длительность паузы перед первым впрыском ( мкс )
vprysk1, // Длительность импульса первого впрыска ( мкс )
pauza1, // Длительность паузы перед вторым впрыском ( мкс )
vprysk2 ; // Длительность импульса второго впрыска ( мкс )
unsigned long pauza2, // Длительность паузы после второго впрыска ( мкс )
period ; // Период работы форсунки ( мкс )
void setup()
{
pinMode(49, OUTPUT); // Строб
pinMode(50, OUTPUT); // Форсунка № 1
pinMode(51, OUTPUT); // Форсунка № 2
pinMode(52, OUTPUT); // Форсунка № 3
pinMode(53, OUTPUT); // Форсунка № 4
//Serial.begin(115200);
//lcd.begin(16, 2);
}
void loop()
{
AnalogIn() ;
pauza2 = period - ( pauza0 + vprysk1 + pauza1 + vprysk2 + 1040 ) ;// Вычисление последней паузы
if ( pauza2 < 2 ) pauza2 = 2 ; // Не допускаем перекрытия
unsigned int pauzaMs = pauza2 / 1000 ; // Длительности последней паузы ( милисекунды )
unsigned int pauzaMk = pauza2 - ( pauzaMs * 1000 ) ; // Длительности последней паузы ( микросекунды )
Metka() ;
delayMicroseconds(pauza0);
ForsOpen() ;
delayMicroseconds(vprysk1);
ForsClose() ;
delayMicroseconds(pauza1);
ForsOpen() ;
delayMicroseconds(vprysk2);
ForsClose() ;
delay(pauzaMs);
delayMicroseconds(pauzaMk);
//LcdOut() ;
//SerialOut() ;
}
void ForsClose() // Закрытие форсунок
{
for (int i=50; i < 54; i++){
digitalWrite(i, LOW);
}
}
void ForsOpen() // Открытие форсунок
{
for (int i=50; i < 54; i++){
digitalWrite(i, HIGH);
}
}
void SerialOut() // Вывод данных по ком-порту
{
Serial.print("pauza0=");
Serial.print(pauza0);
Serial.print(" vprysk1=");
Serial.print(vprysk1);
Serial.print(" pauza1=");
Serial.print(pauza1);
Serial.print(" vprysk2=");
Serial.print(vprysk2);
Serial.print(" pauza2=");
Serial.print(pauza2);
Serial.print(" period=");
Serial.println(period);
}
void LcdOut() // Вывод данных на ЖКИ
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(pauza0);
lcd.setCursor(6, 0);
lcd.print(vprysk1);
lcd.setCursor(11, 0);
lcd.print(pauza1);
lcd.setCursor(0, 1);
lcd.print(vprysk2);
lcd.setCursor(8, 1);
lcd.print(pauza2);
}
void AnalogIn() // Чтение задающих параметров с потенциометров
{
period = map (analogRead(0), 0, 1023, 250000, 10000) ;
pauza0 = map (analogRead(1), 0, 1023, 1, 16200) ;
vprysk1 = map (analogRead(2), 0, 1023, 1, 16200) ;
pauza1 = map (analogRead(3), 0, 1023, 1, 5000) ;
vprysk2 = map (analogRead(4), 0, 1023, 1, 16200) ;
}
void Metka() //Стробирующий импульс ( 1 ms )
{
digitalWrite(49, HIGH);
delay(1);
digitalWrite(49, LOW);
}
Если бы еще для каждой форсунки отдельными циклами в фоне, то вообще получил бы наслаждение от изделия.
-
Re: Генератор работы форсунок инжекторного двигателя
Можно и форсунки сделать фоном и так, чтобы отправка данных в uart не влияла на форсунки. И даже данные выгружать в ЖКИ фоном.
Если нужна точность в единицы микросекунд, то придется забыть про написание в среде arduino. Нужно будет по таймеру работать с форсунками (я так понимаю, это единственное, что требует большой временной точности), потребуется библиотека uart, которая не выключает прерывание на заметное время. Затем на другой таймер повесить вывод в LCD, организовав буфер.
Во всех прерываниях, кроме таймера форсунок надо будет разрешать прерывания и аккуратно смотреть за временем выполнения обработчика прерывания.
Точно надо забыть про функцию digitalWrite, которая съедает единицы микросекунд.
-
Re: Генератор работы форсунок инжекторного двигателя
Цитата:
Сообщение от
SBorovkov
Можно и форсунки сделать фоном и так, чтобы отправка данных в uart не влияла на форсунки. И даже данные выгружать в ЖКИ фоном.
Если нужна точность в единицы микросекунд, то придется забыть про написание в среде arduino. Нужно будет по таймеру работать с форсунками (я так понимаю, это единственное, что требует большой временной точности), потребуется библиотека uart, которая не выключает прерывание на заметное время. Затем на другой таймер повесить вывод в LCD, организовав буфер.
Во всех прерываниях, кроме таймера форсунок надо будет разрешать прерывания и аккуратно смотреть за временем выполнения обработчика прерывания.
Точно надо забыть про функцию digitalWrite, которая съедает единицы микросекунд.
Спасибо за быстрый ответ.
Точность не нужна высокая, так как это не действующая система, а больше макет или даже стенд проверки, но вот девиации, скачков и прочего не хочется.
Среду Ардуино выбрал по причине моего желания позже заинтересовать сына к теме програмирования (пусть даже упрощенного), но только после моего самостоятельного детального изучения.
Как вариант думаю сделать этот генератор с применением прерываний, но сегодня, для меня там еще много вопросов. Содрать готовое не сложно, а вот разобраться и переделать уже готовый пример - это куда интересней. :)
Не подскажите ресурс по работе с таймерами под ХХХдуино, даже если и не для моего процика, наоборот закрепится лучше. Или может есть готовые библиотеки и подобные примеры? :cool:
Заранее спасибо.
-
Re: Генератор работы форсунок инжекторного двигателя
вот здесь пример быстрой работы с портами и с таймером http://www.compcar.ru/forum/showthread.php?t=5869
-
Re: Генератор работы форсунок инжекторного двигателя
Крыша пухнет, а разобраться так и не получилось... :eek:
Подскажите как в фоне общаться через ком-порт, а именно, чтение из порта данных?
-
Re: Генератор работы форсунок инжекторного двигателя
Цитата:
Сообщение от
Chip
И тут не все до конца разобрался...
У меня получается, что не возможно (наверно я просто не разобрался еще ) задать шим относительно высокой частоты и не дикретный, а плавный.
Я думал задавать 2 параметра длительности единицы и ноля, например: 60 мкс - единица и 40 мкс нолик, получается 10 кГц и скважность 60%, а как сделать так и не догнал.
Выручайте. :confused:
-
Re: Генератор работы форсунок инжекторного двигателя
Mastar, ты лезешь туда, где с кодом Arduino и его средой становится тесновато.
ШИМ на AVR микроконтроллерах можно создавать двумя способами:
1. аппаратный ШИМ. Создается только на определенных выводах и с некоторыми ограничениями. Читай мануал на atmega168/328 чтобы узнать какие ограничения существуют и как ШИМ программируется.
2. Софтверный ШИМ. В этом случае используется прерывание таймера и по таймеру выполняется нужная работа. Там тоже позникают ограничения, и на частоты и на то, что другой код не должен надолго блокировать работу прерываний.
С какой точностью в микросекундах тебе нужны импульсы? Точность в 1 мкс для нескольких каналов недостижима для софтверного ШИМ.
Думаю, максимум, во что можно уложиться будет примерно 1мкс+
1мкс*количество каналов. Это если забыть про среду arduino и считать такты в отладчике.
-
Re: Генератор работы форсунок инжекторного двигателя
По поводу чтения данных - родная библиотека uart наверняка использует прерывание прихода символа и по этому прерыванию записывает принятый символ в буфер. Тебе нужно в фоне не только принимать символы но и обрабатывать приходящую информацию?
По-момему обычно всю реально real-time работу выполняют по прерываниям. Приходящую информацию по относительно медленному com порту обычно можно обработать с небольшим запозданием. Поэтому такую работу как раз может быть лучше выполнять в основном цикле программы (разбирая скопившиеся в буфере данные).
-
Re: Генератор работы форсунок инжекторного двигателя
Как я писал ранее, эта моя затея предназначена для работы на столе и абсолютно не критичны единицы микросекунд. Думаю точность импульсов в 10-50 µs достаточна.
__________________________________________________ _______________________
На примере 4-х цилиндрового 4-х тактного двигателя и когда полный цикл работы всех цилиндров проходит за два оборота двигателя, есть несколько видов впрыска бензина:
Моно-впрыск - он ушел из жизни, как лампы из компьютеров. Не рассматриваем :) .
Параллельный - (тоже не стоит рассматривать, но они еще бороздят наши просторы, поэтому учтем)
- это когда, все четыре форсунки открываются одновременно через такт. При диапазоне оборотов 600...6000 об\мин, что равно 10...100 об\сек и соответственно период импульсов впрыска получается 100...10 ms, а время впрыска находится на этих "авто" в диапазоне 1...10 ms.
Тут исходные данные ( период = 100...10 ms, импульс = 1...10 ms ).
Попарный подобное паралельному, но через такт .
Тут исходные данные такие же ( период = 100...10 ms, импульс впрыска = 1...10 ms ), но есть варианты управления форсунками и до 20 ms.
Последовательный - это когда, каждый цилиндр получает именно свою порцию топлива, Получается, что при длительности периода импульсов, примерно Х.Х.(Холостого Хода = 600 rpm) бывает 2...4 ms и под нагрузой 20...30 ms, а на чипованных машинах встречается и 40 ms времени впрыска :(.
Тут нормальные исходные данные ( период = 200...20 ms, импульс впрыска= 2...20 ms ). На холостом можно и 50 ms задать, главное не попасть в постоянное открытие форсунок ;)
_______________________________________
Получается, что мне нужно формировать стабильные импульсы впрыска в диапазоне 1-40 ms с точностью, ну хоть в 10% и периодом до 200 ms с такой же точностью, но зто не мгновенные изменения оборотов(периода) или длительности впрыска , а типа выбора из меню диагностики и могут измениться, к примеру, раз в 300...500 ms.
_______________________________________
Задача №1. Генерация простых импульсов форсунок.
Задаем через ком-порт или по аналоговым входам с выводом на lcd? длительность впрыска и паузы до начала следующего впрыска, которая привязана к типу впрыска и периоду (оборотам).
Задача №2. Генерация сложных импульсов форсунок.
Задаем через ком-порт или по аналоговым входам с выводом на lcd длительность до-впрыска , затем паузы, потом основной впрыск, снова паузы, в конце экстра-впрыск и последняя пауза, которая отвечает за период(оборотов) всего пакета.
Задача №3. Генерация импульсов для тестирования низкоомных форсунок.
Задаем через ком-порт или по аналоговым входам длительность импульса накачки, потом длительности импульса удержания, который представляет собой аналог ШИМа с установленными из порта или аналоговыми параметрами( частоты и скважности ) и в коконце пауза.
Тут есть один момент в управлении форсунками...
Суть такова, что если для ускорения открытия форсунки приложить максимум напряжения (получим максимум скорости открытия), а потом для удержания форсунки использовать ШИМ и ток самоиндукции, то можно экономить на выделении тепла и затратам энергии, а по завершении импульса удержания, можно ускорить возврат форсунки в закрытое состояние, переведя ключевой каскад в 3-е состояние :) .
Примерный аналог ключа VN380, на него нужно на канал А подавать полный импульс открытия и на канал В подавать сигнал накачки с ШИМ-ом (5...20 кГц при скважности 20...80%, в зависимости от типа форсунок!). В этом ключе есть еще и диагностика на К.З., обрыв и и прочее. Это интересно, но наверно будет задачей № 22 :).
Задача №4 Полноценный распределенный впрыск
Аналог одноканального распределенного впрыска, но со смещением 1\4 периода на каждый цилиндр, с возможностью управления и до-впрысками и экстра-впрысками.
Тут проблема в том, что например, в цилиндре №1 еще не отработаны свои варианты, а в это время уже формируются импульсы в цилиндре №3 и т.д.
...................
Надо было мне сразу все озвучить в пером посту. :)
P.S. Я специалист в установке ГБО на автомобили VIP-класса и просто человек, который не хочет ставить фуфло, вот и постоянно изобретаю всякую фигню для тестов продаваемого оборудования и любезно делюсь наработанными и проверенными данными на форумах, типа CarHelp и GasHelp, зовут меня так же = Mastar (Mastylo Artur = Мастыло Артур)
Думаю теперь шпиёнов тут нет? :)
-
Re: Генератор работы форсунок инжекторного двигателя
Цитата:
Сообщение от
SBorovkov
Mastar, ты лезешь туда, где с кодом Arduino и его средой становится тесновато.........
Понимаю, но вариант "Учиться никогда не поздно!" это мне наверно не под силу, именно Ардуина заинтересовла своей видимой простотой. Я еще в начале этого века присел на LabView, не скажу, что в совершенстве освоил, но все свои "виндовые" и не шустрые приложения я делал там, а тут решил поближе подойти к МК, думал тут спасение :(.
Честно скажу, к низкоуровневым языкам - путь закрыт, мне проще взять 561 логику с добавлением 555 таймеров и сделать за час-другой подобное, но хочется именно с Ардуиной позаниматься.
Цитата:
Сообщение от
SBorovkov
Тебе нужно в фоне не только принимать символы но и обрабатывать приходящую информацию?
Нет, рассчитывать буду на ноуте и посылать готовые данные для генерации.
Но вот когда "закрываю крышку" должен работать в автономе с аналоговых портов, как в первом примере или при помощи LCD посредством кнопок.
Сейчас на компе отлавливаю изменение данных и только тогда отправляю в порт и сразу закрываю, притормаживает в момент самой передачи, но дальше работает в статике.
p.s. У меня планшетник, управляю генератором - пальцем. Удобно и показательно.
-
Re: Генератор работы форсунок инжекторного двигателя
Mastar, осознал задачи.
Такие вещи в идеале, конечно програмятся на ассемблере, но мы будем рассматривать шарообразный конь в вакууме (с) анекдот. Поэтому достаточно писать на С.
Итак, делим задачу на две - генерацию импульсов и подготовку данных для генерации импульсов. Пока рассматриваем первую задачу.
Чтобы подобное написать, надо запрограммировать таймер на выполнение каждые 100 мкс, к примеру. Для начала - можно и медленее запустить хоть раз в 10мс, растянув весь процесс во времени.
Затем создаешь комплект переменных для одной форсунки, в которых указываешь на какой вызов таймера эта форсунка должна потянуть за ножку, на какой - отпустить. В сложном случае - начиная с какого вызова и по какой - ШИМить и как шимить.
Таймер поступает просто - он с каждым вызовом увеличивает счетчик на 1 и выполняет все, что нужно выполнить для этого состояния счетчика - открывает форсунку, к примеру.
На этом этапе и со скоростью таймера 10мс тебе еще хватит ардуины. Когда будешь переходить на нормальную скорость таймера, придется уйти от некоторого кода arduino, заменив более быстрым аналогом.
Нужно продумать переменные для каждой форсунки, чтобы они были максимально независимыми.
К примеру переменные (не продумывал серьезно):
1. Длительность двух оборотов в вызовах таймера
2. Момент открытия форсунки после начала двух оборотов
3. длительность открытия форсунки
У этих переменных есть недостаток - нет возможности сообщить таймеру, что оборот начнется через 3 вызова таймера. Или начался 4 вызова назад.
-
Re: Генератор работы форсунок инжекторного двигателя
Цитата:
Сообщение от
SBorovkov
...
Чтобы подобное написать, надо запрограммировать таймер на выполнение каждые 100 мкс, к примеру
...
Хочется именно с этого момента и начать :).
Вот, как раз это и не получается у меня, не могу разобраться как заставить таймер тактировать именно 10 мкс.
Но тут палка о двух концах, если например обороты = 600 ( 200 мс! ), а импульс например 3 мс, то как быть с переполнением при отсчетах по 10 мкс? Ведь получается нужно 20000 отсчетов?
-
Re: Генератор работы форсунок инжекторного двигателя
Нашел кажись часть ответов на свои вопросы :)
В описании 16-bit Timer/Counter (Timer/Counter 1, 3, 4, and 5) , а я второй восьмибитный таймер мучаю.
Так правильно?
PHP код:
TCCR1A =((1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1));
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11); //устанавливаем предделитель на 8
OCR1A = 3000; // PB5, none
OCR1B = 3000; // PB6, OUT2
OCR1C = 3000; // PB7 OUT3
ICR1 = 200; // (16000000hz/8)/10000hz=200
и получаю свои желаемые 10 мкс, а благодаря 16-bit Timer/Counter переполнение будет происходить при 65 536 отсчетах.
-
Re: Генератор работы форсунок инжекторного двигателя
Вот эти строки
OCR1A = 3000
вызывают очень большое сомнение - OCR1B наверняка максимум 8-битный. Поэтому больше 255 туда записать не получится.
-
Re: Генератор работы форсунок инжекторного двигателя
Вот тебе код, который задает таймер на каждые 160 тактов. Правда в реальности по-моему не 160, а 159-161 такт. В среднем получается ровно 160.
Только я тебе говорю - пробовать надо на других скоростях - выстави таймер 60 раз в секунду. Для этого надо исправить
TCCR2B |= (1<<CS21) | (1<<CS20) | (1<<CS22);
чтобы делитель был 1024
и tcnt2=0 - чтобы считал до 256. Получится 16 000 000 / 1024/256=61 герц и экспериментируй. А потом уже можно будет оптимизировать для работы с реальной скоростью.
Просто 160 тактов - на обработку прерывания с серьезным дерганием ногами - очень мало.
Код:
#define tcnt2 251
void setup(void)
{
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
TCCR2B &= ~(1<<CS22); // эта и следующая строка задает таймер увеличение TCNT2 каждые 32 такта.
TCCR2B |= (1<<CS21) | (1<<CS20);
// tcnt2 = 251; 32 такта делителя * (256-251)=160 тактов. То есть каждые 10 мкс.
TCNT2 = tcnt2;
sei();
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2; // это вызывается каждые 160 тактов процессора.
}
-
Re: Генератор работы форсунок инжекторного двигателя
SBorovkov, подставил и получилось на выходе примерно 392 Гц, может это из-за того, что у меня проц 1280?
-
Re: Генератор работы форсунок инжекторного двигателя
Я на таком варианте пробовал
PHP код:
#define D13_High PORTB |=B10000000
#define D13_LOW PORTB &= B01111111
volatile unsigned int tcnt2 = 251; //32 такта делителя * (256-251)=160 тактов. То есть каждые 10 мкс.
volatile byte pwm_time;
void setup()
{ pinMode(13, OUTPUT);
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
TCCR2B &= ~(1<<CS22); // эта и следующая строка задает таймер увеличение TCNT2 каждые 32 такта.
TCCR2B |= ((1<<CS21) | (1<<CS20));
}
void loop()
{
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
pwm_time++;
if(pwm_time < 128) D13_High; else D13_LOW;
}
и получилась примерная частота при tcnt2
250 = 340 гц
251 = 390 гц
252 = 490 гц
253 = 660 гц
254 = 980 гц
и не понятно почему при 255 тоже 980 гц.
-
Re: Генератор работы форсунок инжекторного двигателя
Сейчас изменил
TCCR2B &= ~((1<<CS21) | (1<<CS22));
TCCR2B |= (1<<CS20);
Ура, я очень рядом.
Получилось при tcnt2 = 251 период 870 мкс, что равняется 870/256=3.6 мкс
Подбираю tcnt2 для моих 10 мкс.
Остался еще вопрос, какой быстрой командой обнулить или сбросить таймер?
Или просто для меандра частотой 1000 гц (100 * 10 мкс = 1 мс)
pwm_time++;
if(pwm_time < 49) D13_High; else D13_LOW;
if(pwm_time > 99) pwm_time = 0 ;
-
Re: Генератор работы форсунок инжекторного двигателя
Mastar,
1. я очень советую поставить Avr Studio. В ней определить частоту таймера - раз плюнуть. Ставишь брейк-поинт на попадание в прерывание и смотришь время между первым и вторым попаданием. Хочешь - в тактах, хочешь - в абсолютном времени. Для модификации этого проекта под avr studio надо будет добавить вначале пару include (дома посмотрю и напишу каких именно)
И дописать
void main(void)
{
setup();
for (;;)
Loop();
}
Как установить avr studio - смотри статью на easyelectronics.ru.
по второму вопросу:
Я рекомендую сделать именно
pwm_time++;
if(pwm_time < 49) D13_High; else D13_LOW;
if(pwm_time > 99) pwm_time = 0 ;
Это связано с тем, что тебе надо будет в одном таймере обсчитывать сразу несколько цилиндров. И проще для каждого попадания в таймер сделать полный набор проверок и при необходимости изменить состояние ног
//(очень упрощенный пример)
if(pwm_time < 49) D13_High; else D13_LOW; // первый цилиндр
if(pwm_time < 35) D12_High; else D12_LOW;// второй цилиндр
if(pwm_time < 79) D11_High; else D11_LOW; // третий цилиндр
if(pwm_time < 21) D10_High; else D10_LOW; // четвертый цилиндр
pwm_time++;
if(pwm_time > 99) pwm_time = 0 ;
Это сильно проще, чем вычислять время, через которое надо будет изменить состояние какой-либо ноги (особенно если заранее неизвестно в каком порядке меняется состояние ног).
-
Re: Генератор работы форсунок инжекторного двигателя
Цитата:
Сообщение от
Mastar
Я на таком варианте пробовал
PHP код:
#define D13_High PORTB |=B10000000
#define D13_LOW PORTB &= B01111111
volatile unsigned int tcnt2 = 251; //32 такта делителя * (256-251)=160 тактов. То есть каждые 10 мкс.
volatile byte pwm_time;
void setup()
{ pinMode(13, OUTPUT);
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
TCCR2B &= ~(1<<CS22); // эта и следующая строка задает таймер увеличение TCNT2 каждые 32 такта.
TCCR2B |= ((1<<CS21) | (1<<CS20));
}
void loop()
{
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
pwm_time++;
if(pwm_time < 128) D13_High; else D13_LOW;
}
и получилась примерная частота при tcnt2
250 = 340 гц
251 = 390 гц
252 = 490 гц
253 = 660 гц
254 = 980 гц
и не понятно почему при 255 тоже 980 гц.
Так все нормально!
Смотри сам: сам таймер вызывается каждые 10мкс. То есть 100 000 раз в секунду.
Ты на 256 вызовов таймера создаешь один период колебания ноги D13 (Vcc-Gnd).
То есть делим 100 000 на 256, получаем 390гц. Как у тебя и написано.
А вот TCNT2=255 не проходит потому, что таймер не успевает отработать до того момента, как процессор пытается его вызвать снова. При TCNT2=255 прерывание вызывается каждые 32 такта, а выполняется оно дольше, чем 32 такта.
-
Re: Генератор работы форсунок инжекторного двигателя
SBorovkov, спасибо. Реально подумал про avr studio, может тогда меньше будет тупых вопросов, но я тогда точно уйду от ардуины и процесинга :).
Сегодня наткнулся на пример с таймерами и там, прикольнула меня работа с avr studio. Сегодня - перезагрузка, avr studio начну пробовать. :)
-
Re: Генератор работы форсунок инжекторного двигателя
ардуину (саму плату) можно с удобством использовать как отладочную плату, особенно в сочетании с макетной платой с пружинными контактами.
Как запустить проект arduino среды в avr studio, я писал тут:
http://www.compcar.ru/forum/showthread.php?t=5910
Как зашить полученную прогу в arduino:
У меня среда arduino шьет следующей строкой:
E:\arduino-0021\hardware\tools\avr\bin\avrdude -CE:\arduino-0021\hardware/tools/avr/etc/avrdude.conf -q -q -patmega168 -cstk500v1 -P\\.\COM8 -b19200 -D -Uflash:w:c:\Temp\build4629811770678680876.tmp\sket ch_dec17a.cpp.hex:i
Поменяться в этой строке кроме путей могут:
-patmega168 это тип контроллера. В моем случае atmega168
-P\\.\COM8 - номер ком порта
Сам проверить не могу, поскольку сразу по получении заменил родной бутлоадер на другой, а перешивать туда-сюда его лень.
В avr studio тебе ничто не мешает по началу писать используя библиотеки arduino. Потом, я бы порекомендовал обратить внимание на библиотеку доступа к ногам контроллера. Супер библиотека. И ею можно пользоваться даже не понимая как она устроена.
тут описание http://easyelectronics.ru/rabota-s-p....html#more-339 . Можешь особо не разбираясь и не читая (если сложно) сразу в конце статьи скачать библиотеку. Там есть пара примеров к ней, сразу поймешь как пользоваться.
Единственное, в этой библиотеке оперируют не номерами контактов arduino платы, а стандартными портами avr контроллеров.
Соответствие можно посмотреть в файле
E:\arduino-0017\hardware\cores\arduino\pins_arduino.c
Если у тебя 1280 или 2560
// 0-7 PE0-PE7 works
// 8-13 PB0-PB5 works
// 14-21 PA0-PA7 works
// 22-29 PH0-PH7 works
// 30-35 PG5-PG0 works
// 36-43 PC7-PC0 works
// 44-51 PJ7-PJ0 works
// 52-59 PL7-PL0 works
// 60-67 PD7-PD0 works
// A0-A7 PF0-PF7
// A8-A15 PK0-PK7
-
Re: Генератор работы форсунок инжекторного двигателя
Вот код, который я тестировал в avr studio на предмет работы таймера
Код:
#include <avr/version.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint8_t tcnt2;
int main(void)
{
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
TCCR2B &= ~(1<<CS22); // эта и следующая строка задает таймер увеличение TCNT2 каждые 32 такта.
TCCR2B |= (1<<CS21) | (1<<CS20);
tcnt2 = 251; // 32 такта* (256-251)=160 тактов. То есть каждые 10 мкс.
TCNT2 = tcnt2;
sei();
for (;;);
}
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
}
-
Re: Генератор работы форсунок инжекторного двигателя
Спасибо за советы.
В понедельник утром остановился на варианте ниже
PHP код:
#define D22_High PORTA |=B00000001
#define D22_Low PORTA &= B11111110
volatile byte set[7] ;
volatile unsigned int tcnt2 = 206; //32 такта делителя * (256-206)=1600 тактов. То есть каждые 0,1 мс.
volatile unsigned int var = 1 ;
volatile byte pwm_time = 0 ;
void setup()
{
pinMode(22, OUTPUT);
pinMode(2, OUTPUT); // Давление топлива
pinMode(3, OUTPUT); // Давление в коллекторе
pinMode(4, OUTPUT); // Температура топлива
pinMode(5, OUTPUT); // Температура двигателя
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~((1<<WGM22) | (1<<CS22));
TCCR2B |= ((1<<CS21) | (1<<CS20));
ASSR &= ~(1<<AS2);
TIMSK2 |= (1<<TOIE2);
Serial.begin(9600);
}
void loop()
{
if(Serial.available() > 7)
{
if(Serial.read() == 255)
{
for(int i = 0; i < 7; i++)
{
set[i] = Serial.read(); // set[0] - Длительность импульса впрыска, Длительность паузы = set[1] + set[2] * 250
}
}
}
analogWrite(2, set[3]); // Давление топлива
analogWrite(3, set[4]);
analogWrite(4, set[5]); // Температура топлива
analogWrite(5, set[6]); // Температура двигателя
}
//************* прерывание *************
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
switch (var)
{
case 1:
pwm_time++;
if(pwm_time < set[0]) D22_High;
else
{
pwm_time=0;
var = 2 ;
}
break;
case 2:
pwm_time++;
if(pwm_time < set[1]) D22_Low;
else
{
if (set[2] > 0) var = 3; else var = 1;
pwm_time=0;
}
break;
case 3:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 1) var = 4; else var = 1;
pwm_time=0;
}
break;
case 4:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 2) var = 5; else var = 1;
pwm_time=0;
}
break;
case 5:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 3) var = 6; else var = 1;
pwm_time=0;
}
break;
case 6:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 4) var = 7; else var = 1;
pwm_time=0;
}
break;
case 7:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 5) var = 8; else var = 1;
pwm_time=0;
}
break;
case 8:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 6) var = 9; else var = 1;
pwm_time=0;
}
break;
case 9:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 7) var = 10; else var = 1;
pwm_time=0;
}
break;
case 10:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 8) var = 11; else var = 1;
pwm_time=0;
}
break;
case 11:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 9) var = 12; else var = 1;
pwm_time=0;
}
break;
case 12:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 10) var = 13; else var = 1;
pwm_time=0;
}
break;
case 13:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
pwm_time=0;
var = 1;
}
break;
}
}
Увеличил делитель и с точностью до 0.1 мс запустил. Провозился с командой For в таймере, но так и не понял где ошибаюсь, сделал тупо на Case и собрал в корпус.
Подскажите как лучше работать с двух-байтовыми значениями?
p.s. И еще при измерении реального импульса есть ошибка в 10 мкс, т.е. вместо 10,0 мс получается 9,99 мс, при 10,1 получается 10,09 мс и т.д.
Есть ли вариант добавить 0,01 мс ?
-
Re: Генератор работы форсунок инжекторного двигателя
А почему бы тебе не сократить время обмена с компьютером , всего то изменить скорость обмена на 115200
-
Re: Генератор работы форсунок инжекторного двигателя
Ставил и так и так Разницы не заметил в работе, но более высокая скорость чревата перебоями от помех, а их у меня на СТО - просто кошмар. :)