Делитель/умножитель ШИМ

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Опробовал в реальной работе это устройство. 8) :music:

Работает!

Пара косячков все равно есть. Ну, если можно так сказать.
1. Надо чуток подправить программу и плату, чтобы могла делить больше. Т.е. 8,5 коэффициент не достаточен. Надо будет сделать до 15. но это не сложно и вполне реализуемо.
2. Операционный усилитель все же надо пересчитать на большую чувствительность. Т.к. датчик АБС, сволочь, все равно при низкой скорости дает очень маленькую амплитуду. Со скорости в 40 км/ч уже показания нормально считываются. На настольном DDS-генераторе замерял работу, там ловил до 300 мВ. А в жизни, видимо, еще меньше надо.

З.Ы. Как-то надо оценить производительность микроконтроллера, чтобы все же добавить на ту же Атмега8 потенциометр. Т.к. регулировать им проще. Или может и оставить все как есть. Пока думаю. :dont_know:
Станислав
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Если АЦП читать без прерываний, а в основном цикле (где у вас как я понимаю пока ничего и не делается) - то вообще без проблем пот. поместится, т.к. читать его будете в свободные циклы.
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Думаю еще на плате поменять местами тантал и электролит... По входу питания лучше сразу электролит.
Станислав
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Делитель/умножитель ШИМ

Сообщение Ivanoff-iv »

повторю картинку: Изображение
чтобы повысить чувствительность надо снижать сопротивление R5.
но, мне иногда попадаются ОК датчики, которые не могут просадить линию ниже 0,5в, они так работать перестанут... (разве что джампер ставить, чтоб сопротивление можно было изменить)

Добавлено after 13 minutes 36 seconds:
про АЦП: NShtorm прав, это измерение практически не нагрузит АЛУ (если его правильно написать) правильно - это без делаев, прямо в том же цикле, где и деление/умножение:
иф (флаг завершения преобразования)
{забираем результат;
заводим следующее преобразование;};
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3817625#p3817625"]про АЦП: NShtorm прав, это измерение практически не нагрузит АЛУ (если его правильно написать) правильно - это без делаев, прямо в том же цикле, где и деление/умножение:
иф (флаг завершения преобразования)
{забираем результат;
заводим следующее преобразование;};[/uquote]

Так вот... у меня то прерывание, где происходит деление (умножение) вызывается каждые 12,8 мкс. А эти математические действия используют библиотеку с плавающей точкой. Не могу сказать, как быстро все это считается, т.к. библиотеку не я писал. Будет ли успевать укладываться в эти 12,8 мкс все и еще АЦП? Пока что без АЦП укладывается. И это при частоте 20 МГц на Тини2313. А если перенести на Атмегу8, то там максимум 16 МГц.

Добавлено after 1 minute 19 seconds:
З,Ы. А у вас нету как делать нормальные расчеты этой обвязки у операционника? )
Станислав
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

СКАЗОЧНИК, а вот зря вы математику в прерывании делаете... Ivanoff-iv выше предполагал, что математику вы делаете в основном цикле программы. И так действительно более правильно делать. Но если работает... можно пока и так оставить как есть. А вот АЦП вынести в основной цикл, как я уже и говорил.
На самом деле АЦП ведь конвертацию производит независимо. Всё что вам нужно - проверить регистр на отметку завершения преобразования и скопировать данные с другого регистра... Но вам еще нужно из этой цифры потом высчитать ваше коэф. - ну так делайте это в основном цикле. А не в прерывании.

Добавлено after 7 minutes 34 seconds:
PS: актуальная версия вашего варианта тут: https://radiokot.ru/forum/viewtopic.php ... 5#p3802875 ?
Или уже есть новее вариант?

EDIT: Вижу, что это не актуальный вариант, т.к. без float. Показывайте актуальный тогда.
И зачем вам какая-то библиотека для float, если он нативно поддерживается в avr-gcc?
Реклама
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

:oops:
Спойлер

Код: Выделить всё

#define F_CPU 20000000L  											// 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

unsigned int Counter = 0;
unsigned int Impuls = 0;
unsigned int Pause = 0;

char Flag = 0;
char DIV_MUL = 0;

float K = 1;

unsigned long int T1 = 0;
unsigned long int T2 = 0;

char END = 1;

int main(void)               
{
   	TCCR1B |= (1<<ICNC1)|(0<<ICES1)|(1<<CS12)|(0<<CS11)|(0<<CS10);	//Предделитель = 256, прерывание по спаду, подавитель помех
	TCCR0B |= (0<<CS02)|(0<<CS01)|(1<<CS00);						//Предделитель таймера0 = 1

	TIMSK |= (1<<TOIE1)|(1<<ICIE1)|(1<<TOIE0);						//Разрешить прерывание по захвату сигнала T1, Разрешить прерывания таймера0 по переполнению

	TCNT1 = 26473;
	TCNT0 = 0;

  	DDRD |= (0<<DDD6)|(0<<DDD5)|(0<<DDD4)|(0<<DDD3)|(0<<DDD2)|(0<<DDD1)|(1<<DDD0);   
	PORTD |= (1<<PORTD6)|(1<<PORTD5)|(1<<PORTD4)|(1<<PORTD3)|(1<<PORTD2)|(1<<PORTD1)|(1<<PORTD0);

	DDRB |= (0<<DDB7)|(0<<DDB6)|(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0);
	PORTB |= (1<<PORTB7)|(1<<PORTB6)|(1<<PORTB5)|(1<<PORTB4)|(1<<PORTB3)|(1<<PORTB2)|(1<<PORTB1)|(1<<PORTB0);
	
	unsigned int LOAD = 0;	

	LOAD = PINB;	

	if (!(LOAD & 0b10000000))										//Если кнопка нажата, придавлена к земле
	{
		DIV_MUL = 0;
	}
		else 
		{
			DIV_MUL = 1;
		}

	LOAD = ~LOAD;													//Скинуть старший бит в 0, чтобы не мешал

	K = ((LOAD & 0b01110000)>>4) + ((float)(LOAD & 0b00001111) / 10.0);

	wdt_enable(WDTO_1S);

	sei ();

//=========================
				while (1)
				{   
				   										 		//главный цикл программы     
				}       	
} 	     
//=========================

ISR(TIMER1_CAPT_vect)   											//оформление прерывания Т1 по захвату
{
	TCCR1B ^= (1<<ICES1);											//Исключающее ИЛИ переворачивает бит (меняем фронт)
	
	TCNT1 = 26473;
	
	Flag++;

	if (Flag==1)
	{
		Pause = Counter;											//Сохранили длину импульса
		Counter = 0;
	}
		else
		{
			Impuls = Counter;	
			Counter = 0;
			Flag = 0;
		}											
}

ISR(TIMER0_OVF_vect)												//Прерывание по переполнению Т0 каждые 12.8 мкс
{
	wdt_reset();

	Counter++;

		if (END==1)
		{
			if (DIV_MUL==0)
			{
				T1 = Impuls/K;
				T2 = Pause/K;
			}
				else
				{
					T1 = Impuls*K;
					T2 = Pause*K;
				}
			END = 0;
		}

		if (T1|=0)
		{
			PORTD &= ~(1<<PORTD0);
			T1--;
		}
			else if ((T1==0) && (T2|=0))
			{
				PORTD |= (1<<PORTD0);
				T2--;
			}
				else
				{
					PORTD &= ~(1<<PORTD0);
					END = 1;
				}
}


ISR (TIMER1_OVF_vect)
{
	Pause = 0;
	Impuls = 0;
//	PORTD ^= (1<<PORTD1);
}

Добавлено after 7 minutes 21 second:
:dont_know: Я не смог вынести в главный цикл вычисления...

Добавлено after 27 minutes 26 seconds:
З.Ы. Подключена у меня встроенна ЛИБС.А. libc.a

Добавлено after 1 minute 3 seconds:
И заняла она почти целый 1 кБ памяти МК
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Странное выражение if (T1|=0) , оно конечно работать будет, но лучше и проще записать if (T1) просто или хотя бы if (T1 != 0).
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

О блин... Вообще то я так и думал, что Т не равно нулю. Тупанул. И, ведь, не знаю, где я взял, что оно должно так быть написано. :facepalm:
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Как-то так можно, хотя мне многое не нравится еще:
Спойлер

Код: Выделить всё

#define F_CPU 20000000 L // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

volatile unsigned int Counter, Impuls, Pause;

volatile char Flag = 0;
char DIV_MUL = 0;

float K = 1;

volatile unsigned long int T1, T1buf, T2, T2buf;

volatile char END = 1;

int main(void) {
    TCCR1B |= (1 << ICNC1) | (0 << ICES1) | (1 << CS12) | (0 << CS11) | (0 << CS10); //Предделитель = 256, прерывание по спаду, подавитель помех
    TCCR0B |= (0 << CS02) | (0 << CS01) | (1 << CS00); //Предделитель таймера0 = 1

    TIMSK |= (1 << TOIE1) | (1 << ICIE1) | (1 << TOIE0); //Разрешить прерывание по захвату сигнала T1, Разрешить прерывания таймера0 по переполнению

    TCNT1 = 26473;
    TCNT0 = 0;

    DDRD |= (0 << DDD6) | (0 << DDD5) | (0 << DDD4) | (0 << DDD3) | (0 << DDD2) | (0 << DDD1) | (1 << DDD0);
    PORTD |= (1 << PORTD6) | (1 << PORTD5) | (1 << PORTD4) | (1 << PORTD3) | (1 << PORTD2) | (1 << PORTD1) | (1 << PORTD0);

    DDRB |= (0 << DDB7) | (0 << DDB6) | (0 << DDB5) | (0 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (0 << DDB0);
    PORTB |= (1 << PORTB7) | (1 << PORTB6) | (1 << PORTB5) | (1 << PORTB4) | (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0);

    unsigned int LOAD = 0;

    LOAD = PINB;

    if (!(LOAD & 0b10000000)) //Если кнопка нажата, придавлена к земле
    {
        DIV_MUL = 0;
    } else {
        DIV_MUL = 1;
    }

    LOAD = ~LOAD; //Скинуть старший бит в 0, чтобы не мешал

    K = ((LOAD & 0b01110000) >> 4) + ((float)(LOAD & 0b00001111) / 10.0);

    wdt_enable(WDTO_1S);

    sei();

    //=======
    while (1) {
        //главный цикл программы    
        if (Flag == 0) {
            if (DIV_MUL == 0) {
                T1buf = Impuls / K;
                T2buf = Pause / K;
            } else {
                T1buf = Impuls * K;
                T2buf = Pause * K;
            }
        }
    }
}
//=======

ISR(TIMER1_CAPT_vect) //оформление прерывания Т1 по захвату
{
    TCCR1B ^= (1 << ICES1); //Исключающее ИЛИ переворачивает бит (меняем фронт)

    TCNT1 = 26473;

    Flag++;

    if (Flag == 1) {
        Pause = Counter; //Сохранили длину импульса
        Counter = 0;
    } else {
        Impuls = Counter;
        Counter = 0;
        Flag = 0;
    }
}

ISR(TIMER0_OVF_vect) //Прерывание по переполнению Т0 каждые 12.8 мкс
{
    wdt_reset();

    Counter++;
    
    if (END) {
        T1 = T1buf;
        T2 = T2buf;
        END = 0;
    }

    if (T1) {
        PORTD &= ~(1 << PORTD0);
        T1--;
    } else if ((T1 == 0) && T2) {
        PORTD |= (1 << PORTD0);
        T2--;
    } else {
        PORTD &= ~(1 << PORTD0);
        END = 1;
    }
}

ISR(TIMER1_OVF_vect) {
    Pause = 0;
    Impuls = 0;
    //   PORTD ^= (1<<PORTD1);
}
Добавлено after 5 minutes 50 seconds:
Вот наверное еще для Impuls и Pause буферы сделать стоит и быстренько их просто копировать, чтобы исключить их изменение по прерыванию захвата во время математики float:
Спойлер

Код: Выделить всё

#define F_CPU 20000000 L // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

volatile unsigned int Counter, Impuls, Pause, Impuls_buf, Pause_buf;

volatile char Flag = 0;
char DIV_MUL = 0;

float K = 1;

volatile unsigned long int T1, T1buf, T2, T2buf;

volatile char END = 1;

int main(void) {
    TCCR1B |= (1 << ICNC1) | (0 << ICES1) | (1 << CS12) | (0 << CS11) | (0 << CS10); //Предделитель = 256, прерывание по спаду, подавитель помех
    TCCR0B |= (0 << CS02) | (0 << CS01) | (1 << CS00); //Предделитель таймера0 = 1

    TIMSK |= (1 << TOIE1) | (1 << ICIE1) | (1 << TOIE0); //Разрешить прерывание по захвату сигнала T1, Разрешить прерывания таймера0 по переполнению

    TCNT1 = 26473;
    TCNT0 = 0;

    DDRD |= (0 << DDD6) | (0 << DDD5) | (0 << DDD4) | (0 << DDD3) | (0 << DDD2) | (0 << DDD1) | (1 << DDD0);
    PORTD |= (1 << PORTD6) | (1 << PORTD5) | (1 << PORTD4) | (1 << PORTD3) | (1 << PORTD2) | (1 << PORTD1) | (1 << PORTD0);

    DDRB |= (0 << DDB7) | (0 << DDB6) | (0 << DDB5) | (0 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (0 << DDB0);
    PORTB |= (1 << PORTB7) | (1 << PORTB6) | (1 << PORTB5) | (1 << PORTB4) | (1 << PORTB3) | (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0);

    unsigned int LOAD = 0;

    LOAD = PINB;

    if (!(LOAD & 0b10000000)) //Если кнопка нажата, придавлена к земле
    {
        DIV_MUL = 0;
    } else {
        DIV_MUL = 1;
    }

    LOAD = ~LOAD; //Скинуть старший бит в 0, чтобы не мешал

    K = ((LOAD & 0b01110000) >> 4) + ((float)(LOAD & 0b00001111) / 10.0);

    wdt_enable(WDTO_1S);

    sei();

    //=======
    while (1) {
        //главный цикл программы    
        if (Flag == 0) {
            Impuls_buf = Impuls;
            Pause_buf = Pause;
            
            if (DIV_MUL == 0) {
                T1buf = Impuls_buf / K;
                T2buf = Pause_buf / K;
            } else {
                T1buf = Impuls_buf * K;
                T2buf = Pause_buf * K;
            }
        }
    }
}
//=======

ISR(TIMER1_CAPT_vect) //оформление прерывания Т1 по захвату
{
    TCCR1B ^= (1 << ICES1); //Исключающее ИЛИ переворачивает бит (меняем фронт)

    TCNT1 = 26473;

    Flag++;

    if (Flag == 1) {
        Pause = Counter; //Сохранили длину импульса
        Counter = 0;
    } else {
        Impuls = Counter;
        Counter = 0;
        Flag = 0;
    }
}

ISR(TIMER0_OVF_vect) //Прерывание по переполнению Т0 каждые 12.8 мкс
{
    wdt_reset();

    Counter++;
    
    if (END) {
        T1 = T1buf;
        T2 = T2buf;
        END = 0;
    }

    if (T1) {
        PORTD &= ~(1 << PORTD0);
        T1--;
    } else if ((T1 == 0) && T2) {
        PORTD |= (1 << PORTD0);
        T2--;
    } else {
        PORTD &= ~(1 << PORTD0);
        END = 1;
    }
}

ISR(TIMER1_OVF_vect) {
    Pause = 0;
    Impuls = 0;
    //   PORTD ^= (1<<PORTD1);
}
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Буду переносить на Атмегу8. Надо в устройство добавить пару функций, а памяти у Тини не хватает уже.
Заодно и добавлю АЦП и в главном цикле разберусь.

Спасибо за помощь. )

И мне скобочки фигурные все же по своему нравится делать. :beer:
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Немного поясню свои изменения. Только делал я их в "блокноте" - не проверял нигде, может неправильно работать - проверку оставляю вам )
Ну мелочи - вроде нет смысла определять переменную как 0, она и так будет равна 0.
1. Те переменные, которые меняются в прерывании, а используются в других местах - обязательно объявляем как volatile.
2. Копии переменных Impuls_buf, Pause_buf - чтобы исключить возможность того, что пока мы считаем float математику в главном цикле с их участием, произойдет новый захват и одна из них поменяется в процессе - получим мусор на выходе тогда.
3. Копии T1buf, T2buf - аналогично, чтобы выход не поменялся посреди процесса. Вот как только выход закончился, поднялся флаг END - вот тогда мы из них и скопируем сразу значения уже в T1, T2.

Скобочки ставьте как вам удобнее. Просто у вас форматирование съехало, местами трудно читать мне было. Поэтому прогнал через функцию автоформатирования редактора кода, она так расставила.

Добавлено after 1 minute 46 seconds:
PS: Хотя блоки else / else if в любых принятых стандартах форматирования ставятся на том же уровне отступа, что и if ранее.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Делитель/умножитель ШИМ

Сообщение Ivanoff-iv »

расчёт компаратора триггера Шмидта:
компаратор бывает только в 2х состояниях вкл и выкл, от этого и отталкиваемся - получаем 2 уровня (схема та же) R1 || R4 и R1 || R5 (я немного упростил) теперь надо рассчитать потенциал точки соединения этих трёх резисторов для обоих случаев (это и будут напряжения переключения триггера). получаем R4 тянет обе точки вверх, R5 - вниз, а R1 - раздвигает их друг от друга. теоретически можно вычислить точно их номиналы для строго заданных потенциалов, но то, что на выходе ОУ не ровно 0 и 5в, лишает эту затею смысла. т.ч. примерно прикидывай их сопротивления, а точно уже подбирай на плате...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

На плате точно тяжел подобрать... у меня нету генератора. И приходится ездить к другому человеку. ))) Миллион раз уже пожалел, что не купил себе DDS.
Станислав
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Делитель/умножитель ШИМ

Сообщение Ivanoff-iv »

тини на 20МГц в твоем случае будет медленнее чем мега на 16 т.к. у тини нет аппаратного блока умножения.
я обычно оцениваю загрузку АЛУ так: в протеусе подключаю фьюзами ногу ресет как обычный пин и по прерыванию, перед началом вычислений отправляю туда 1, а как только вычисления закончены - 0, а потом осциллографом смотрю скважность получившихся импульсов.
перед заливкой в реальный камень работу с ногой-ресет'ом сотри или закомментируй.

Добавлено after 2 minutes 21 second:
для настройки ОУ генератор не нужен, достаточно потенциометра и вольтметра.
можно или ловить момент переключения вольтметром или просто в обоих состояниях измерить напряжение в точке соединения R1,R4,R5.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Почему именно Резет? Есть же другие ноги свободные.

А идея интересная. !
Станислав
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Делитель/умножитель ШИМ

Сообщение NStorm »

Да тут не надо считать особо. Если вынести математику из прерываний, то пусть себе считает спокойно в свободные циклы. Оно и в прерывании успевало раньше. Ну расширится диапазон коэф. в 2 раза тут, максимум на 1 период опоздает значит расчет - что не важно, т.к. выход на прибор, на который глазами смотрят. Тут запаздывание на 1-2 периода не важно будет, незаметно.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Делитель/умножитель ШИМ

Сообщение Ivanoff-iv »

ресет? потому, что она намного реже других ног в проектах фигурирует, да и если подтереть забудешь, то это ничего в реальном железе не изменит (если ресет включен, то операции с регистрами этой ноги игнорируются)

Добавлено after 3 minutes 22 seconds:
заодео увидишь, укладывается ли вычисление в заданный интервал или часть прерываний пропускается...

Добавлено after 8 minutes 15 seconds:
кстати, а зачем флоат? результат его действий один фиг обратно к целочисленному приводить приходится
я сначала просто сделал умножение а потом деление (с запасом по разрядности) но потом посмотрел - дробная часть отсекается => выход всегда будет немного спешить...
поэтому я сделал накопитель, теперь отброшенная дробная часть в нём копится и корректирует выход. точнее одного отсчета всёравно вывод не сделать, но дробная часть накопившись до 1 будет иногда корректировать выходящий сигнал по фазе т.е. выходной сигнал будет немного ёрзать около правильной величины, а не уползать от неё в одну и ту же сторону.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Делитель/умножитель ШИМ

Сообщение СКАЗОЧНИК »

Целочисленная математика здесь слишком сложна для меня. ))))
Станислав
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Делитель/умножитель ШИМ

Сообщение Ivanoff-iv »

никто же не говорит дроби вычислять...
я думал просто: период_вых.=период_вх. * х / у
где х и у целые числа, взятые, например, со свободных портов...
если х>у получим замедление, если у<х - ускорение...
если 8 бит на переменную, то это до 256 раз (на 0 делить нельзя, а умножать бессмысленно) изменение скорости можно сделать как в ускорение, так и в замедление...
и пересчёт несложный: если было 3 импульса на метр, а стало 5, то так и вводим х=5, у=3 и всё...

Добавлено after 1 minute 46 seconds:
только важно, чтобы умножение было сделано раньше деления и переменную взять с учётом того что после умножения может получиться большое число. я для перемножения инт на коэффициент взял лонг переменную...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Ответить

Вернуться в «AVR»