Есть универсальный класс шаблон который хранит статичный указатель на функцию и имеет методы 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, к примеру, кроме собственно результирующего бинарника выдает на гора еще ворох файлов, весьма во всех отношениях познавательных - ассемблерные листинги каждого компилируемого файла с комментариями из исходника; выхлоп диагностики линковщика, куда чего он какие символы положил, откуда их взял и сколько каждый занимает места; сводка использования областей памяти - вот такое, штук около десятка. В вашем такое поведение не присутствует или не включается флагами?
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
я IAR использую, да, надо будет погружаться в схему распределения памяти у линковщика для С++ она явно отличается от Си
другой вопрос происходит прерывание по GPIO и по усолчанию прерывания от таймеров не могут прозойти пока я не завершил прерывание по GPIO можно как то внутри обработчика прерывания GPIO узнать, что тот или иной таймер переполнился? т.е. что должно будет следом произойти прерывание таймера
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
У меня вроде не было пролем со вложенностью прерываний. Контент на стек МК сам скидывает.
axillent писал(а):
а какой это флаг? TIF?
Нет, UIF. Он называется не по переполнению, а по обновлению. Точку же обновления сам назначаешь. Ну можно считать что переполнение, если регистр TIMx_ARR=0xFF.
Добавлено after 3 minutes 47 seconds: Коли STM8 мучаете. Если не в лом, можете проверить вот это viewtopic.php?p=3090161#p3090161 . А то я так время и не нашел (под этой фразой прячется слово лень).
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
сейчас как раз отлаживаю устройство в котором активно конкурентно работают прерывания по двум таймерам и прерывания по одному пину теоретически они должны друг на друна попадать, но как это сделать абсолютно точно - не знаю у меня прерывания по пинам не теряются
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Чтобы это проверить, я хотел запретить прерывания, дать один два импульса на порт, и разрешить прерывания когда уже внешних импульсов нет.
Собственно запрета прерывания глобального как такого нет в контроллере, есть повышение текущего уровня основной программы который прерывания не перебивают.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
как избавиться от таких варнингов кроме как описывать промежуточную переменную?
Цитата:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
речь о коде где вместе используется более одной volatile переменной и где для меня порядок обращения к ним не важен видел решение использовать #pragma для скрытия варнингов, но мне нужен стандартный код, не только для IAR
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Не переживайте за лишние переменные, объявляйте их как локальные и в узкой области видимости, они долго жить не будут, может даже только в регистрах ядра (маловато конечно регистров в stm, зато система команд неплохая). Оптимизацию только не выключайте.
Добавлено after 8 minutes 24 seconds: Например.
Код:
func (x+y);
и
Код:
type buf=x; buf+=y; func(buf);
Скорее всего компиллятор сделает одинаковый код, все равно же куда то класть надо результат суммы для передачи его в функцию.
З.Ы. По моему скромному мнению конечно.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2708 Откуда: г. Чайковский
Рейтинг сообщения: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-х битов), от низкого к высокому, по ней и выставляй соответствующую пару...
Возможно это решается как то по другому и покрасивее, но мне когда это было нужно, я ничего другого не сообразил, как только таким способом ... так что другого пока не могу предложить)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения