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

Приглашаем на вебинар «Инновационные технологии Analog Devices в области управления питанием» (11.08.2021)

В программе вебинара технология Silent Switcher® - сочетание высокого КПД и сверхмалого уровня ЭМИ, технология uModule® - высокоинтегрированные решения для источников питания, микро- и нанопотребляющие DC/DC-преобразователи, решения для резервного питания, цифровое управление системой питания (PSM), безоптронные изолированные обратноходовые преобразователи. В практической части вебинара будут продемонстрированы примеры работы с инструментами Analog Devices для проектирования источников питания.
Подробнее

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

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

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

Share this post


Link to post
Share on other sites

Концевые микропереключатели KLS – простая и надежная коммутация по оптимальной цене

На складе Компэл широко представлены нажимные переключатели от KLS в стандартных и миниатюрных корпусах с различными типами актуаторов. Микропереключатели серий KLS7-KW10 и KLS7-KW4-3Z соответствуют строгим стандартам электрической безопасности и эффективности, что гарантирует надежную коммутацию цепей управления.

Подробнее

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

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

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

Share this post


Link to post
Share on other sites

Датчики STMicroelectronics – новые возможности систем умного дома ST

Согласно прогнозам аналитиков, в ближайшие пару лет будет наблюдаться заметный рост рынка датчиков движения и положения для умного дома. Компания STMicroelectronics предлагает одну из самых широких линеек MEMS-датчиков, включая акселерометры, гироскопы, цифровые компасы, модули IMU, микрофоны и датчики параметров окружающей среды. Рассмотрим применение датчиков и тенденции их развития.
Подробнее

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

Share this post


Link to post
Share on other sites
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...

  • Сообщения

  • Similar Content

    • By Maxim Frantskevich
      Возникла проблема, не знаем как прошить STM8S003F3P6. Уже как только не пытались, кучи различных программ ставили, различными способами пытались подкопаться, всё равно выдаёт либо что не видит, либо просто некую ошибку. По поводу этих ошибок тоже сколько не копались, всё равно ничего. ST-Link рабочий, подключение хорошее. Нужно залить код для управления маленьким движком, чтобы выдавало либо +5В, либо -5В.
      Такое ощущение, что этот контроллер уже просто не поддерживается многими программами.
      Может кто-нибудь из вас знает что можно сделать, или как правильно прошить этот аппарат? Потому что уже кучу роликов на ютубе пересмотрели, форумов перечитали, никак не выходит. Получилось только сделать, чтобы программа увидела STM-ку.
      Благодарю за помощь)
    • By leonid1908
      Проявление неисправности: полное молчание, никакой реакции... Нигде ничего об этом пульте нет, хотя... на али экспрессе есть такой пульт, ну и цена тоже есть....



    • By Михаил Карнаухов
      В общем, во встроенных библиотеках Proteus нет МК PIC12F635. И мне нужна какая-нибудь сторонняя библиотека, что бы там был этот МК
    • By Sergey Krugov
      Доброго времени суток дня и ночи!!! Я конечно понимаю, что за это время уже успел надоесть вам, но прошу откликнуться к просьбе о помощи. 
      Проблема заключается в следующем:

      В данной схеме используется Atmega8
      Фьюзы:

      При симуляции схемы происходит следующее:


      А дальше ничего не происходит. 
      Возникает также проблема такого рода: 

      Почему-то Протеус ругается на это,  но при удалении этой строки из кода в Протеусе, схема начинает вроде бы работать, но дальше setup на ЖКИ ничего не появлется. Очень прошу помочь понять, что не так. Мб на железе это всё бы и работало. Как разрешить эту проблему в программе?
      Я буду очень благодарен всем, кто откликнется на мою проблему. Надеюсь вы не оставите это без внимания. Очень надеюсь...
×
×
  • Create New...