Есть универсальный класс шаблон который хранит статичный указатель на функцию и имеет методы sethandler и callhandler Этот же шаблон применен для двух таймеров где все работает Для универсальности ссылка описана как void (*handler_ptr)(void) и в таймерах это описание соотвествует реальным функциям А в ADC реальная функция имеет аргумент типа uint16_t Чтобы тем не менее использовать универсальный класс я делаю одно явное преобразование типа указателя при присвоении адреса статичной переменной и одно когда вызываю функцию из хандлера Не может быть именно в этом какого то сюрприза?
добавка все таки действительно что то не так с временем после того как поменял предделитель ADC с 4 на максимальное 18 зацикливание прекратилось
но это не снимает вопроса - почему так? есть старая программа на Си на том же железе и с теми же настройками железа - там работает с предделителем при том что кода внутри вектора больше, но нет выхова функций в обоих случаях CLK_CKDIVR = 0 в программе на си ADC_CR1_SPSEL = 2, в программе на С++ так не работает, работает с ADC_CR1_SPSEL = 7
что еще может быть причиной? не может же один вызов функции быть таким времязатрантным?
переписал проект на с++ получил +250 байт read write memory от линковщика это RAM? как понять на что ушло? что еще странно - пишу новый проект, совершенно пустой проект на С++ - 524 байта read write memory это вообще как?
Карма: 38
Рейтинг сообщений: 618
Зарегистрирован: Пн апр 06, 2015 11:01:53 Сообщений: 3092 Откуда: москва, уфа
Рейтинг сообщения:0
а что за компилятор? sdcc, к примеру, кроме собственно результирующего бинарника выдает на гора еще ворох файлов, весьма во всех отношениях познавательных - ассемблерные листинги каждого компилируемого файла с комментариями из исходника; выхлоп диагностики линковщика, куда чего он какие символы положил, откуда их взял и сколько каждый занимает места; сводка использования областей памяти - вот такое, штук около десятка. В вашем такое поведение не присутствует или не включается флагами?
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
я IAR использую, да, надо будет погружаться в схему распределения памяти у линковщика для С++ она явно отличается от Си
другой вопрос происходит прерывание по GPIO и по усолчанию прерывания от таймеров не могут прозойти пока я не завершил прерывание по GPIO можно как то внутри обработчика прерывания GPIO узнать, что тот или иной таймер переполнился? т.е. что должно будет следом произойти прерывание таймера
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
У меня вроде не было пролем со вложенностью прерываний. Контент на стек МК сам скидывает.
axillent писал(а):
а какой это флаг? TIF?
Нет, UIF. Он называется не по переполнению, а по обновлению. Точку же обновления сам назначаешь. Ну можно считать что переполнение, если регистр TIMx_ARR=0xFF.
Добавлено after 3 minutes 47 seconds: Коли STM8 мучаете. Если не в лом, можете проверить вот это viewtopic.php?p=3090161#p3090161 . А то я так время и не нашел (под этой фразой прячется слово лень).
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
сейчас как раз отлаживаю устройство в котором активно конкурентно работают прерывания по двум таймерам и прерывания по одному пину теоретически они должны друг на друна попадать, но как это сделать абсолютно точно - не знаю у меня прерывания по пинам не теряются
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Чтобы это проверить, я хотел запретить прерывания, дать один два импульса на порт, и разрешить прерывания когда уже внешних импульсов нет.
Собственно запрета прерывания глобального как такого нет в контроллере, есть повышение текущего уровня основной программы который прерывания не перебивают.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
как избавиться от таких варнингов кроме как описывать промежуточную переменную?
Цитата:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
речь о коде где вместе используется более одной volatile переменной и где для меня порядок обращения к ним не важен видел решение использовать #pragma для скрытия варнингов, но мне нужен стандартный код, не только для IAR
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Не переживайте за лишние переменные, объявляйте их как локальные и в узкой области видимости, они долго жить не будут, может даже только в регистрах ядра (маловато конечно регистров в stm, зато система команд неплохая). Оптимизацию только не выключайте.
Добавлено after 8 minutes 24 seconds: Например.
Код:
func (x+y);
и
Код:
type buf=x; buf+=y; func(buf);
Скорее всего компиллятор сделает одинаковый код, все равно же куда то класть надо результат суммы для передачи его в функцию.
З.Ы. По моему скромному мнению конечно.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Вот приоритеты прерываний
Обратите внимание что приоритеты левела 0 и левала 3 для основного цикла программы устанавливаются командами RIM и SIM. Т.е. установив левел3 для основного цикла, ни одно прерывание не сможет его перебить (таким хитрым образом запрещаются прерывания глобально).
Приоритеты же для соответствующего вектора прерывания настраиваются в регистре ITC_SPRx. По умолчанию уровень 0b11 или левел 3. Т.е. чтобы повысить уровень одного вектора, надо опустить другие включенные, что по-моему неудобно, а что делать...
----- UPD: Зато можно часть прерываний отключать пачкой, изменяя биты I1 I0 в регистре CCR (типа регистр статуса), ну то есть пывысить уровень основного цикла до левел 1 например и только прерывания левела 2 и 3 будут актиывны, все с левелом 1 будут как бы отключены, только я так не пробовал.
я правильно понял, что чтобы из EXTIx срабатывал TIMx_OVR_UIF надо у EXTIx приоритет понизить до 2-го? а это какие биты в каком конкретно регистре? по RM0016 я не понял как векторы связаны с этими регистрами, там почему то нотация другая, иными словами не вижу там EXTIx
а это какие биты в каком конкретно регистре? по RM0016 я не понял как векторы связаны с этими регистрами, там почему то нотация другая, иными словами не вижу там EXTIx
Для примера... настраиваю TIM2 с пониженным приоритетом следующим образом:
Код:
//настройка таймера TIM2 для организации регулярных прерываний 400Гц TIM2_PSCR = 7; //предделитель таймера 0-7 (7 = 128) TIM2_ARRH = (uint8_t)(154>>8); //считаем до 150, (для генерации частоты 400Гц при 8МГц) TIM2_ARRL = (uint8_t)(154); TIM2_IER_bit.UIE = 1; //прерывание по обновлению включено TIM2_CR1_bit.CEN = 1; //разрешение работы таймера ITC_SPR4 &= ~(0x0C); //понизить c 3 до 2 программный приоритет у TIM2 update/overflow
В RM0016 на стр.68 есть табличка с 8-мю регистрами ITC_SPR1 - ITC_SPR8, в которых каждые парные 2 бита отвечают за приоритет соответствующего прерывания. Но в этой таблице (на стр.68), первые два железных прерывания пропущены (RESET и TRAmP или как там его...)))), поэтому VECT0SPR[1:0] это биты не 0-го прерывания а 2-го... соответственно VECT1SPR[1:0] это биты 3-го и т.д. Так что от фактического номера железного прерывания нужно отнимать 2 чтобы получить номер в таблице на стр.68
Номера железных прерываний можно подсмотреть в IAR-е в конце файла iostm8s103f3. Например, нужный мне вектор TIM2_OVR_UIF_vector находится под номером 0x0F, отнимаем от 15-ти двоечку и получаем номер 13 в таблице на стр.68 т.е. VECT13SPR[1:0] а это конкретно регистр ITC_SPR4 и биты [3:2], отсюда и команда ITC_SPR4 &= ~(0x0C);
на стр.67 есть табличка уровней (состояния 2-х битов), от низкого к высокому, по ней и выставляй соответствующую пару...
Возможно это решается как то по другому и покрасивее, но мне когда это было нужно, я ничего другого не сообразил, как только таким способом ... так что другого пока не могу предложить)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения