Jump to content

Recommended Posts

22 minutes ago, Дмитрий Вас said:

speed тоже пришлось так обозвать

Значит, где-то в коде проблемы. Потому что если переменная не меняется внутри прерывания, объявлять ее волатильной не нужно.

Share this post


Link to post
Share on other sites
11 минут назад, Eddy_Em сказал:

Значит, где-то в коде проблемы.

какого рода могут быть проблемы? код выложен на предыдущей странице

без volatile переменную speed как будто не видит

Share this post


Link to post
Share on other sites

Приглашаем на вебинар «Экономичные решения МЕAN WELL для надежных разработок» (30.09.2021)

Компания Компэл приглашает 30 сентября на вебинар посвященный экономичным решениям МЕAN WELL. На вебинаре мы рассмотрим, как решения MEAN WELL позволяют сэкономить при выборе недорогого источника питания. Будут представлены основные группы источников питания по конструктивным признакам и по областям применения в контексте их стоимости или их особенностей, позволяющих снизить затраты на электропитание конечного устройства.
Подробнее

31 минуту назад, Дмитрий Вас сказал:

какого рода могут быть проблемы?

Возможно, у вас включена какая-нибудь оптимизация в настройках компилятора.
Вот он и умничает.

Share this post


Link to post
Share on other sites

Модульные RJ-соединители KLS — масштабное пополнение склада Компэл

Продуктовая линейка компании KLS на складе Компэл пополнилась модульными соединителями типа RJ. Ассортимент представлен неэкранированными соединителями RJ11, RJ12 и RJ45 для построения базовых информационных сетей, а также экранированными RJ45 с трансформатором для реализации систем передачи данных между узлами ЛВС.

Подробнее

2 минуты назад, LiVit сказал:

включена какая-нибудь оптимизация

конечно включена, -01, я думал она как бы обязательно

Share this post


Link to post
Share on other sites

Вебинар «Microchip и современный подход к искусственному интеллекту. Разворачиваем нейронную сеть на 32-битном микроконтроллере» (13.10.2021)

Приглашаем всех желающих 13 октября 2021 г. посетить вебинар, посвященный искусственному интеллекту, машинному обучению и решениям для их реализации от Microchip. Современные среды для глубинного обучения нейронных сетей позволяют без детального изучения предмета развернуть искусственную нейронную сеть (ANN) не только на производительных микропроцессорах и ПЛИС, но и на 32-битных микроконтроллерах. А благодаря широкому портфолио Microchip, включающему в себя диапазон компонентов от микроконтроллеров и датчиков до ПЛИС, средств скоростной передачи и хранения информации, возможно решить весь спектр задач, возникающий при обучении, верификации и развёртывании модели ANN.
Подробнее

А что за компилятор? Gcc даже с -O3 не будет "оптимизировать" настолько, что используемую переменную выбросит. Ее значение в прерываниях не меняется, так что все должно быть ОК.

Share this post


Link to post
Share on other sites

STMicroelectronics: электростатический разряд больше не проблема

Защита от статического электричества необходима каждому современному устройству. Компания STMicroelectronics представляет решения, соответствующие стандарту IEC61000-4-2, а также специальное приложение PROTECTION FINDER, которое поможет легкого и эффективно подобрать необходимые компоненты. Рассмотрим практические примеры защиты от ESD, отраслевые стандарты и ряд ключевых параметров важных при проектировании электростатической защиты устройств.
Подробнее

31 минуту назад, Eddy_Em сказал:

с -O3 не будет "оптимизировать" настолько,

оптимизировал еще сильнее , что даже volatile перестала помогать

полное отключение оптимизации помогло. но на сколько это правильно?

Share this post


Link to post
Share on other sites
5 часов назад, Дмитрий Вас сказал:

не этого я ожидал заходя на форум

А что Вы ожидали увидеть на единственную фразу "не заходит внутрь if, хотя Flag стоит в единице", без конкретики ?
Вот начали сами разбираться, выкладывать сюда результаты, рассуждать, ... И Вам помогли.

Запомните - тут нет экстрасенсов. Для помощи нужно больше информации. На фразу "у меня не работает код", Вы вряд ли получите тут адекватный ответ.

2 часа назад, Дмитрий Вас сказал:

оптимизировал еще сильнее , что даже volatile перестала помогать

Вы так говорите, как будто volatile - какая-то волшебная палочка от глюков :)
volatile не может от чего-то помогать. Почитайте в интернете про этот квалификатор и выясните, почему Ваш код с ним работает, а без него - нет. Не нужно его тыкать теперь везде, где не попадя ...

Share this post


Link to post
Share on other sites
1 час назад, Alex сказал:

Почитайте в интернете про этот квалификатор

сразу так и сделал, но 

 

5 часов назад, Eddy_Em сказал:

Потому что если переменная не меняется внутри прерывания, объявлять ее волатильной не нужно.

Flag_IT_timer тоже считаю объявлять ей не нужно. но такой совет поступил. и результат имел место быть

Share this post


Link to post
Share on other sites
2 часа назад, Дмитрий Вас сказал:

сразу так и сделал

И что интересного вычитали про него ? Расскажите.

2 часа назад, Дмитрий Вас сказал:

Flag_IT_timer тоже считаю объявлять ей не нужно

Аргументируйте.

Share this post


Link to post
Share on other sites
Posted (edited)
3 hours ago, Дмитрий Вас said:

Flag_IT_timer тоже считаю объявлять ей не нужно.

В отличие от других переменных, эта меняется внутри прерывания. Но т.к. явно функция-обработчик прерывания не вызывается, gcc считает, что переменная абсолютно всегда равна нулю. Вот и оптимизирует. Поэтому и нужно ее (и ТОЛЬКО ЕЕ) объявлять как volatile.

Ах, да! Чего я все gcc, да gcc? Судя по описанным косякам, там не gcc, а какой-то кусок большого Г! Либо у кого-то руки откуда-то не оттуда растут...

Edited by Eddy_Em

Share this post


Link to post
Share on other sites
Posted (edited)
1 час назад, Alex сказал:

Аргументируйте.

использую два таймера, таймер1 для крутилки энкодера в качестве антидребезга. таймер0 для плавного пуск/стоп/реверс. крутилка работает отлично на каждый щелчок энкодера, переменная speed увеличивается/уменьшается на 10. и не требует volatile. в то время как проверка флага таймера0 не проходит 1277427705_0.jpg.6f4d04fd9b858e9d94dfd4886a1cf585.jpg1363791903_1.jpg.09eda80adfcac27658f4dc689ca49d76.jpg 

да она используется внутри цикла for но это не говорит о том что проверка не должна проходить.

Edited by Дмитрий Вас

Share this post


Link to post
Share on other sites
19 минут назад, Дмитрий Вас сказал:

да она используется внутри цикла for но это не говорит о том что проверка не должна проходить.

Конечно не говорит. for тут совсем не при чём.

Давайте посмотрим со стороны на поведение компилятора.
Вот он находит объявление некой переменной (в Вашем случае - флаг). Находит его инициализацию. Вероятнее всего, Вы проинициализировали его нулём. Дальше, анализируя определённую единицу кода, он сталкивается с условием проверки этой переменной на true. Как Вы думаете, что он сделает ? Правильно - вырежет нахрен этот код, ибо он не нашёл в этой единице кода какие-либо изменения этой переменной.
Вы с ним не согласны ?

Share this post


Link to post
Share on other sites
Только что, Alex сказал:

Вероятнее всего, Вы проинициализировали его нулём.

нет, без какого то конкретного значения, но по умолчанию да это ноль.

 

1 минуту назад, Alex сказал:

вырежет нахрен этот код, ибо он не нашёл в этой единице кода какие-либо изменения этой переменной.

не понял.

можете сами проверить, нужно просто скопировать и вставить. 

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
//#define button (!(PIND&(1<<5)))
unsigned char Flag_IT_timer0;
unsigned char button_time;
unsigned char button_long;
unsigned char button_shot;
short speed;
int button;
void port_ini (void)
{
	//усилитель
	DDRB&=~(1<<3)|(1<<4);//вход усилителя для измерения тока
	//ЛСД
	DDRC|=((1<<4)|(1<<5)|(1<<6)|(1<<7));
	DDRB|=((1<<2)|(1<<5));
	//ШИМ
	DDRD|=(1<<0);DDRC|=(1<<0);
	DDRB|=((1<<0)|(1<<1)|(1<<6)|(1<<7));
	//энкодер
	DDRD&=~(1<<5)|(1<<6)|(1<<7);
	PORTD=(1<<5)|(1<<6)|(1<<7);
}
void start(void)//плавный старт
{
	for (;speed<=400;)
	{
		if (Flag_IT_timer0 == 1)
		{
			Flag_IT_timer0 = 0;
			speed++;	
		}
	}
	// подключаем выходы генератора сигнала PSC к выходам порта
	//PSOC0 = (1 << POEN0B) | (1 << POEN0A);
	//PSOC1 = (1 << POEN1B) | (1 << POEN1A);
	//PSOC2 = (1 << POEN2B) | (1 << POEN2A);
}
void revers (void)
{
	int s_new;
	if (speed>0)
	{
		s_new = ~speed + 1;
		for (;speed>=s_new;)
		{
			if (Flag_IT_timer0)
			{
				Flag_IT_timer0 = 0;
				speed--;
			}
		}
	}
	if (speed<0)
	{
		s_new = ~speed + 1;
		for(;speed>=s_new;)
		{
			if (Flag_IT_timer0)
			{
				Flag_IT_timer0 = 0;
				speed++;
			}
		}
	}
}
void stop (void)// стоп
{
	for(;speed>=0;)
	{
		if (Flag_IT_timer0)
		{
			Flag_IT_timer0 = 0;
			speed--;
		}
	}
	for(;speed<=0;)
	{
		if (Flag_IT_timer0)
		{
			Flag_IT_timer0 = 0;
			speed++;
		}
	}
	// отключаем выходы генератора сигнала PSC к выходам порта
	//PSOC0 &=~ (1 << POEN0B) | (1 << POEN0A);
	//PSOC1 &=~ (1 << POEN1B) | (1 << POEN1A);
	//PSOC2 &=~ (1 << POEN2B) | (1 << POEN2A);
	
}
void Timer_init(void)
{
	//инициализация энкодера содержит настройки таймера 1
	TCCR1A = 0x00;
	TCCR1B |= (1<<CS11);            // делитель на 8
	TCNT1 = 0;                    // Обнуляем счетный регистр
	OCR1A=250;                    // Настраиваем регистр сравнения 100 раз в секунду
	//CS12	CS11	CS10
	//0		0		0	нет тактирования
	//0		0		1	/1
	//0		1		0	/8
	//0		1		1	/64
	//1		0		0	/256
	//1		0		1	/1024
	//1		1		0	External clock source on T1 pin. Clock on falling edge.
	//1		1		1	1 External clock source on T1 pin. Clock on rising edge.
	// Разрешаем прерывание таймера по совпадению с OCR1A
	TIMSK |= (1<<OCIE1A);
}
ISR(TIMER1_COMPA_vect)
{
	Flag_IT_timer0 = 1;
	TCNT1=0;                    // Обнуляем счетчик
}
int main(void)
{
	DDRB=0b11111101;
	PORTB=0b00000010;
	Timer_init();
	sei();
	while (1)
	{
		if (Flag_IT_timer0)
		{
			Flag_IT_timer0=0;
			if(button)
			{
				button_time++;
			}
		}
		//---------------------работаем вне таймера 1 с результатами энкодера------------
		if (!button && button_time>200)//т.к. таймер срабатывает 100 раз в сек. то 200 будет = 2с
		{
			
			button_time = 0;
			button_long = 1;
		}
		if (!button && button_time > 0 && button_time < 200)
		{
			button_time = 0;
			button_shot = 1;
		}
		if (button_shot && speed==0)//первое короткое
		{
			start();
			button_shot = 0;
		}
		if (button_shot)//любое другое короткое нажатие
		{
			revers();
			button_shot = 0;
		}
		if (button_long)
		{
			stop();
			button_long = 0;
		}
	}
	
}


 

Share this post


Link to post
Share on other sites
14 минут назад, Дмитрий Вас сказал:

не понял.

// Тут где-то Flag_IT_timer0 = 0

int main(void)
{
	DDRB=0b11111101;
	PORTB=0b00000010;
	Timer_init();
	sei();
	while (1)
	{
		if (Flag_IT_timer0) // Вот до сюда дошёл анализатор компилятора. До этого момента, переменная Flag_IT_timer0 не модифицировалась. Что ему делать ?
		{
			

 

Share this post


Link to post
Share on other sites
Только что, Alex сказал:

// Вот до сюда дошёл анализатор компилятора. Что ему делать ?

но тут можно задать значение и я его задаю ставлю в единицу

Share this post


Link to post
Share on other sites

Вы плохо прочитали мой предыдущий пост. Я говорил о компиляторе и о его действиях. А не то, что Вам писать в коде.
Посмотрите со стороны компилятора на свой код. Даже не на весь. А на кусок, который я выложил.

Share this post


Link to post
Share on other sites

@Alex я понял о чем вы говорили, но ведь в процессе отладки можно задать значение любой переменной, вот я и задал его как = 1.

Share this post


Link to post
Share on other sites

Причём тут отладка ?
Вы меня не поняли. Почитайте повнимательней.

Share this post


Link to post
Share on other sites

Понял, компилятор с отладчиком перепутал. Ок почему он так делает? Потому что таймер работает только в железе? Разве в отладке не работает? 

Share this post


Link to post
Share on other sites
3 часа назад, Дмитрий Вас сказал:

Ок почему он так делает?

Потому, что Вы сами его заставили это делать.

Share this post


Link to post
Share on other sites
22.06.2021 в 12:23, Дмитрий Вас сказал:

конечно включена, -01, я думал она как бы обязательно

Я никогда не включаю оптимизацию. Потому что мне не известно, как компилятор себя поведет.
Однажды только пришлось - код в память не лез. 

А вам тем более не стоит лазить ручками в такие тонкости. Вот годика через три ежедневного программирования, и если код в память не лезет - тогда можно присмотреться к оптимизации.

Share this post


Link to post
Share on other sites
22.06.2021 в 22:07, Alex сказал:

До этого момента, переменная Flag_IT_timer0 не модифицировалась. Что ему делать ?

почему не модифицировлась?

24.06.2021 в 15:04, LiVit сказал:

А вам тем более не стоит лазить ручками в такие тонкости. Вот годика через три ежедневного программирования, и если код в память не лезет - тогда можно присмотреться к оптимизации.

выключаю оптимизацию получаю мильон ошибок, и гугл не может с ними помочь.

 

эрор.jpg

Share this post


Link to post
Share on other sites

Здравствуйте, друзья. Сто лет сюда не писал, так как не очень занимался программированием, и все забыл.
Есть светодиодная линейка, в которой куча микросхем 74HC595, всего 256 диодов. Как мне создать такую функцию, чтобы передавать ей число от 0 до 255, и она выводила это число на линейку? Линейка разбита на восемь плат по 32 диода. Сейчас я делаю это так:

IndikatorReset (); // резет 
Latch (); // задвижка


void indOut(int numPLT, uint32_t data) 
{
	IndikatorReset();

	for (int i = 1; i <= numPLT * 32; i++)
	{
		INDCLK_LOW();
		if ((data & 0x80000000) == 0x00)
		{
			INDDATA_LOW();
		}
		else
		{
			INDDATA_HIGH();
		}

		INDCLK_HIGH();
		data = (data << 1);
	}
	Latch();
}

Да, это работает, но я понимаю что это не оптимальный вариант. Во-первых, использую 32х битное число, не рационально. Во-вторых, надо сделать динамическую индикацию, чтобы в один момент на каждой из восьми плат засвечивался только один диод, потому что жрут они очень много энергии.
Я уже неделю ломаю голову над этой платой, и видимо моего мозга недостаточно для решения этой задачи. Прошу помощи и сильно не гневаться, я начинающий))

Share this post


Link to post
Share on other sites
Posted (edited)
3 hours ago, si4karuk said:

засвечивался только один диод

Я бы сделал массив из восьми чисел uint8_t plate[8], по одному числу для каждой платы. В каждую ячейку массива положил бы номер диода для зажигания, а потом бы в цикле проверял какой диод зажечь. Если положили 0, то никакой диод не включается.

Наверно и IndikatorReset() не нужен, потому что все регистры обновляются всякий раз.

IndikatorReset (); // резет 
Latch (); // задвижка

uint8_t plate[8]; 

main()
{
...
  plate[0] = 1;  //зажечь первый диод
  plate[1] = 22; //зажечь двадцать второй диод
  plate[2] = 32; //и т.д.
  plate[3] = 0;
  plate[4] = 5;
  plate[5] = 17;
  plate[6] = 14;
  plate[7] = 7;
  indOut();
...
}

	
void indOut() 
{
    uint8_t tmp;

    for(int numPLT = 0; numPLT < 8; numPLT++)
    {
        tmp = 1;
        for (int i = 0; i < 32; i++)
        {
            INDCLK_LOW();

            if (plate[numPLT] == tmp)
            {
                INDDATA_HIGH();
            }
            else
            {
                INDDATA_LOW();
            }

            INDCLK_HIGH();
            tmp8++;
        }
    }

    Latch();
}

 

Edited by Yurkin2015

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Это в дежурки , которая? Снаббером скорее перегрузил. По схеме чет я не нашёл защиту от перегрузки..
    • @rahimov08 , если вас в университете действительно готовят на инженера, то вам должны были рассказать, что прежде чем бросаться что-то трясти, инженер должен подумать. Ну то, что скважность не в микросекундах, а безразмерная, это вам потом преподаватель надеюсь скажет, но даже если предположить, что это длительность импульса, задание всё равно нужно уточнить. Изменяется с каким дискретом? С какой точностью? Или вообще изменяется непрерывно (сервопривод, всё-таки...)? В зависимости от ответа на эти вопросы в задании меняется всё. И схемотехника, и даже принципиальная возможность реализовать на МК. А помочь вам - вообще безнадёжно. У вас в задании указано: Что считать будем?  
    • Ежу понятно, что схема не от Вашего стабилизатора. Ищите родную схему.
    • Если конденсаторный, т.е. статический то как выше. Тонкая пленка - диэлектрик между пластинами. Толстая - между конденсаторами. Конденсаторы соединить параллельно и подавать частоту. Пружина закреплена на стержне будет прижимать бутерброд к основанию. Роль пружин будет исполнять и пленка. Допустим, толщина 1 конденсатора 0.1 мм. По 20 мкм фольга и 60 мкм изолятор. И 100 мкм толщина слоя между конденсаторами. Вместе 0.2 мм. Диаметр 50 мм. Считал в онлайн-калькуляторе емкость 289.6795пФ. Энергия хранимая в нем при 1000В (если не пробъет) 0.00000145 Дж (1.45 мкДж). Допустим, частота 1000 Гц, через такой конденсатор пройдет 1450 мкДж или 1.45 мДж. Чтобы набрать мощность 1.45 Дж, надо в 1000 раз больше, т.е. 0.2*1000=200мм или 20 см. Вывод. 20 см/1000Гц/1000V/1.45W /50mm. Наверное, что 1000V да 1000 Гц это гарантированный пробой даже приличной пленки. Не говоря уже о том, что размеры пленки должны быть не 50 мм, а намного больше, чтобы исключить пробой по воздуху/клею. Клей взять эпоксидный прикинуть слой клея 10 мкм, тогда слой изолятора 50 мкм/90 мкм Допустим, что частота 30 кГц, можно передать около 30W. Нужен ток около 30mA И как можно допридумать, чтобы заработало?
    • Здравствуйте, уважаемые форумчане. В одном из своих проектов столкнулся со следующей проблемой. Необходимо реализовать эффект заполнения светодиодной полосы (как полоса загрузки). В ходе поиска в интернете чего-то подобного нашёл схему плавного розжига светодиодов на n-канальном мосфете и rc цепочке и решил, что если последовательно включить такую схему, то для моих целей это идеальный вариант. Но, столкнулся с рядом проблем (схема на фото во вложении).  1) Собирая данную схему на макетной плате, я уже был готов к тому, что загорится только 1й светодиод. Но, почему-то, загораются все разом (без задержек и плавного розжига)  2) Перед тем как покупать мосфеты, проверил эту схему в крупном масштабе на реле (но щелкание десятка реле это совсем не камильфо в моём устройстве), всё работало как нужно с 2мя "Но". Первое - не было плавного розжига (само собой, это понятно). Второе - вместо керамических конденсаторов я использовал электролитические. (Может ли выбор конденсаторов влиять на rc цепь?) 3) оставил полоску светодиодов гореть на некоторе время и заметил, что часть диодов периодически то погаснет, то начинает гореть тусклее. Никакой системы не проглядывается, при этом, светодиоды не перегарают. При выключении/включении снова загораются все и горят нормально.  Направьте, пожалуйста, в нужном направлении. Как победить данную проблему, чтобы всё работало так, как нужно?   P.S. Крайне желательно, чтобы диоды остались так же независимы друг от друга. Каждый из них со своей схемой должен будет размещаться на отдельной плате 17х25мм(максимум) с возможностью увеличить/уменьшить количество этих плат на конечном устройстве (рекламный стенд).    Upd.: PPS. У первого мосфета забыл дорисовать конденсатор, но он там должен быть.   
    • Повторю ответ... Думаю, вы всё поняли теперь..
  • Similar Content

    • By Илья1964
      Нужен специалист, ориентирующийся в MotionLab3 для настройки серводрайвера EVEREST XCR ETHERCAT SERVO DRIVE (EVE-XCR-E) от компании INGENIA для привода отечественного BLDC (0,7 кВт). Энкодер магнитный от компании RLS. Мануал с описанием MotionLab3 можно скачать здесь https://doc.ingeniamc.com/mot3/documentation/motionlab3-user-manual, сам пакет здесь https://doc.ingeniamc.com/mot3/downloads  .  BLDC сидит на оси  линейного перемещения и должен вращаться влево-вправо. Никаких особых хитростей в движении мотора нет.
    • By Klumjuk
      Добрый день! Никак не могу найти резистор R97 на плате бумбокса. Можете определить на фото, либо как-нибудь объяснить мне, где он...
      Вот фотка основной платы,и платы зарядки.
      (На основной плате обозначен контролер заряда,если что)


    • By Klumjuk
      Сгорел контроллер питания в колонке, батарейка 7.4 вольта. Помогите подобрать такой же контролер, либо аналог. Весь интернет обрыл,ничего не нашёл (

    • By Иванов Владимир
      Здравствуйте! Я профан в этой теме, но по работе нужно. Хочу собрать так скажем приёмник на микроконтроллере, чтоб демодулировал сигнал. Сигнал собираюсь подавать с компа. Типо на мк подключённый к компу послать модулированный сигнал. Задача в том чтоб запрограммировать сам мк на демодуляцию. Какой мк и отладочную плату посоветуете?
×
×
  • Create New...