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

amiller

Участник
  • Постов

    202
  • Зарегистрирован

  • Посещение

  • Победитель дней

    1

Весь контент amiller


  1. Детская ошибка

    А давайте утрируем ситуацию: main () { unsigned int temp1, temp2; for (unsigned int i = 0; i < 10; i++) { temp1 = 0x0001; temp2 = 0xFFFE; if (1) continue; temp2 = temp1; } } Вроде как здесь всё ещё более определено. Так ведь нет. В этом случае видим предупреждение: Warning[Pe111]: statement is unreachable H:\work\test\example2.c 9 Где логика то?
  2. Детская ошибка

    Ну что же Вы право... Если усомнились, что же сами не проверили? example1.c - переменные 16 битные, код не формируется (example1.lst). example2.c - переменные 32 битные, код формируется (example2.lst). Оптимизация - None. Понятно, что в данном конкретном случае, когда присваиваются константы, компилятор на высоком уровне оптимизации может выбросить вообще весь код. Но без оптимизации на этом фрагменте всё воспроизводится так, как я описал. example.zip
  3. Детская ошибка

    Как же Вы любите ярлыки навешивать... Вообще то мои слова появились в ответ на Ваше "продолжать дерзить". По моему Вы вообще не поняли, о чём идёт речь. 1. Я не прошу помощи в написании кода или в оценке его качества. 2. Не нужно советов по использованию дополнительного ПО, так как это совсем не относится к делу. 3. И речь не шла о правильности или эффективности примера, его (примера) задача - продемонстрировать описанную проблему. В своем сообщении я описал проблему в работе компилятора, которую увидел. И хотел выяснить нормальное это поведение или нет и почему компилятор ведёт себя по разному в похожих случаях. А конкретная задача в написании программы была решена ещё до того, как было написано сообщение. Ведь не все вопросы обязаны быть на тему "помогите, не работает...".
  4. Детская ошибка

    Ну извините пожалуйста. Я сразу не обратил внимание, что Вы из Москвы. Простите молодого пятидесятилетнего провинциала, что я вообще вступил с Вами в дискуссию. Мне надо было посыпать голову пеплом и с восторгом внимать Вам. Только напомните мне пожалуйста, что именно Вы сказали по существу конкретного вопроса, который я задал?
  5. Детская ошибка

    А кроме голословных утверждений Вам есть что сообщить? В чём именно заключается лень или дурные манеры? Чтобы убедиться в том, а чём я пишу, достаточно: 1. Вставить в программу фрагмент кода (соответствующим образом изменив названия типов). 2. Откомпилировать. Убедиться, что начиная с условного оператора в листинге код не формируется, а предупреждений не выдается. 3. Поменять типы на int32u (или uint32_t, как удобно). 4. Снова откомпилировать,убедиться, что в листинге код есть, хотя результат условного оператора также предопределен, как и в первом случае. 5. Задуматься, возможно сделать выводы. 6. Если понятна причина такого поведения компилятора, рассказать автору вопроса. 7. Если причина неизвестна, то лучше промолчать, а не опускаться до стиля "сам дурак".
  6. Детская ошибка

    Уважаемый, не рассказывайте мне пожалуйста, о бессмысленных присвоениях и сравнениях констант. Вы невнимательно читали предыдущую переписку. Представленный фрагмент кода имеет только один смысл - продемонстрировать наличие проблемы в действиях компилятора. Вместо того, чтобы доказывать, что автор сообщения не умеет писать программы, постарались бы понять, что он хотел донести своим сообщением. Уточнение: мои типы int16u и int32u соответствуют uint16_t u uint32_t. Не уверен, что в этом случае можно говорить о расширении знака. Когда я говорил "ничего не меняется", я имел в виду, что условие в условном операторе по прежнему всегда true (не зависит от типа переменных), но в одном случае код компилируется, а в другом выбрасывается.
  7. Детская ошибка

    Я нигде не писал, что претендую на звание "гуру". Более того, на ошибках учусь с удовольствием, как на своих, так и на чужих. Но никто не дал на мой вопрос чёткий ответ. 1. Если переменные int16u, то компилятор код выбрасывает. У меня нет вопросов к самому факту этого события. У меня вопрос к тому, почему это происходит без предупреждения (молча). Я не считаю, что это нормальное поведение компилятора. 2. Однако если переменные int32u, то с точки зрения выполнения кода ничего не меняется. Но тем не менее в этом случае, код компилируется (не выбрасывается). Хотя результат также предопределен и известен заранее. Я уже вроде успокоился по этому поводу, но находятся всё новые люди, которые утверждают, что я не знаю язык, но не дают чёткого ответа, почему компилятор поступает именно так. Может Вы попробуете?
  8. Можно. Просто я такой способ отнёс к "рукопашным" вариантам. Наверное это будет даже проще, чем пытаться перенести инициализацию переменных на момент после инициализации SDRAM. Хотя лично я бы отключил System_init и написал свою функцию копирования переменных, используя адреса, которые формирует линкер. Просто не люблю присутствия стороннего кода, а System_init - как раз такой.
  9. По моему сделать так как Вы хотите невозможно. На примере IAR: Инициализируемые переменные инициализируются в функции System_init (startup), которая вызывается до передачи управления main(). А SDRAM у вас становится доступной в main(), после инициализации. Все остальные способы рукопашные. Я бы после инициализации внешней памяти добавил функцию типа SDRAM_data_init(), в которой и произвёл это действие. Для удобства можно объявить массив констант для инициализации во Flash.
  10. По смыслу моего сообщения эту фразу нужно продолжить: чтобы генератор выдавал номинальную частоту. Если емкость меньше или больше номинальной, то частота будет больше или меньше. И в этом я пока не вижу попытки сварить яйца или что-то подобное. Т.е. в использовании резонаторов без нагрузочных конденсаторов криминала не нахожу. Дайте ссылку на документ пожалуйста. У меня есть сомнения, что конденсаторы встроены в микросхему. По крайней мере я не нашёл упоминания о таком. По моим представлениям, для известных технологий производства чипов, самым сложным компонентом является конденсатор. Даже индуктивность сделать проще. Технология заточена под p/n переходы и резисторы. Наличие конденсаторов внутри микросхемы переводит её в другой ценовой диапазон. По этому пункту извиняюсь. Нашёл у Ramtron: Не вижу причин для таких обобщений. Блокировочные конденсаторы и фильтры по питанию ставлю в соответствии с требованиями производителя и с учётом своего опыта. В своё время проштудировал не один документ по этой теме. Наличие и необходимость блокировочных конденсаторов вписывается в мою логическую модель мироустройства. А нагрузочные конденсаторы для часового кварцевого резонатора - не совсем.
  11. Детская ошибка

    Извините, но я не понял к чему это всё, что Вы написали. Или Вы считаете, что если я скопирую сюда полный код функции, Вы точно укажете на источник проблемы? Или Вы считаете, что я школьник, и то, что я прислал к делу не имеет отношения, а ошибка в другом месте? Смею Вас заверить, что это не так. И проблема воспроизводится именно в том "огрызке", который я разместил, я специально проверял. Для этого больше ничего не нужно, достаточно этот фрагмент разместить в пустом main(). Ну разве что скорректировать названия типов. И в отзывах была информация, что это характерно не только для компилятора IAR. В gcc тоже проблема воспроизводится.
  12. Хотелось бы поподробнее узнать, что именно навело Вас на такие сравнения. Буду рад замечаниям по существу, собственно ради этого и разместил это сообщение. Могу сразу сказать, чем я руководствовался: 1. Несмотря на то, что я не поставил конденсаторы, емкость самого резонатора и емкость монтажа никто не отменял. Рекомендуемая емкость нагрузочных конденсаторов составляет единицы пФ, что не намного превышает емкость монтажа. Для сравнения: проходная емкость резистора 0805 составляет 1-2пФ. А так как платы устройств в обязательном порядке покрываются защитным лаком (до калибровки), то за сохранность и воспроизводимость этого параметра (емкость монтажа) можно не беспокоится. 2. Я использовал много автономных RTC с последовательным интерфейсом. Ни на одном из них не было требований по установке нагрузочных конденсаторов. Более того, многие из них показывают удовлетворительную точность без калибровки (т.е. откалиброваны с завода под конкретный тип резонаторов). Я тоже предполагаю, что при серийном выпуске отпадёт необходимость в калибровке каждого изделия. Так как при использовании одного и того же типа резонаторов и стандартной калибровки я рассчитываю, что все изделия будут попадать в диапазон 10ppm, что для меня достаточно. 3. Когда нет конденсаторов, гораздо проще соблюсти требования по взаимному расположению резонатора и микроконтроллера, а также обеспечить необходимое экранирование слаботочных сигналов генератора.
  13. Детская ошибка

    Если ошибка воспроизводится в такой простой конструкции, то зачем присылать страницы кода? Переменные temp1 и temp2 локальные, объявление на строчку выше. В исходном коде переменным присваиваются не константы, а результат, возвращаемый функцией. А после условного оператора ещё сотня строк в цикле. Меня лично смутило, что компилятор без предупреждений выбросил из программы большой фрагмент кода. Это было главное, на что я обратил внимание. Но раз общественность не забилась в праведном гневе, значит все считают это нормальным. А тогда вопрос и не стоит обсуждать. Тем более в коде был грешок с приведением типов, на который мне правильно указали.
  14. Калибровка RTC в STM32F1

    Хочу поделиться некоторыми умозаключениями с целью проверить их правильность. Навеяно изучением документов: (AN2867) Oscillator design guide for STM8S, STM8A and STM32 microcontrollers (AN2604) STM32F101xx and STM32F103xx RTC calibration 1. Частота кварцевого генератора в существенной степени зависит от величины его собственной емкости и от емкости нагрузочных емкостей. Номинальную частоту генератор обеспечивает только при подключении нагрузочных конденсаторов номинальной для этого резонатора емкости. При меньшей нагрузочной емкости частота генератора существенно выше, при большей - существенно ниже номинальной. Отклонение может составлять величину около 50 ppm/pF. 2. Чем больше величина нагрузочных емкостей, тем меньше отклонение частоты в связи с отклонением емкости (ppm/pf). Но чем больше нагрузочная емкость, тем больше абсолютное отклонение емкости (погрешность, температура). Поэтому на выбор величины емкости этот пункт не влияет. 3. Чем меньше нагрузочная емкость, тем меньше ток, потребляемый генератором. С точки зрения длительности работы от батареи это скорее аргумент в пользу уменьшения емкостей. 4. При увеличении нагрузочных емкостей рабочая точка генератора приближается к точке резонанса и находится на более крутом участке резонансной кривой. Соответственно разброс параметров генератора оказывает меньшее влияние на его выходную частоту. 5. Для генераторов 32768 зависимость частоты от величины нагрузочных емкостей гораздо больше, чем для генераторов, работающих в мегагерцовом диапазоне. Собственно эти выводы я сделал после того, как столкнулся с тем, что генератор вообще без конденсаторов показал без калибровки слишком большой уход в месяц (более10 минут). Частота на калибровочном выводе составила 512,138Гц, что эквивалентно частоте генерации кварца 32777Гц. Отклонение составляет 270ppm что слишком много для механизма калибровки микроконтроллера. После размышлений решил оставить генератор как есть. Тем более что он без конденсаторов идеально запускается и потребляет даже меньше, чем прописано в документации. Надеюсь, что в таком режиме часы покажут достаточную временную стабильность. Но потребовалась калибровка с учётом изменения делителя. Чтобы упростить процесс калибровки, сделал файл Exel, в который достаточно вбить измеренную частоту 512Гц и получаем нужный коэффициент делителя и нужную калибровочную константу. Результат объединяю в так называемую калибровочную константу, старший байт которой - это K делителя (добавляемый к 32760), а младший байт - регистр калибровки. Алгоритм расчёта выдает несколько вариантов, из которых можно выбирать любой. Файл прикладываю, может кому понравится. RTC___________.zip
  15. Детская ошибка

    В этом с Вами я согласен, но предупредить то надо. Например если поставить внутри функции безусловный return, генерится предупреждение. А в данном случае всё происходит молча. Ну и не совсем понятен алгоритм. В одном случае молча выбрасывает код, а в другом очень похожем случае всё же генерит код, который тем не менее также не выполняется. Например, если в том же примере заменить строку с условным оператором "if (true) continue;" то получаем предупреждение: Warning[Pe111]: statement is unreachable - что логично. А в моем примере это происходило "молча". Тем не менее всем спасибо! Ошибка локализована. И с утверждением, что компилятор "не обязан", я согласен. Остальное в общем то уже нюансы функционирования программы, которой также является и компилятор.
  16. Детская ошибка

    Позволю себе усомниться по двум пунктам: 1. Раньше во всех случаях, когда в коде был фрагмент, который никогда не выполняется, я получал от компилятора соответствующее предупреждение. В данном случае - нет. 2. Я уже писал, что если переменные объявить как int32u, то условие тоже всегда истинно. Но в этом случае компилятор не выбрасывает из кода условный оператор и всё что после него. Есть вероятность, что ответ на этот простой вопрос, как обычно, лежит в более сложных материях. Кстати уровень оптимизации = Null, поэтому с этой стороны не следует ожидать от компилятора излишней предупредительности.
  17. Детская ошибка

    Про неявное приведение типов соглашусь. Ну а судя по второй фразе, Вы точно знаете причину по которой компилятор удаляет часть кода, и при этом нет ни одного предупреждения? Так сообщите пожалуйста. Мне это по прежнему непонятно. Речь идёт о самом первом примере. Поясняю ещё раз. Дело не в том, что результат выполнения условной операции неверный. Дело в том, что условный оператор не выполняется вообще. В исходной программе после этого условного оператора у меня было под сотню строк кода до окончания цикла. И весь этот код отсутствует в ассемблере. \ 00000000 0xB538 PUSH {R3-R5,LR} 68 int16u temp1, temp2; 69 70 for (int32u i = 0; i < 10; i++) \ 00000002 0x2000 MOVS R0,#+0 \ ??main_0: (+1) \ 00000004 0x280A CMP R0,#+10 \ 00000006 0xD206 BCS.N ??main_1 71 { 72 temp1 = 0x0001; \ 00000008 0x2101 MOVS R1,#+1 \ 0000000A 0x000C MOVS R4,R1 73 temp2 = 0xFFFE; \ 0000000C 0xF64F 0x71FE MOVW R1,#+65534 \ 00000010 0x000D MOVS R5,R1 74 if (~temp1 != temp2) continue; 75 temp2 = temp1; 76 } \ 00000012 0x1C40 ADDS R0,R0,#+1 \ 00000014 0xE7F6 B.N ??main_0 77 78 79 80
  18. Детская ошибка

    Так как Вы предлагаете, тоже работает. Хотя в этом меня тоже смущает один момент. После выполнения оператора "~" не должна меняться размерность переменной. Но больше всего меня беспокоит результат компиляции первого моего примера. В ассемблерном коде вообще отсутствует условный оператор и всё, что после него. И при этом никаких предупреждений от компилятора. Как это можно рассматривать? Бага компилятора? Или есть более простое объяснение?
  19. Детская ошибка

    Недавно столкнулся с одной странностью (по крайней мере для меня). Хотелось бы понять. Есть фрагмент года (упрощенный до безобразия): int16u temp1, temp2; for (int32u i = 0; i < 10; i++) { temp1 = 0x0001; temp2 = 0xFFFE; if (~temp1 != temp2) continue; temp2 = temp1; } Так вот, в этом фрагменте условный оператор и код после него никогда не выполняется. В отладчике после выполнения операции "temp2 = 0xFFFE;" происходит сразу переход на начало цикла. Переменные объявлены как int16u (== unsigned short (16 бит беззнаковое)) При этом никаких предупреждений на этапе компиляции. Если переменные объявить как int32u (== unsigned long (32 бита беззнаковое)), то условный оператор выполняется, но естественно результат всегда true. И код работает как надо только в таком варианте: int16u temp1, temp2; for (int32u i = 0; i < 10; i++) { temp1 = 0x0001; temp2 = 0xFFFE; temp1 = ~temp1; if (temp1 != temp2) continue; temp2 = temp1; } В этом случае выполняются все операторы, входящие в тело цикла. IAR C/C++ Compiler for ARM 7.40.3.8902 (7.40.3.8902) Добавлю: Оптимизация отключена. Проект под микроконтроллер STM32F105VCT6
  20. Автор написал, что происходит сброс настроек периферии. Значит и таймер-сторож может отключиться (сбросится в начальное состояние). Может конечно помочь принудительное включение таймера через Option byte, но надежнее проверенный путь - внешний WDT.
  21. Если речь идёт о том, что глючит периферия STM, то почему не может произойти сбой таймера-сторожа? Это такой же периферийный модуль. Если остальные наблюдаемые эффекты Вас не смущают, и дело только в WDT, то я рекомендую Вам также поставить внешний таймер. Несмотря на то, что сам я с такими эффектами не сталкивался, в особо ответственных применениях наряду с внутренним WDT, всегда использую ещё и внешний, тем более, что стоит он копейки. Я тоже не так давно был неприятно удивлён, что модуль протоколирования операций на STM32 в условиях сильных помех писал в области Flash, куда ему писать было запрещено. Хотя адреса неоднократно программно проверяются перед записью. Пришлось через Option byte запрещать запись в некоторые сектора. Но само по себе это печально. Пока я ещё верю, что схемотехнически, используя комплексные меры защиты, можно любой микроконтроллер заставить нормально работать в любых условиях. Но знаю несколько человек, которые утверждают, что там где STM32 периодически выходит из строя в результате воздействия мощных электромагнитных помех, AVR работают устойчиво.
  22. Может усилить подтяжку на линии данных? А вообще идея использовать UART для обмена с датчиком DALLAS интересная. Надо будет попробовать. Я раньше делал связь с датчиком на таймере (правда не на STM). Формирование сигнала через PWM, а считывание длительности импульса ответа через Capture. Но мне показалось, что получился слишком сложный алгоритм. Кстати по применению библиотек: Кто Вам мешает прямо в main прочитать значение любого регистра? Если в библиотеке объявлены символические имена регистров, можно использовать их. Или даже объявить указатель, присвоить ему адрес регистра из даташита, и читать его где угодно и как угодно в отладочных целей.
  23. Достаточно далек от темы, кубик не использую, просто мысли вслух: 1. Вероятно Вы проверили работоспособность каждого датчика и результаты эксперимента подтверждаются, если поменять их местами или использовать по одному? 2. Насколько я помню, измерение у этого датчика происходит как раз за время около секунды и в течение измерения нельзя дергать линию связи. Не получилось ли так, что процесс измерения одного датчика накладывается на попытку обмена с другим датчиком?
  24. Может имеется в виду, что если купил JLINK адаптер с софтом, то можно теперь его (софт) совершенно бесплатно на свой страх и риск залить в ST-LINK?
  25. Насколько я представляю, синхронизацию можно обеспечить всех узлов, в том числе АЦП и ЦАПа внешними эвентами, например от таймера, который будет тактироваться от основной частоты. А на какой частоте при этом работает сам АЦП и когда точно появятся данные в ячейке памяти (посредством DMA), собственно неважно. Если что можно другим потоком DMA забирать из ячейки памяти и отправлять в ЦАП, например. Главное, чтобы новые данные появлялись до того момента, когда Вы их будете использовать. Это будет более правильно, чем заставлять работать АЦП на частоте, которая выше предельной.
×
×
  • Создать...