ViKo 1 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба Видать "Всемогущие гуру" хотели еще что-нить в скобочках...вписать И как бы оно {в скобочках} работало после ; ? :w00t: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба Плетясь в хвосте у библиописателей, всегда ограничиваешься эффективностью этих библиописателей. Там, что, мастера высшего пилотажа работают? Похоже, нет. //не в тему Столкнулся недавно с "библиотекой" для AD9837 на сайте AD Я уж было свою наполовину написал, но решил приобщиться к культуре :) Так Mihai & Bogdan там такого накуралесили.. void AD9837_SetRegisterValue(unsigned short regValue) { unsigned char data[5] = {0x03, 0x00, 0x00}; data[1] = (unsigned char)((regValue & 0xFF00) >> 8); data[2] = (unsigned char)((regValue & 0x00FF) >> 0); ADI_CS_LOW; SPI_Write(data,2); ADI_CS_HIGH; } //кончаю оффтоп Похоже, место индусов потихоньку занимают славяне :) А индусы - продвинулись до CEO MS Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба ..Так Mihai & Bogdan там такого накуралесили.... исторически сложённый похоже. в опен исходниках такое часто встречается... этим они и отличаются от боевых, коммерческих = нет повышенного контроля (читай бездельников менагеров), и отсутствие тотального тестирования. У большинства когорты потребителей(читай программистов) подход какой? хэлох-ты мир пишет, значит можно юзать. с возгласами ух-ты!!! а вот то, что какое то состояние может выплыть нечаянно и всё встанет совсем поперёк - ну то через пару лет может и аукнуться на каком-то проценте изделий... к примеру - сейчас немного перетряхиваю lwip - так там так-же встречаются пёрлы. порой заметна даже разная кисть "мастера". что поделать :))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Boriska 0 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба В библиотеку не хожу. Не хочу пользоваться. У меня - просто, понятно... А можно взглянуть на одну какую-нибудь Вашу процедурку, чтобы, так сказать, оценить преимущества подхода? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба А можно взглянуть на одну какую-нибудь Вашу процедурку, чтобы, так сказать, оценить преимущества подхода? Преимуществ особых нет, просто я имею представление о том, что хочу сделать. /*!**************************************************************************** * @brief System Clock STM32F100RBT6B initialize @details Установить тактовую частоту 24MHz @param @return @note Вызывается в startup.s */ void SystemInit(void) { /* Задать начальное состояние (как после сброса) */ RCC->CR = 0x00000083; // HSI On, HSITRIM = 0x80 RCC->CFGR = 0x00000000; // HSI oscillator used as system clock RCC->CIR = 0x001F0000; // Reset and disable all interrupts /* Включить HSE генератор Счетчик таймаута старта HSE генератора, загружается числом из stm32f10x.h Ждать готовности генератора или окончания таймаута */ uint32_t StartCount = HSE_STARTUP_TIMEOUT; RCC->CR |= RCC_CR_HSEON; while (--StartCount && !(RCC->CR & RCC_CR_HSERDY)) { } /* Если HSE генератор включился (таймаут не вышел) */ if (StartCount) { /* Конфигурировать SYSCLK, HCLK, PCLK2, PCLK1, ADCPRE Задать коэффициенты деления частоты */ RCC->CFGR = RCC_CFGR_SW_0 * 0 | // SW[1:0] bits (System clock Switch): HSI RCC_CFGR_HPRE_0 * 0 | // HPRE[3:0] bits (AHB prescaler): SYSCLK / 1 = 24 MHz (max) RCC_CFGR_PPRE1_0 * 0 | // PRE1[2:0] bits (APB1 prescaler): HCLK / 1 = 24 MHz (max) RCC_CFGR_PPRE2_0 * 0 | // PRE2[2:0] bits (APB2 prescaler): HCLK / 1 = 24 MHz RCC_CFGR_ADCPRE_0 * 0 | // ADCPRE[1:0] bits (ADC prescaler): PCLK2 / 2 = 12 MHz (max) RCC_CFGR_PLLSRC * 1 | // PLL entry clock source: PREDIV1 RCC_CFGR_PLLXTPRE * 1 | // HSE divider for PLL entry: / 2 (4 MHz) RCC_CFGR_PLLMULL_0 * 4 | // PLLMUL[3:0] bits (PLL multiplication factor): * 6 = 24 MHz RCC_CFGR_MCO_0 * 7 ; // MCO[2:0] bits (Microcontroller Clock Output): PLL / 2 = 12 MHz /* Пределитель для PLL, не обязательно Младший бит совпадает с RCC_CFGR_PLLXTPRE */ RCC->CFGR2 = RCC_CFGR2_PREDIV1_0 * 1 ; // PREDIV1 input clock divided by 2 /* Включить PLL (и защиту HSE от сбоев, если нужно) Ждать, пока нет готовности PLL */ RCC->CR |= RCC_CR_PLLON * 1 | // PLL enable RCC_CR_CSSON * 1 ; // Clock Security System enable while (!(RCC->CR & RCC_CR_PLLRDY)) { } /* Выбрать PLL как источник системной частоты Ждать, пока PLL не выберется как источник системной частоты */ RCC->CFGR |= RCC_CFGR_SW_0 * 2 ; // System clock Switch: PLL while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) { } /* Выключить внутренний генератор HSI */ RCC->CR &= ~RCC_CR_HSION; } /* Если HSE генератор не запустился, работать от HSI */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба RCC->CR = 0x00000083; // HSI On, HSITRIM = 0x80 RCC->CFGR = 0x00000000; // HSI oscillator used as system clock RCC->CIR = 0x001F0000; "Магические цифры" - тоже не "особенный" вариант. Потом начинаешь мучительно вспоминать, где чего и когда это было :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 февраля, 2014 Опубликовано 12 февраля, 2014 · Жалоба "Магические цифры" - тоже не "особенный" вариант. Потом начинаешь мучительно вспоминать, где чего и когда это было :laughing: Это взято из мануала, состояние после сброса. Оно не особенно и нужно. Будет работать и без этого. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Boriska 0 13 февраля, 2014 Опубликовано 13 февраля, 2014 · Жалоба Преимуществ особых нет, просто я имею представление о том, что хочу сделать. Да, отказ от использования стандартной библиотеки не очевиден. Я только пару раз столкнулся с некоторыми неудобствами использования: Если нужна оптимизация по времени, то иногда приходится отказываться от лишних вызовов процедур. И второй момент: не все процедуры получились очевидными, так что приходится смотреть, что они делают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 февраля, 2014 Опубликовано 13 февраля, 2014 · Жалоба Если хотите очевидного, продемонстрируйте инициализацию порта, например. Желательно, с ассемблерным листингом. И укажите, для какого MCU. А после я покажу свой способ. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Boriska 0 13 февраля, 2014 Опубликовано 13 февраля, 2014 (изменено) · Жалоба Если хотите очевидного, продемонстрируйте инициализацию порта, например. Желательно, с ассемблерным листингом. /* GPIOD Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); /* Configure PD0 and PD2 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOD, &GPIO_InitStructure); На счет листинга - сейчас нет возможности сделать. MCU - STM32F103 Изменено 13 февраля, 2014 пользователем Boriska Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 февраля, 2014 Опубликовано 13 февраля, 2014 · Жалоба Для STM32F100, 103. Такты задаю раньше, одной командой для всех устройств. /*! Port bit configuration table */ typedef enum { IN_ANAL, GO_PP10, GO_PP02, GO_PP50, // Input Analog, GP Output Push-pull 10-2-50MHz IN_FLOA, GO_OD10, GO_OD02, GO_OD50, // Input Float*, GP Output Open-drain 10-2-50MHz IN_PDPU, AO_PP10, AO_PP02, AO_PP50, // Input Pull-down/Pull-up, Alt Func Push-pull CM_NONE, AO_OD10, AO_OD02, AO_OD50 // none(illegal), Alt Func Open-drain 10-2-50MHz } CONF_MODE; /*!**************************************************************************** * @brief Port Low/High byte configuration @details Конфигурация байтов порта целиком @param PORT - имя порта (A..G) @param CM00..CM15 - конфигурация битов 0..15 @note Используется перечисляемый тип CONF_MODE @note Для IN_PDPU нужный pull-down/pull-up задается в ODR */ #define GPIO_CONF(PORT, \ CM00, CM01, CM02, CM03, \ CM04, CM05, CM06, CM07, \ CM08, CM09, CM10, CM11, \ CM12, CM13, CM14, CM15); \ GPIO##PORT->CRL = ((uint32_t) \ CM00 << 0 | CM01 << 4 | CM02 << 8 | CM03 << 12 | \ CM04 << 16 | CM05 << 20 | CM06 << 24 | CM07 << 28); \ GPIO##PORT->CRH = ((uint32_t) \ CM08 << 0 | CM09 << 4 | CM10 << 8 | CM11 << 12 | \ CM12 << 16 | CM13 << 20 | CM14 << 24 | CM15 << 28); #define GPIO_CONFL(PORT, \ CM00, CM01, CM02, CM03, \ CM04, CM05, CM06, CM07); \ GPIO##PORT->CRL = ((uint32_t) \ CM00 << 0 | CM01 << 4 | CM02 << 8 | CM03 << 12 | \ CM04 << 16 | CM05 << 20 | CM06 << 24 | CM07 << 28); #define GPIO_CONFH(PORT, \ CM08, CM09, CM10, CM11, \ CM12, CM13, CM14, CM15); \ GPIO##PORT->CRH = ((uint32_t) \ CM08 << 0 | CM09 << 4 | CM10 << 8 | CM11 << 12 | \ CM12 << 16 | CM13 << 20 | CM14 << 24 | CM15 << 28); /*!**************************************************************************** * @brief Bit of Low/High byte Port configuration @details Конфигурация одиночного бита порта @param PORT - имя порта (A..G) @param BIT - номер бита (0..15) @param CM - конфигурация бита @note Используется перечисляемый тип CONF_MODE @note Для IN_PDPU нужный pull-down/pull-up задается в ODR */ #define GPIO_CONFB(PORT, BIT, CM) \ *(uint32_t *)((uint32_t)(GPIO##PORT) + BIT / 8 * 4) = \ *(uint32_t *)((uint32_t)(GPIO##PORT) + BIT / 8 * 4) \ & (~(0xF << (BIT % 8) * 4)) | (CM << (BIT % 8) * 4) /* GPIO */ GPIO_CONF(A, IN_FLOA, IN_FLOA, IN_FLOA, IN_FLOA, // User_Key, _ , _ , _ IN_ANAL, IN_ANAL, IN_FLOA, IN_FLOA, // DAC-1, DAC-2, _ , _ AO_PP50, IN_FLOA, IN_FLOA, IN_FLOA, // MCO, _ , _ , _ , _ IN_FLOA, IN_FLOA, IN_FLOA, IN_FLOA); А вот листинг ;;;371 /* GPIO */ ;;;372 GPIO_CONF(A, 00000e 49e1 LDR r1,|L1.916| 000010 48df LDR r0,|L1.912| 000012 6008 STR r0,[r1,#0] 000014 1d09 ADDS r1,r1,#4 000016 48e0 LDR r0,|L1.920| 000018 6008 STR r0,[r1,#0] ;;;373 IN_FLOA, IN_FLOA, IN_FLOA, IN_FLOA, // User_Key, _ , _ , _ ;;;374 IN_ANAL, IN_ANAL, IN_FLOA, IN_FLOA, // DAC-1, DAC-2, _ , _ ;;;375 AO_PP50, IN_FLOA, IN_FLOA, IN_FLOA, // MCO, _ , _ , _ , _ ;;;376 IN_FLOA, IN_FLOA, IN_FLOA, IN_FLOA); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Falkon_99 0 14 февраля, 2014 Опубликовано 14 февраля, 2014 · Жалоба от стандартных CMSIS предпочитаю не отказыватся, типа - stm32fxxx.c - system_stm32f2xx.c - core_cm3.c Всё равно стартап вызывается только один раз вначале программы. А вот STM32Fxxx_StdPeriph_Driver ( типа библиотеки GPIO, RCC, DMA ) стараюсь не использовать. Иногда проще пару битов вручную выставить, и тем самым Flash экономиить на пару килобайт. Вы скажете, флеша и так хватает у STM? Это правда, но в режиме отладки, прошивка быстрее грузится в камень))) :smile3046: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Boriska 0 14 февраля, 2014 Опубликовано 14 февраля, 2014 · Жалоба Для STM32F100, 103. Такты задаю раньше, одной командой для всех устройств. /*! Port bit configuration table */ typedef enum {... В принципе, нормально. Только может значения CONF_MODE переименовать, чтобы было понятнее? А то IN_ANAL как-то режет глаз ;) Да и AO_PP02 менее понятно, чем GPIO_Speed_50MHz. Иногда, в проекте под каждый датчик/исполнительное устройство есть отдельный файл, а то и несколько. Как в этом случае задавать настройки: какие порты и другие ресурсы контроллера будут использоваться этим датчиком? Если это делать в заголовочном (*.h) файле самого датчика, то иногда возникают ситуации, когда одни и те же ресурсы используются одновременно несколькими устройствами. Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать? Может есть что-нибудь вроде "Best practices in embedded systems programming" для начинающих? Посоветуйте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 февраля, 2014 Опубликовано 14 февраля, 2014 · Жалоба В принципе, нормально. Только может значения CONF_MODE переименовать, чтобы было понятнее? А то IN_ANAL как-то режет глаз ;) Да и AO_PP02 менее понятно, чем GPIO_Speed_50MHz. Иногда, в проекте под каждый датчик/исполнительное устройство есть отдельный файл, а то и несколько. Как в этом случае задавать настройки: какие порты и другие ресурсы контроллера будут использоваться этим датчиком? Если это делать в заголовочном (*.h) файле самого датчика, то иногда возникают ситуации, когда одни и те же ресурсы используются одновременно несколькими устройствами. Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать? Может есть что-нибудь вроде "Best practices in embedded systems programming" для начинающих? Посоветуйте. Пусть режет. Автору виднее! Каждый думает в меру своей распущенности. На некоторых импортных осциллографах выход калибратора назывался "CAL". У меня все настройки всего - это одна функция, не такая уж и большая. Правда, USB там нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 17 февраля, 2014 Опубликовано 17 февраля, 2014 · Жалоба Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать? Я так делаю. Именно потому что ноги процессора мультиплексируются и нужно смотреть, чтобы не пересекался функционал. В cmsis сделана настройка ног из соответствующих модулей. На мой взгляд, это неудобно и чревато хитрыми багами. По поводу оптимизации инициализации ног. Считаю, что бороться за чистоту листинга и прочую оптимизацию при первоначальной настройке ног нет никакого смысла. Сколько бы она тактов не съела, делается настройка один раз и больше на производительность кода не влияет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться