Jump to content

    

ierofant

Участник*
  • Content Count

    31
  • Joined

  • Last visited

Community Reputation

0 Обычный

About ierofant

  • Rank
    Участник

Контакты

  • ICQ
    Array

Информация

  • Город
    Array
  1. Согласен, многого хочу. Опустили планку температуры до 100-150 °C. Глобально, температура не так важна. Должна быть достаточной, чтобы почувствовать изменения в разных режимах. О каких величинах(изменений) идет речь - без понятия пока. Резисторы : я знаю обычные силовые резисторы, на несколько ампер. Но читал, что есть специфические, вроде нагревательных. Конкретно еще не выбирал, сначала хочу услышать какие-то еще идеи и определится, что же это будет за компонент.
  2. Всем привет. Пойдем по-порядку. Цель: Исследовать распределение температуры компонента установленного на плату + промоделировать.(это если в двух словах) Вопросы: 1. Что можете посоветовать в качестве источника тепла? Критерии: температура до 300 °C 150 °C (можно меньше, если очень компактный), простая форма, компактный (желательно в форме параллелепипеда, высотой до 2 мм). Мои варианты: ограничительный резистор (часто очень большие по размеру), линейный стабилизатор (нужна нагрузка, форма TO220 не фонтан), процессор (нужно нагрузить чем-то, плюс много обвязки). Что можете предложить еще? Главное- компактно и чтобы грелось хорошо. Может есть какие-то специальные нагревательные элементы? 2. Чем лучше прикрепить термоэлементы(термопары) к компоненту? Плата будет подвержана действию давления и температуры, надо, чтобы термопары не изменили положения. Спасибо за советы.
  3. Как зависает? Вываливается в Hard Fault или зацикливается в обработчике? Попробуйте считывать статус-регистр в буффер, потом уже с буфера проверять, установлены ли флаги. Вот работающий пример, проверьте, может где-то ошиблись: void init_uart() { RCC->APB2ENR|= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO. RCC->APB2ENR|= RCC_APB2ENR_USART1EN; // Включение тактирования USART1. GPIOA->CRH |= GPIO_CRH_MODE9; // Вывод TX PA.9 - на выход. GPIOA->CRH &=~GPIO_CRH_CNF9; GPIOA->CRH |=GPIO_CRH_CNF9_1; // Альтернативный выход. USART1->CR1 |=(USART_CR1_RE | USART_CR1_TE); // Разрешить выводы RX, TX. // Скорость 9.6 kbps. USARTDIV=FSYS/(16*baud) = 24e6/(16*9600)=156.25 USART1->BRR=(156<<4); // Целая часть коэффициента деления USART1. USART1->BRR|=4; // Дробная часть*16 = 0,25*16 = 4. USART1->CR1 |=USART_CR1_UE; // Включение USART1. USART1->CR1 |=USART_CR1_RXNEIE; // Разрешить прерывания RXNE. NVIC_EnableIRQ(USART1_IRQn); // Разрешить прерывание USART1_IRQn в NVIC. NVIC_SetPriority(USART1_IRQn, 3); //Задать приоритет прерыванию } void USART1_IRQHandler (void) // Обработчик USART1. { uint16_t status = USART1->SR; if (status & USART_SR_RXNE)// Если прерывание по приёму. { .... } else if (status & USART_SR_TXE) // Если прерывание по осовобождению передатчика. { .... } USART1->SR&=~(USART_SR_TXE|USART_SR_RXNE); //очистка флагов } void begin_uart_transm() { USART1->CR1 |=USART_CR1_TXEIE; }
  4. CADiLO, прокомментируйте, пожалуйста, второй вопрос. Как можно избавиться от появления +FTPGET:1,1 в середине сообщения? Я обрисовал для себя такой вариант: после получения 1кб части файла и его обработки, выжидать от модуля сообщения +FTPGET:1,1 и сразу передавать новый запрос на получение 1кб. Это гарантирует исправление проблеммы? :) Проблема с +FTPGET:1,0 решается как раз получением длинны файла. Я Вам отписал на почту по поводу новой прошивки. Буду очень за нее благодарен.
  5. Всем привет. 1. Начиная с какой прошивки работают команды : AT+ FTPSIZE AT+FTPRESET? У меня прошивка Revision:1137B08SIM900M64_ST_DTMF_JD_MMS, работать не хотят. :) И вообще - где-то есть сводный файлик хронологии прошивок, чтобы видеть, с какой прошивки начала работать определенная функция. AT+FTPRESET - работает только после полной закачки файла, или ею можно воспользоваться после неуспешной закачки одной из частей файла командой at+ftpget=2,1024 ? 2. Принимаю файл с фтп кусками по 1024 байт. Скорость юарта - 9600. Иногда(редко) сообщение от модуля +FTPGET:1,1 - принимается в середине этого однокилобайтного куска файла. Что очень портит жизнь и вообще вносит дополнительные трудности в обработку полченной инфы. Как с этим можно бороться? Можно как-то отключить периодическую выдачу в порт этого сообщения - "+FTPGET:1,1"? Плюс, к тому же, последние несколько(десятков) раз после полной передачи файла модуль не выдавал сообщение +FTPGET:1,0, из-за этого не получается однозначно определять окончание передачи. Абсолютно все байты передаются, потом модуль долго тупит, и в итоге выдает ошибку по таймауту(хотя все нормально передал). Ранее это сообщение выдавал как положенно. Какая-то странная неопределенность - при всех равных условиях от раза к разу результаты получения данных не одинаковые.
  6. Спасибо всем за помощь. В целом получилось и перейти на выполнение приложения и перенести таблицу векторов. Вот только если я пытаюсь перенести таблицу в программе бутлоадера - не выходит (не работают прерывания), если же в основной программе - все нормально. Переношу так(т.к. не использую библиотеку для периферии, написал сам) : #define vector_table_offset 0xC00 //смещение #define offset (uint32_t)(vector_table_offset & 0x1FFFFF80) //выравнивание SCB->VTOR = offset; На приложение перехожу с помощью функции JumpToApplication, которую подсказал skripach. Сергей Борщ, пытался разобрать вашу программу. Не понятна эта строчка: SCB->VTOR = (uintptr_t)&Application.Vectors; Возвращается адрес Application.Vectors, после чего явно преобразуется в тип указателя. Тут понятно. А что именно содержит Application.Vectors? И как оно туда попало? Связано это, видимо, с И на сколько я понимаю, линкер предоставляет структуре адрес начала приложения, потом уже в структуре в соотвествии этому начальному адресу всем векторам присваиваются их адреса? Написана ваша программа, однозначно красивее и четче, единственное, хочется её полностью понять. А может еще подскажете, где в iar 6.21 линкерный скрипт?
  7. Спасибо, что откликнулись. skripach Пытаюсь в простейшей программке протестировать переход выполнения кода по определенному адресу. Пробывал с вашим примером, опять не получилось. Вот мой код(для иара, поэтому немного отличается от вашего): #include "stm32f10x.h" #include "core_cm3.h" #define ApplicationAddress 0x08000081 void JumpToApplication(uint32_t addr) { typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; //if(addr>=0x08005000) //{ JumpAddress = *(uint32_t*) (addr + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(uint32_t*) addr); //__MSR_MSP(*(vu32*) addr); Jump_To_Application(); //} } void init_mk() { RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN|RCC_APB2ENR_IOPCEN); GPIOC->CRH |= (GPIO_CRH_MODE9 | GPIO_CRH_MODE8); //C.8, C.9 OUTPUT GPIOC->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_CNF8); GPIOA->CRL&=~GPIO_CRL_MODE0;//A.0 INPUT } void test() { GPIOC->BSRR = GPIO_BSRR_BS9; } int main() { init_mk(); JumpToApplication(ApplicationAddress); GPIOC->BSRR = GPIO_BSRR_BS8; test(); while(1) { } } __MSR_MSP - не было, заменил на функцию подобного содержания из своего хидера. Вот такая функция void __set_MSP(uint32_t topOfMainStack) { __ASM("msr msp, r0"); __ASM("bx lr"); } Проверка была для конкретно вашего примера, насколько я понял, поэтому она закоменчена. #define ApplicationAddress 0x08000081 - это начальный адрес функции test(). (беру его из map-а) Т.е. по предположению - код должен выполниться в обход строки : GPIOC->BSRR = GPIO_BSRR_BS8; Верно? Отладчик после выполнения Jump_To_Application(); матерится на то, что указатель стека находится вне его пределах, причем откуда такое значение - черт знает: The stack pointer for stack 'CSTACK' (currently 0x00F44F28) is outside the stack range (0x20000000 to 0x20000400) Cosmojam, я пока пытаюсь осуществить просто переход выполнения программы по определенному адресу, таблицу векторов даже не трогаю.:) Выше отписался, что у меня не так. Кстати, я правильно понимаю алгоритм работы бутлоадера? После того, как он закончил все свои необходимые действия, нужно: 1. перенести таблицу векторов по адресу в памяти, где начинается основная программа.(т.е. если у меня основная программа записана, начиная с 2й страницы флеша (1 страница - 1кб), то нужно будет сделать так: NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x08000800);) 2. Перейти к выполнению кода на тот же адрес (0x08000800) Верно ли я все понял? P.S. Кстати, skripach, спасибо за приведенный код.
  8. Всем привет. Появилась задача создать бутлоадер, который будет удаленно перепрошивать контроллер. Контроллер работает в связке с gsm-модулем. Раньше опыта создания бутов не было, поэтому вопросов появилось просто масса. Во-первых, для себя я вижу 2 концепции бутлоадера, каждый со своими плюсами и минусами. 1. Основная программа качает прошивку, пишет её в определенное место флеша(например, с 16-й страницы флеша), проверяет, все ли правильно записалось, устанавливает в энергонезависимом регистре флаг, что нужно войти в бут, перезагружается, происходит вход в бутлоадер, который очищает основную программу(например, со 2й страницы флеша) и перезаписывает новую прошивку на это место и переходит на выполнение основной программы. Преимущества(+)/недостатки(-): +простота бутлоадера, в том числе не нужно инициализировать юарт и модуль из бутлоадера. +не нужно долго висеть в буте +перезагружаться в бут можно только после того, как прошивка успешно закачана -если не верно закачалась прошивка либо же не рабочая прошивка - только вручную перепрошивать -нужен МК с бОльшим обьемом Flash 2. Основная программа перегружает МК в бут, который удаляет старую прошивку, качает новую и сразу записывает её вместо старой. Преимущества(+)/недостатки(-): +бут может сам скачать новую прошивку +контроллер с меньшим обьемом флеша -сложность бута - нужно будет иниициализировать юарт, включать и инициализировать gsm модуль. -долго находиться в бутлоадере Какой вариант лучше? И, может, есть более совершенные решения? Теперь вопросы по реализации: 1. Какие подводные камни могут быть в написании бута? 2. Читал на форуме про то, что нужно перезаписывать таблицу векторов(или вектора прерываний?)? Можно об этом подробнее? Как это делается? Где об этом можно подробнее почитать, а то никакой вразумительной инфы не нашел. 3. Бут и основная программа пишуться ведь как 2 разных проекта? Отадельным вопросом - как заставить программу перейти на выполнение с определенного адреса? Где найти об этом информацию? Пробывал как в примере от ST: #include "common.h" #define ApplicationAddress 0x08000073 extern pFunction Jump_To_Application; extern uint32_t JumpAddress; /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); Не получилось. На ф-ции Jump_To_Application(); уходит в hardfault Особенно не понятно, где тело этой функции, нигде в присоединенных файлах эта функция не описана. (файлы примера прикрепил к сообщению) Был бы очень благодарен, если бы кто-то подсказал, где об этом можно прочитать и где можно найти рабочие и понятные примеры. И чтобы не плодить сообщения, напишу про еще одну проблему с отладочной платой: на STM32VLDiscovery целевой контроллер работает, прошивается, но невероятно греется. Даже на 2 секунды нельзя на нем задержать палец. Очень горячий. Закороток визуально нет, да и паяльником я не притрагивался к плате , не знаю, с чего все и началось. Тестера под рукой тоже нет. Не работает светодиод LD4. Правда я не знаю, это следствие или причина нагрева, сейчас далеко от цивилизации, протестить и перепаять ничего не могу. (схема : http://www.st.com/internet/com/TECHNICAL_R...CD00267113.pdf) an2557.rar
  9. Случайно было поделючено питание к схеме с sim900, на которой была закоротка питания с землей. Закоротка была удалена, после этоого при попытках включить модуль, на статусе не появляетсяя высокий уровень. (модуль ни разу включен не был) Теперь питание и земля звоняться в обе стороны : в одну - 1700, в другую - 450(это как и положено). Что за симптомы, и как их можно вылечить? В закоротке ли вообще проблема?
  10. Можно и так. Зависит от терминальной программы, которой пользуетесь. Если терминал от Брая - тогда в конце строки нужно дописывать $0D .($ указывает, что символ будет задан в hex формате) В общем нужно выдать символ перевода каретки. Это 0D в шестнадцатеричной системе. Добавите - должно нормально заработать.
  11. Allregia, Сергей Борщ спасибо за полезные паттерны, буду использовать.
  12. Нашел ошибку. Была она в некорректном применении созданых тестовых массивов. Инициализировал так : uint16_t b[50]; uint16_t b1[50]; А так обрабатывались( i<99): for(int i=0; i<99; i++) {b[i]= *p1; p1++;} Значение 99 перекочевало с предыдущей функции, когда использовался 100 элементный массив. Исправил на 49 - все работает нормально. А в .map все нормально, потому и начал искать в других местах промах. Ошибка глупая такая, стыдно. Кстати, нигде не предусмотренна защита от превышения количества обьявленных элементов массива? Всем большое спасибо за участие и помощь!
  13. Если считать с массивами - до 1кБ занято переменными. Под стеки было выделенно 1кБ, я увеличил это значение до 3кБ - ничего не изменилось все те же лишние значения в переменных и HardFault. Кучу на всякий тоже до 3 кБ увеличил - никакого эффекта. Все переменные глобальные. По тексту программы есть и локальные, но уже до их обьявления и инициализации уже появляются какие-то проблемы. Симптомы очень похожи. Могли бы вы немного подробнее описать, как это проверить, как узнать что должно быть и какие значения сейчас у меня? А то я раньше в таких дебрях еще не копался.) Открыл новую зависимость : Если обьявляется 2 массива : uint16_t b[50]; uint16_t b1[50]; То начинаются такие проблемы. Если же обьявлять только один массив - все ок: uint16_t b[1000]; //uint16_t b1[50]; Можно что угодно местами переставлять и не будет проблем. Причем величину этого массива можно установить хоть 1000 элементов, все отлично работает. Вообще не понятно, какая разница в обьявлении двух массивов по 50 или одного на 100 элементов? Почему так коряво работает?
  14. Всем привет. Возникла странная проблема с которой я не могу разобратся. Контроллер - STM32F100RB. Компилятор - IAR for ARM 6.21 Есть обьявление глобальных переменных: uint16_t b[50]; //тест uint16_t b1[50]; //тест unsigned char time_to_break=0; unsigned int counter=0; unsigned char ban=0; unsigned char push_button=0; .... еще несколько переменных .... unsigned char test[100]; В этом случае еще до входа в главную функцию массив test заполнен символами "я". Если записать к примеру unsigned char test[]="hello my sweety"; , то остальные переменные будут содержать неверные и произвольные значения + контроллер зависает в B HardFault_Handler. Если обьявление массивов b1 и b2 разместить после обьявления всех остальных переменных, то будет та же ситуация. - неверные значения остальных переменных и зависание B HardFault_Handler. В общем от перестановки местами строчек обьявления переменных конечная работа устройства очень меняется и в большинстве случаев имеет какую-то проблему. У меня есть подозрения, что из-за различности типов (char, uint) или еще из-за чего-то происходит неправильное размещение переменных в оперативной памяти. (и они как-то накладываются) Если это так, то как решается? Если нет: Подскажите, в чем проблема и как с ней бороться. Буду очень признателен. Заранее благодарен за помощь.
  15. UART STM32

    Спасибо большое за совет. Действительно, с таким прерыванием отлично заработало, как предпологалось изначально. Сначала прочитал про него, подумал что полный аналог прерывания по окончанию передачи. Продолжил ковырять со старым прерыванием. Пока экспериментировал проследил в дебаге как меняются все регистры состояния и контроля юарта, вот там то и заметил, что когда буфер передатчика пуст - флаг TXE всегда установлен, и как только разрешено прерывание - оно сразу генерируется, в виду пустого передатчика. В отличии от флага окончания передачи, который до прерывания сброшен. У меня антидребезг еще программно реализован с помощью прерываний таймера. А передавать первый байт с установкой флага - мне казалось каким-то извратом. В общем сейчас все заработало как хотелось, что не может не радовать. DMA контроллер - вещь весьма полезная, надо будет с нею разобраться. Среда разработки - IAR 6.21. Проблемы, конечно же, были. Куда без этого?!)) Были проблемы и с работой IARа, т.к. в новая версия(6.21) не хотела работать с внешними хидерами core_cm3.h, и с включением прерываний(пытался их включить, не добавив в проект файл с заголовками прерываний- startup для моего контроллера). Но, для начала, хочу вам обьяснить, каким вообще образом можно создавать проекты для данных контроллеров: Спасоб 1 : читая даташит и управляя всеми необходимыми регистрами для запуска и управления периферией(в этом случае используются только те стандартные библиотеки, где описываются бит-маски, обработчики прерываний и т.п.). Спасоб 2 : используя стандартные библиотеки для работы с периферией(STM32F10x_StdPeriph), где, в принципе, интуитивно понятно происходит работа с периферией. Хотя, даташит, скорее всего, читать все же прийдется. Многие ругаются на её глючность. Я покаместь использую только первый спасоб. Для начала советую помотреть видео с данного ресурса: http://bsvi.ru/category/embedded/arm/ Там небольшое вступление по документации и настройка ИАРа плюс создание простейшего проекта. Видео на русском, лишним однозначно не будет. Много информации(статьи с примерами) есть на ресурсах: http://easyelectronics.ru/ и http://we.easyelectronics.ru/ Поиск по тегам : STM32 http://eugenemcu.ru/publ/13 - тоже хороший ресурс В принципе, почти все эти статьи - это переводы даташитов + примеры. Тем не менее, мне приятнее читать на родном языке. Потом я все равно еще пересматриваю описание работы нужной периферии в ДШ. Всем еще раз спасибо за помощь.