Перейти к содержанию

Вопросы от начинающих по МК


Рекомендуемые сообщения

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

  • Ответов 8,9т
  • Создана
  • Последний ответ

Топ авторов темы

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

Ссылка на комментарий
Поделиться на другие сайты

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

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

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

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

1 час назад, Alex сказал:

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

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

 

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

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

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

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

3 hours ago, Дмитрий Вас said:

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

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

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

Изменено пользователем Eddy_Em
Ссылка на комментарий
Поделиться на другие сайты

1 час назад, Alex сказал:

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

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

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

Изменено пользователем Дмитрий Вас
Ссылка на комментарий
Поделиться на другие сайты

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

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

Только что, 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;
		}
	}
	
}


 

Ссылка на комментарий
Поделиться на другие сайты

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

не понял.

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

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

 

Ссылка на комментарий
Поделиться на другие сайты

Только что, Alex сказал:

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

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

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

22.06.2021 в 12:23, Дмитрий Вас сказал:

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

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

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

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...
22.06.2021 в 22:07, Alex сказал:

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

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

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

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

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

 

эрор.jpg

Ссылка на комментарий
Поделиться на другие сайты

Здравствуйте, друзья. Сто лет сюда не писал, так как не очень занимался программированием, и все забыл.
Есть светодиодная линейка, в которой куча микросхем 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х битное число, не рационально. Во-вторых, надо сделать динамическую индикацию, чтобы в один момент на каждой из восьми плат засвечивался только один диод, потому что жрут они очень много энергии.
Я уже неделю ломаю голову над этой платой, и видимо моего мозга недостаточно для решения этой задачи. Прошу помощи и сильно не гневаться, я начинающий))

Ссылка на комментарий
Поделиться на другие сайты

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();
}

 

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

03.07.2021 в 12:44, Дмитрий Вас сказал:

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

Чтота эта... гугл и правда не мог помочь? Даже гугл-переводчик? Ну, он же прямым текстом написал: секция .text переполнена на 2 с лишним килобайта... все остальные ошибки - связанные с этим событием. Без оптимизации у вас прошива в память не лезет... в какую, правда, непонятно. может, констант слишком много накидали?

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Доброго времени суток уважаемые форумчане. Возникла маленькая проблемка (для профи скорее всего даже смешная)...

Суть вопроса, как сделать на ардуинке вот такое: При нажатии на кнопку загорается поочереди 8 светодиодов с интервалом в 0.75 секунды и продолжают гореть 2 минуты и потом так же гаснут поочереди с интервалом в 0.75 секунды. Причем самое главное кнопку кратковременно нажал и отпустил (Везде практически есть нажал горит отпустил потух....) а мне именно нужно нажал-отпустил и запустил протокол зажигания и горения в течении 2 минут всех. После выключения всех светодиодов  чтоб с начала стартовала программа ожидания нажатия кнопки...

Набросал скетч так он мне при нажатии запускает сразу все светодиоды и поочереди их выключает с интервалом в 2 секунды... причем если нажать и отпустить то все загорятся и сразу потухнут... если снова нажать продолжат выключатся с последнего потухшего в прошлый раз светодиода и когда все потухнуть больше уже не реагирует ничего на эти кнопки.... причем у меня вместо кнопки датчик пересечения линии, но смысл посути как у тактовой кнопки... этот датчик выдаёт все время 5 вольт информационных, а при пересечении 0 вольт. Но в скетче в условии считывания ставлю LOW или HIGH но срабатывает одинаково почемуто...

Скетч (100% неправильный скорее всего):

Скрытый текст

 

void setup()
{
  pinMode (2, OUTPUT); //Выходы
  pinMode (3, OUTPUT);
  pinMode (4, OUTPUT);
  pinMode (5, OUTPUT);
  pinMode (6, OUTPUT);
  pinMode (7, OUTPUT);
  pinMode (8, OUTPUT);
  pinMode (9, OUTPUT);

  pinMode (11, INPUT); //Вход 11 пин
  pinMode (12, INPUT);  //Вход 12 пин
//digitalWrite (11, HIGH); //Подтяжка
//digitalWrite (12, HIGH); //Подтяжка
}

void loop() {
 
  if (digitalRead(11) == LOW  || digitalRead(12) == LOW) // если любая кнопка нажата
  {
    digitalWrite (2, HIGH); //Зажигаем огни
    delay (2000);
    digitalWrite (3, HIGH);
    delay (2000);
    digitalWrite (4, HIGH);
    delay (2000);
    digitalWrite (5, HIGH);
    delay (2000);
    digitalWrite (6, HIGH);
    delay (2000);
    digitalWrite (7, HIGH);
    delay (2000);
    digitalWrite (8, HIGH);
    delay (2000);
    digitalWrite (9, HIGH);
    delay (2000);
  }
}

 

 

Ссылка на комментарий
Поделиться на другие сайты

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...