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

Вебинар «Новинки и решения Traco для промышленных и отраслевых приложений» (28.10.2021)

Компэл 28 октября приглашает всех желающих принять участие в вебинаре, где будет рассмотрена новая и перспективная продукция компании Traco. Мы подробно рассмотрим сильные стороны и преимущества продукции Traco, а также коснемся практических вопросов, связанных с измерением уровня шумов, промывкой изделий после пайки и отдельно разберем, как отличить поддельный ИП Traco от оригинала.
Подробнее

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

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

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

Share this post


Link to post
Share on other sites

Особенности вывода ключей PROFET+2 12V из состояния блокировки

Интеллектуальные ключи PROFET производства Infineon блокируют электрическую цепь в случае превышения допустимых параметров. Как ускорить их возврат в нормальное состояние в ответственных применениях, где это критически важно?

Подробнее

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

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

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

Share this post


Link to post
Share on other sites

Беспроводные интерфейсы умного проSTранства - преимущества и ограничения

При автоматизации больших территорий используются протоколы беспроводной связи ZigBee, BLE/Bluetooth, LoRaWAN, Sigfox, Thread, проприетарные протоколы 433/868 МГц и NFC. Компания STMicroelectronics предлагает для них приемопередающие модули и системы на кристалле, специализированные контроллеры, ИС для создания RFID-меток, а также экосистему из аппаратных и программных продуктов для разработки, отладки и поддержания работоспособности. Разберем подробно решения STMicroelectronics для передачи данных по этим протоколам.
Подробнее

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

Share this post


Link to post
Share on other sites

Реле TE Connectivity – надежная коммутация, доступная со склада Компэл

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

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...

  • Сообщения

    • При обрыве ремня возникает опасность опущения штанов. Для его временной замены предлагаю использовать обычную верёвку со скользящим узлом. Такой ремень прост в изготовлении, не содержит дефицитных материалов  и обеспечивает регулировку  степени натяжения без опасности её самопроизвольного ослабления. При необходимости  быстро снять или опустить штаны, для чего достаточно потянуть за узел и ведущий конец верёвки. Ниже показаны ослабленный и затянутый варианты верёвочного ремня, с двумя узлами, и ролик, в котором демонстрируется техника формирования этих узлов.  
    • Народ, че вы к BAFI  пристали? Он не знает как транзистор работает и откуда там "Миллер" берется. Не опускайте ниже плинтуса его. Просьбой что-то разработать. Все знают , что не сможет. Пусть живет своей звездной болезнью.  Он больной человек. Не трогайте больных.
    • Художественная фантазия - дело вкуса. Истина - дело принципа. Об этом  я и говорил.
    • Да не счесть. Миллионам наверное... https://sendle.ru/1432-bronza/174224056551-bronze-erotic-sexual-erotic-statues-sculpture-figurine-rare.html
    • В блог выложу - может быть - ес желание будет - те морочить голову мешать не буду) завтра не получиться -  я работаю, и те зачем? Читай тему с начала - там в начале полно всяких резонансов делали - авось что нить соберёшь - а то привык на все готовенькое) да *молодых* поучать) 
    • Может не стоит хренью форум наполнять? Оставишь при себе?! Или во - может как и задрот майоров заведешь канал на ютубе и там эту хрень будешь выкладывать?   Прикинь,  я тоже не слышал от "разумного" - "грит" А базаришь, так это повсюду говорят Ладно, думай Завтра посмотрим на твое детище

  • Мебельные петли с подсветкой (10шт)

  • Similar Content

    • By Эдик Ибрагимов
      Использовать микроконтроллер семейства 8951
       
    • 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...