COKPOWEHEU

Members
  • Content count

    3071
  • Joined

  • Last visited

Community Reputation

271 Хороший

About COKPOWEHEU

  • Rank
    Старожил
  • Birthday 02/23/91

Контакты

  • ICQ
    0

Информация

  • Пол
    Мужчина
  • Город
    московская область

Электроника

  • Стаж в электронике
    6-10 лет
  • Сфера радиоэлектроники
    контроллеры

Recent Profile Visitors

15183 profile views
  1. Вот для начала. http://we.easyelectronics.ru/STM32/ispolzovanie-gcc-dlya-stm32f100.html Нужно будет в makefile поменять серию устройства. Тут еще важны буквы, от них зависит память устройства и линия. Для классического f103C8T6 это medium density если не ошибаюсь. Если описать алгоритм вкратце: нужно скомпилировать main (юзерский код) и startup (настройка памяти, прерываний и всего прочего, эта штука компилируется из ассемблерного файла, предоставляемого производителем, только надо найти в нужном формате), у меня это Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_ml.s. Для всей серии stm32f1x испольщуется один заголовочный файл #include <stm32f10x.h> , выбор конкретного камня задается дефайном DEVCLASS (лучше всего в makefile через флаг -D ), например -D DEVCLASS = STM32F10X_MD. Но дополнительно надо еще указать путь к инклюдам на конкретные камни, например Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/ Мало того, при линковке надо еще указать распределение памяти и еще какие-то параметры. Это делается указанием линкеру файла настроек через флаг -T, например -T ld/stm32f10xC8.ld Из того что вспомнил, вроде все. Можно бы еще упомянуть прошивку, но это уже будет зависеть от программатора. Я пробовал с stm32flash (uart bootloader) и самодельным st-link2 (прошитым через тот же stm32flash, естественно) через openocd.
  2. минимизация потребления stm32l151rct6

    Читал и раньше. Попробовал еще несколько комбинаций: - переключение выводов в Digital input + pull-up вместо analog input: потребление растет - запуск часов от LSI вместо LSE: потребление практически не меняется. Возможно, только на фоне общего потребления в пол-миллиампера, а в абсолютных величинах будет заметнее. - бит PWR_CR_ULP (внутренняя опора для аналоговых блоков?) : потребление немного снижается. Последняя надежда что недостаточно очистил плату и идут утечки по налипшей гадости. Я ее, конечно, отмывал в спирте, но мало ли. Попробую еще в керосине, ацетоне и прочих растворителях. Кстати, кто-нибудь знает чем можно удалить остатки цианакрилата? В инете пишут что ацетоном, диметилсульфоксидом и теплой водой (wtf?). Пока лучше тонких проволочек и бритвенного лезвия лучшего способа не нашел.
  3. минимизация потребления stm32l151rct6

    Код я привел. Все выводы настраиваются как аналоговые входы, даже те, что под JTAG используются. Внешней обвязки тоже нет, максимум проводки сантиметров по 5 от силы.
  4. минимизация потребления stm32l151rct6

    Если бы все было так просто. Ток-то я меряю после него
  5. Захотелось сделать устройство с минимальным потреблением. Первоначально хотел попробовать на f103, но глянул в даташит и ужаснулся: в любом режиме сна у него потребление больше, чем у AVR-ок. Ну хорошо, в standby сравнимо, но этот режим мне не подходит. Поискал аналоги, вроде бы серия L1 больше подходит для автономных устройств. Да еще там есть вкусности вроде сенсорных кнопок и управления ЖКИ (не то чтобы необходимо, но поиграться стоит). Собрал макетную плату с высокочастотным (8 МГц) и низкочастотным (32768) кварцами, стабилизатором, кнопками и светодиодами (из кода понятно что где висит). Запускаю RTC с пробуждением раз в секунду (в финальном устройстве просыпаться будет еще чаще) и пытаюсь увести в режим stop. Но вместо потребления в единицы микроампер получаю пол-миллиампера. Либо я какую-то периферию не отключил (да я их и не включал вроде...), либо как-то неправильно увожу в сон (вроде все по даташиту...), либо лыжи не едут. Вот ключевые моменты кода (остальное во вложении): void enable_btn(){ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; GPIO_config(JBTN); //настройка на вход с минимальной скоростью, без подтяжке } void disable_all(){ GPIOA->MODER = 0xFFFFFFFF; //all to analog in GPIOB->MODER = 0xFFFFFFFF; //all to analog in GPIOC->MODER = 0xFFFFFFFF; //all to analog in GPIOD->MODER = 0xFFFFFFFF; //all to analog in GPIOA->OSPEEDR = 0; //all to low speed (наверное, неважно) GPIOB->OSPEEDR = 0; //all to low speed (наверное, неважно) GPIOC->OSPEEDR = 0; //all to low speed (наверное, неважно) GPIOD->OSPEEDR = 0; //all to low speed (наверное, неважно) GPIOA->OTYPER &=~ 0x0000FFFF; GPIOB->OTYPER &=~ 0x0000FFFF; GPIOC->OTYPER &=~ 0x0000FFFF; GPIOD->OTYPER &=~ 0x0000FFFF; RCC->AHBENR &=~ (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIODEN); clock_MS(); } void go_sleep(){ RCC->APB1ENR |= RCC_APB1ENR_PWREN;//вкл тактирование PWR SCB->SCR |= SCB_SCR_SLEEPDEEP; //для M3 разрешаем sleepdeep PWR->CR &=~PWR_CR_PDDS;//выбираем режим Power Down Deepsleep PWR->CR &=~PWR_CR_CWUF ; //очищаем wakeup flag PWR->CR |= PWR_CR_LPSDSR; //уменьшаем voltage regulator __WFI(); } ... //когда нужно заснуть disable_all(); go_sleep(); enable_btn(); Пробовал совсем не переключаться с MSI на HSE, это влияет только на рабочий режим, во сне как было 500 мкА так и остается. L1_sleep.rar
  6. Посмотрите описание порта PB2. К сожалению, вы не написали какой контроллер вы используете. Если stm32f103c8t6 в 48-выводном корпусе, то 20-й вывод. На практике достаточно притянуть BOOT0 и BOOT1 к земле через резистор. Плюс поставить перемычку, замыкающую BOOT0 на питание. Тогда для перепрошивки надеваете перемычку, дергаете ресет (или питание) и запскаете прошивку. После окончания снимаете перемычку и дергаете ресет (питание) для проверки прошитого. UART1: PA9, PA10, которые 30, 31 выводы в 48-выводном корпусе.
  7. Если хочет как сложно, надо не Ардуину брать, а ATtiny2313, травить плату, кодить на ассмеблере
  8. Arduino Uno работа USART

    тогда UCSR1A или UCSR0A, не помню какой номер, гляньте в даташите
  9. дело не только в отладчике. Не придется дергать BOOT1 и ресет, да и скорость у JTAG/SWD выше
  10. А вы оптимистично надеетесь отладить с нуля через UART быстрее чем дойдет отладчик?
  11. Дребезг это нестабильное обнаружение фронта. Либо натурально механическое подпрыгивание контакта на контакте, либо когда оптический сенсор засвечен лишь частично и реагирует на любую помеху. В случае энкодера он возникает за раз только на одном контакте, так что некорректных состояний не возникает, максимум - хаотичный счет на +/- 1. А некорректные состояния могут возникнуть только если скорость вращения достаточно высока чтобы "проскочить" промежуточное состояние между опросами. Ну либо совсем уж жуткие помехи.
  12. Назначение у них совершенно одинаковое - обращение ко 2-й ножке порта. А уж что с ней делать - вопрос к программисту. Более того, глупо разбивать одну и ту же ножку по разным дефайнам, это добавляет путаницу и увеличивает шанс забыть где-то переименовать. А вот когда номер ножки назван по смыслу и используется один на все регистры, ошибиться сложнее. В этом плане, кстати, неплох подход Ардуины, где за вывод отвечает номер и больше ничего. Конечно, реализация у них подкачала, но ведь никто не мешает сделать то же самое на макросах с нулевыми накладными расходами. Нет уж, магические константы это к вам. Мы же продолжим именовать порт в соответствии с назначением, а не с номером. А разбивку на порты и пины пусть делает автоматика, она в таком не ошибается.
  13. Ничего подобного. Поименованной она станет когда ее поименовать осмысленно, в соответствии с назначением. А то можно и #define ONE 1 #define TWO 2 назвать именованными константами и утверждать что это дает какую-то безопасность.
  14. Он имеет в виду, что Atmel неудачно запихали в константу номер бита, а могли - битовую маску, как сделано в других МК. Сравните #define DWEN 4 #define DWEN 0x10 Для этого используются макроопределения портов в соответствии с назначением, а не номером. Да возьмите хотя бы ардуинскую запись class SoftUart{ private: int rx, tx; public: SoftUart(int _rx, int _tx); void write(char ch){ DigitalWrite(tx, LOW); ... } }; могу ошибиться в синтаксисе - ардуиной не пользовался никогда, но суть понятна. А можно сделать то же самое на макросах: #define SOFT_USRT_TX B,1 #define SOFT_UART_RX C,3 void SoftUartWrite(char ch){ PORT_0( SOFT_UART_TX ); ... } Не так много задач, где нужна работа именно с номером порта, а не с устройством, которое на нем висит. А макроопределения битов для разных портов все равно не слишком помогут в защите от багов копипаста, ведь при переносе на другой кристалл меняется в первую очередь схемотехника, устройства переползают на другие порты и другие биты. Не драматизируйте. Замена номера_бита на PINB_номер_бита не делает код лучше. Это как было магическое число, так и остается, только завуалированное. Если хотите избежать ошибок, надо самостоятельно назначать макроконстанты в соответствии с назначением. #define BTN_PORT PORTB #define BTN_PIN PINB #define BTN_DDR DDRB #define BTN_BIT (1<<4) ... BTN_DDR &=~ BTN_BIT; BTN_PORT |= BTN_BIT; if( BTN_PIN & BTN_BIT ){...}