реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Как я накололся с stm32f10x.h, врагу не пожелаю
ViKo
сообщение Feb 12 2014, 11:21
Сообщение #16


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(mantech @ Feb 12 2014, 14:16) *
Видать "Всемогущие гуру" хотели еще что-нить в скобочках...вписать biggrin.gif

И как бы оно {в скобочках} работало после ; ? w00t.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 12 2014, 11:46
Сообщение #17


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Feb 10 2014, 16:49) *
Плетясь в хвосте у библиописателей, всегда ограничиваешься эффективностью этих библиописателей. Там, что, мастера высшего пилотажа работают? Похоже, нет.

//не в тему

Столкнулся недавно с "библиотекой" для AD9837 на сайте AD
Я уж было свою наполовину написал, но решил приобщиться к культуре sm.gif
Так 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;
}

//кончаю оффтоп
Похоже, место индусов потихоньку занимают славяне sm.gif
А индусы - продвинулись до CEO MS


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Feb 12 2014, 12:41
Сообщение #18


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(MrYuran @ Feb 12 2014, 15:46) *
..Так Mihai & Bogdan там такого накуралесили....


исторически сложённый похоже.
в опен исходниках такое часто встречается... этим они и отличаются от боевых, коммерческих = нет повышенного
контроля (читай бездельников менагеров), и отсутствие тотального тестирования. У большинства когорты
потребителей(читай программистов) подход какой? хэлох-ты мир пишет, значит можно юзать. с возгласами ух-ты!!!
а вот то, что какое то состояние может выплыть нечаянно и всё встанет совсем поперёк - ну то через пару лет может
и аукнуться на каком-то проценте изделий...

к примеру - сейчас немного перетряхиваю lwip - так там так-же встречаются пёрлы. порой заметна даже разная кисть "мастера".
что поделать sm.gif))
Go to the top of the page
 
+Quote Post
Boriska
сообщение Feb 12 2014, 14:00
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-11-07
Пользователь №: 32 772



Цитата(ViKo @ Feb 9 2014, 18:57) *
В библиотеку не хожу. Не хочу пользоваться. У меня - просто, понятно...

А можно взглянуть на одну какую-нибудь Вашу процедурку, чтобы, так сказать, оценить преимущества подхода?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 12 2014, 14:08
Сообщение #20


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Boriska @ Feb 12 2014, 17:00) *
А можно взглянуть на одну какую-нибудь Вашу процедурку, чтобы, так сказать, оценить преимущества подхода?

Преимуществ особых нет, просто я имею представление о том, что хочу сделать.
CODE

/*!****************************************************************************
*
@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 */
}
Go to the top of the page
 
+Quote Post
mantech
сообщение Feb 12 2014, 17:27
Сообщение #21


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(ViKo @ Feb 12 2014, 18:08) *
RCC->CR = 0x00000083; // HSI On, HSITRIM = 0x80
RCC->CFGR = 0x00000000; // HSI oscillator used as system clock
RCC->CIR = 0x001F0000;


"Магические цифры" - тоже не "особенный" вариант. Потом начинаешь мучительно вспоминать, где чего и когда это было laughing.gif
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 12 2014, 17:34
Сообщение #22


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(mantech @ Feb 12 2014, 20:27) *
"Магические цифры" - тоже не "особенный" вариант. Потом начинаешь мучительно вспоминать, где чего и когда это было laughing.gif

Это взято из мануала, состояние после сброса. Оно не особенно и нужно. Будет работать и без этого.
Go to the top of the page
 
+Quote Post
Boriska
сообщение Feb 13 2014, 05:57
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-11-07
Пользователь №: 32 772



Цитата(ViKo @ Feb 12 2014, 18:08) *
Преимуществ особых нет, просто я имею представление о том, что хочу сделать.

Да, отказ от использования стандартной библиотеки не очевиден. Я только пару раз столкнулся с некоторыми неудобствами использования: Если нужна оптимизация по времени, то иногда приходится отказываться от лишних вызовов процедур. И второй момент: не все процедуры получились очевидными, так что приходится смотреть, что они делают.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 13 2014, 07:00
Сообщение #24


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если хотите очевидного, продемонстрируйте инициализацию порта, например. Желательно, с ассемблерным листингом. И укажите, для какого MCU. А после я покажу свой способ. sm.gif
Go to the top of the page
 
+Quote Post
Boriska
сообщение Feb 13 2014, 12:50
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-11-07
Пользователь №: 32 772



Цитата(ViKo @ Feb 13 2014, 11:00) *
Если хотите очевидного, продемонстрируйте инициализацию порта, например. Желательно, с ассемблерным листингом.

Код
  
/* 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

Сообщение отредактировал Boriska - Feb 13 2014, 12:51
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 13 2014, 13:35
Сообщение #26


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Для STM32F100, 103. Такты задаю раньше, одной командой для всех устройств.
CODE

/*! 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);
Go to the top of the page
 
+Quote Post
Falkon_99
сообщение Feb 14 2014, 09:31
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 169
Регистрация: 26-03-12
Из: Харьков
Пользователь №: 71 010



от стандартных CMSIS предпочитаю не отказыватся, типа
- stm32fxxx.c
- system_stm32f2xx.c
- core_cm3.c
Всё равно стартап вызывается только один раз вначале программы.

А вот STM32Fxxx_StdPeriph_Driver ( типа библиотеки GPIO, RCC, DMA ) стараюсь не использовать. Иногда проще пару битов вручную выставить, и тем самым Flash экономиить на пару килобайт.
Вы скажете, флеша и так хватает у STM? Это правда, но в режиме отладки, прошивка быстрее грузится в камень))) smile3046.gif
Go to the top of the page
 
+Quote Post
Boriska
сообщение Feb 14 2014, 11:20
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-11-07
Пользователь №: 32 772



Цитата(ViKo @ Feb 13 2014, 17:35) *
Для STM32F100, 103. Такты задаю раньше, одной командой для всех устройств.
/*! Port bit configuration table */
typedef enum {...

В принципе, нормально. Только может значения CONF_MODE переименовать, чтобы было понятнее? А то IN_ANAL как-то режет глаз wink.gif Да и AO_PP02 менее понятно, чем GPIO_Speed_50MHz.
Иногда, в проекте под каждый датчик/исполнительное устройство есть отдельный файл, а то и несколько. Как в этом случае задавать настройки: какие порты и другие ресурсы контроллера будут использоваться этим датчиком? Если это делать в заголовочном (*.h) файле самого датчика, то иногда возникают ситуации, когда одни и те же ресурсы используются одновременно несколькими устройствами. Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать?
Может есть что-нибудь вроде "Best practices in embedded systems programming" для начинающих? Посоветуйте.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 14 2014, 11:25
Сообщение #29


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Boriska @ Feb 14 2014, 14:20) *
В принципе, нормально. Только может значения CONF_MODE переименовать, чтобы было понятнее? А то IN_ANAL как-то режет глаз wink.gif Да и AO_PP02 менее понятно, чем GPIO_Speed_50MHz.
Иногда, в проекте под каждый датчик/исполнительное устройство есть отдельный файл, а то и несколько. Как в этом случае задавать настройки: какие порты и другие ресурсы контроллера будут использоваться этим датчиком? Если это делать в заголовочном (*.h) файле самого датчика, то иногда возникают ситуации, когда одни и те же ресурсы используются одновременно несколькими устройствами. Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать?
Может есть что-нибудь вроде "Best practices in embedded systems programming" для начинающих? Посоветуйте.

Пусть режет. Автору виднее! Каждый думает в меру своей распущенности. На некоторых импортных осциллографах выход калибратора назывался "CAL".
У меня все настройки всего - это одна функция, не такая уж и большая. Правда, USB там нет.
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Feb 17 2014, 05:13
Сообщение #30


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
Меня подмывает перенести все дефайны распределения ресурсов в один заголовочный файл. Стоит так делать?

Я так делаю. Именно потому что ноги процессора мультиплексируются и нужно смотреть, чтобы не пересекался функционал.
В cmsis сделана настройка ног из соответствующих модулей. На мой взгляд, это неудобно и чревато хитрыми багами.

По поводу оптимизации инициализации ног. Считаю, что бороться за чистоту листинга и прочую оптимизацию при первоначальной настройке ног нет никакого смысла. Сколько бы она тактов не съела, делается настройка один раз и больше на производительность кода не влияет.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th August 2025 - 22:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01508 секунд с 7
ELECTRONIX ©2004-2016