Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя
Показано с 11 по 20 из 26
  1. #11
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию Re: Генератор работы форсунок инжекторного двигателя

    Mastar, осознал задачи.

    Такие вещи в идеале, конечно програмятся на ассемблере, но мы будем рассматривать шарообразный конь в вакууме (с) анекдот. Поэтому достаточно писать на С.

    Итак, делим задачу на две - генерацию импульсов и подготовку данных для генерации импульсов. Пока рассматриваем первую задачу.

    Чтобы подобное написать, надо запрограммировать таймер на выполнение каждые 100 мкс, к примеру. Для начала - можно и медленее запустить хоть раз в 10мс, растянув весь процесс во времени.

    Затем создаешь комплект переменных для одной форсунки, в которых указываешь на какой вызов таймера эта форсунка должна потянуть за ножку, на какой - отпустить. В сложном случае - начиная с какого вызова и по какой - ШИМить и как шимить.

    Таймер поступает просто - он с каждым вызовом увеличивает счетчик на 1 и выполняет все, что нужно выполнить для этого состояния счетчика - открывает форсунку, к примеру.

    На этом этапе и со скоростью таймера 10мс тебе еще хватит ардуины. Когда будешь переходить на нормальную скорость таймера, придется уйти от некоторого кода arduino, заменив более быстрым аналогом.

    Нужно продумать переменные для каждой форсунки, чтобы они были максимально независимыми.

    К примеру переменные (не продумывал серьезно):
    1. Длительность двух оборотов в вызовах таймера
    2. Момент открытия форсунки после начала двух оборотов
    3. длительность открытия форсунки

    У этих переменных есть недостаток - нет возможности сообщить таймеру, что оборот начнется через 3 вызова таймера. Или начался 4 вызова назад.

  2. #12
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    59
    Сообщений
    241
    Вес репутации
    214

    По умолчанию Re: Генератор работы форсунок инжекторного двигателя

    Цитата Сообщение от SBorovkov Посмотреть сообщение
    ...
    Чтобы подобное написать, надо запрограммировать таймер на выполнение каждые 100 мкс, к примеру
    ...
    Хочется именно с этого момента и начать .
    Вот, как раз это и не получается у меня, не могу разобраться как заставить таймер тактировать именно 10 мкс.
    Но тут палка о двух концах, если например обороты = 600 ( 200 мс! ), а импульс например 3 мс, то как быть с переполнением при отсчетах по 10 мкс? Ведь получается нужно 20000 отсчетов?

  3. #13
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    59
    Сообщений
    241
    Вес репутации
    214

    По умолчанию 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 отсчетах.

  4. #14
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию Re: Генератор работы форсунок инжекторного двигателя

    Вот эти строки
    OCR1A = 3000
    вызывают очень большое сомнение - OCR1B наверняка максимум 8-битный. Поэтому больше 255 туда записать не получится.

  5. #15
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию 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 тактов процессора.
    }

  6. #16
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    59
    Сообщений
    241
    Вес репутации
    214

    По умолчанию Re: Генератор работы форсунок инжекторного двигателя

    SBorovkov, подставил и получилось на выходе примерно 392 Гц, может это из-за того, что у меня проц 1280?

  7. #17
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    59
    Сообщений
    241
    Вес репутации
    214

    По умолчанию 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(13OUTPUT);    
        
    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 128D13_High; else D13_LOW

    и получилась примерная частота при tcnt2
    250 = 340 гц
    251 = 390 гц
    252 = 490 гц
    253 = 660 гц
    254 = 980 гц
    и не понятно почему при 255 тоже 980 гц.

  8. #18
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    59
    Сообщений
    241
    Вес репутации
    214

    По умолчанию 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 ;

  9. #19
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию 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 ;

    Это сильно проще, чем вычислять время, через которое надо будет изменить состояние какой-либо ноги (особенно если заранее неизвестно в каком порядке меняется состояние ног).

  10. #20
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию 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(13OUTPUT);    
        
    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 128D13_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 такта.

Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •