|
Генератор начального кода для STM32F4хх |
|
|
|
Oct 25 2012, 05:59
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(ViKo @ Oct 25 2012, 06:35)  Я посмотрел предложенный генератор с помощью LibreOffice. Макросы нужно разрешить. Посмотрел (инициализацию портов)... и удалил. Мне это не нужно. Ну можно вообще на ассемблере писать, или сразу в машинных кодах.... Цитата Используются те же структуры инициализации, что и в библиотеке от ST. И это правильно! Цитата Очень неэффективно. Кого интересует эффективность выполняемого как правило один раз в программе, при ее старте? К тому-же, е надо себя считать умнее компилятора - все там достаточно эффективно.
|
|
|
|
|
Oct 26 2012, 08:03
|

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

|
Цитата(Allregia @ Oct 25 2012, 08:59)  Кого интересует эффективность выполняемого как правило один раз в программе, при ее старте? К тому-же, е надо себя считать умнее компилятора - все там достаточно эффективно. Меня. Тупить тоже не надо. Код, пример которого показываю, сочинил не компилятор. CODE void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 00174 { 00175 uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00; 00176 uint32_t tmpreg = 0x00, pinmask = 0x00; 00177 /* Check the parameters */ 00178 assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 00179 assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); 00180 assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); 00181 00182 /*---------------------------- GPIO Mode Configuration -----------------------*/ 00183 currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); 00184 if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) 00185 { 00186 /* Check the parameters */ 00187 assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); 00188 /* Output mode */ 00189 currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; 00190 } 00191 /*---------------------------- GPIO CRL Configuration ------------------------*/ 00192 /* Configure the eight low port pins */ 00193 if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) 00194 { 00195 tmpreg = GPIOx->CRL; 00196 for (pinpos = 0x00; pinpos < 0x08; pinpos++) 00197 { 00198 pos = ((uint32_t)0x01) << pinpos; 00199 /* Get the port pins position */ 00200 currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; 00201 if (currentpin == pos) 00202 { 00203 pos = pinpos << 2; 00204 /* Clear the corresponding low control register bits */ 00205 pinmask = ((uint32_t)0x0F) << pos; 00206 tmpreg &= ~pinmask; 00207 /* Write the mode configuration in the corresponding bits */ 00208 tmpreg |= (currentmode << pos); 00209 /* Reset the corresponding ODR bit */ 00210 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) 00211 { 00212 GPIOx->BRR = (((uint32_t)0x01) << pinpos); 00213 } 00214 else 00215 { 00216 /* Set the corresponding ODR bit */ 00217 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) 00218 { 00219 GPIOx->BSRR = (((uint32_t)0x01) << pinpos); 00220 } 00221 } 00222 } 00223 } 00224 GPIOx->CRL = tmpreg; 00225 } 00226 /*---------------------------- GPIO CRH Configuration ------------------------*/ 00227 /* Configure the eight high port pins */ 00228 if (GPIO_InitStruct->GPIO_Pin > 0x00FF) 00229 { 00230 tmpreg = GPIOx->CRH; 00231 for (pinpos = 0x00; pinpos < 0x08; pinpos++) 00232 { 00233 pos = (((uint32_t)0x01) << (pinpos + 0x08)); 00234 /* Get the port pins position */ 00235 currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); 00236 if (currentpin == pos) 00237 { 00238 pos = pinpos << 2; 00239 /* Clear the corresponding high control register bits */ 00240 pinmask = ((uint32_t)0x0F) << pos; 00241 tmpreg &= ~pinmask; 00242 /* Write the mode configuration in the corresponding bits */ 00243 tmpreg |= (currentmode << pos); 00244 /* Reset the corresponding ODR bit */ 00245 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) 00246 { 00247 GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); 00248 } 00249 /* Set the corresponding ODR bit */ 00250 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) 00251 { 00252 GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); 00253 } 00254 } 00255 } 00256 GPIOx->CRH = tmpreg; 00257 } 00258 }
Цитирую помощь из библиотеки. Цитата Then user has the choice to use or not the Peripheral’s Drivers - Case1: application code based on Standard Peripheral’s drivers API (files under Libraries\STM32F10x_StdPeriph_Driver) - Uncomment #define USE_PERIPH_LIBRARY (default) - In stm32f10x_conf.h file, select the peripherals to include their header file - Use Peripheral’s drivers API to build the application; refer to next section for more information. - In addition to the Peripheral’s drivers you can reuse/adapt the rich set of examples available within the Library to speed your development, this allow you to started within few hours. Refer to the complete list of available examples - Case2: application code based on Peripheral’s registers direct access - Comment #define USE_PERIPH_LIBRARY - Use Peripheral’s registers structure and bits definition available within stm32f10x.h to build the application Я пошел вторым путем.
|
|
|
|
|
Oct 26 2012, 15:01
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(ViKo @ Oct 26 2012, 10:03)  Меня. Это ради бога. Просто всегда надо иметь ввиду, что "проблемы индейцев, шерифа не волнуют". Цитата Тупить тоже не надо. Код, пример которого показываю, сочинил не компилятор. Это не код, это исходный текст. Код - это то. во что его компилятор превратит. И ничего особо страшного, я там не увидел.
|
|
|
|
|
Oct 26 2012, 17:58
|

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

|
Цитата(Allregia @ Oct 26 2012, 18:01)  Это не код, это исходный текст. Код - это то. во что его компилятор превратит. Пусть будет "текст"... Цитата И ничего особо страшного, я там не увидел. Это я уже понял... А вот как сделано у меня. Код ;;;223 GPIO_PORTL_CFG(A, AFO_PP50, IN_PD_PU, AFO_PP50, GPO_OD50, IN_PD_PU, AFO_PP10, AFO_PP10, IN_PD_PU); 0000ae 49d8 LDR r1,|L1.1040| 0000b0 48d6 LDR r0,|L1.1036| 0000b2 6008 STR r0,[r1,#0] ;;;224 GPIO_PORTH_CFG(A, IN_FLOAT, IN_FLOAT, IN_FLOAT, IN_FLOAT, IN_FLOAT, IN_PD_PU, AFO_PP10, AFO_PP50); 0000b4 48d6 LDR r0,|L1.1040| 0000b6 49d7 LDR r1,|L1.1044| 0000b8 1d00 ADDS r0,r0,#4 0000ba 6001 STR r1,[r0,#0] Не пугает?
|
|
|
|
|
Oct 26 2012, 19:24
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 15-01-09
Из: Moldova
Пользователь №: 43 421

|
Цитата(ViKo @ Oct 26 2012, 20:58)  Не пугает? Пугает. Так как надо обсчитать каждый регистр. А наглядности нет. Инициализация проводится один раз по включению, и написав ее с использованием ст. библиотек получим уверенную инициализацию без ошибок. например void init_GPIO(void) { GPIO_InitTypeDef GPIO_InitStructure; /* GPIOD Periph clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); }
|
|
|
|
|
Oct 26 2012, 19:42
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(ViKo @ Oct 25 2012, 08:35)  Используются те же структуры инициализации, что и в библиотеке от ST. Очень неэффективно. Да там вся библиотека неэффективна. И имена на пол строки, код вроде и читаем, но простые вещи выглядят в тексте очень сложно. Вся легкость пропадает. Минус подхода - нужен какой то офис (у меня на компах например его просто нет, только вьювер стоит) и нет текстового файла конфигурации. Т.е. diff можно сделать только результата, а не исходника! Я для себя уже с 90х годов пошел по пути сохранения такой конфигурации в обычном текстовом файле в простом формате. А сейчас перешел на python там вообще все красиво получается. потому что если надо что то особенное тут же можно и вписать...
|
|
|
|
|
Oct 26 2012, 21:30
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(AHTOXA @ Oct 27 2012, 01:01)  А можно примерчик, как это выглядит? Идея была что бы код получался примерно таким: Код from lpc11c14 import *
U0.txd_pin = -1 U0.rxd_pin = -1
use_all_pins(SSP0)
add_output('test_led', P0[2]) add_block_input('kbd1', (P0[3],P0[4],P0[5])) add_block_input('kbd2', (P1[i] for i in range(2,7)))
generate('def.h','def.c') сейчас очень похоже и работает, -1 ножка автоматически назначается (для периферии), можно присвоить например P0[5]. Так же проверка есть на несуществующие ноги и т.п. add_output генерируют макросы и задают конфигурацию для ноги. (реально параметров больше) но есть псевдонимы с определенными свойствами (например LED(P0[1])) т.е. код компактнее и понятнее получается. но это пока еще больше концепт, но в паре проектов сегенерированным кодом инитил LPC11, там ноги муторно настраивать регистры по разному называются, исключения есть...
|
|
|
|
|
Oct 26 2012, 23:18
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(KRS @ Oct 27 2012, 03:30)  Спасибо, очень интересно. Однако меня немного смущает, что настройки проекта размазываются по сишным и питоновым файлам. У меня сейчас немного другой подход. Для каждого периферийного модуля имеется шаблонный класс с параметрами-настройками модуля. Он знает, какие ножки принадлежат модулю, и умеет их конфигурировать (в конструкторе). И все настройки сводятся к чему-то типа: hw.h: Код #include "uart.h" // настройки UART1 struct Uart1Settings { enum { uartNum = 1 }; enum { baudrate = 115200 }; ... }; // собственно UART1 typedef Uart<Uart1Settings> Uart1;
// просто ножки #include "pin.h" typedef Pin<'A', 1> DE1; typedef Pin<'A', 2> CS1; и hw.cpp: Код Uart1 uart1; Так я имею все настройки проекта в одном месте. Единственный недостаток - сразу не видно, какие ноги используются какими модулями. Пока мирюсь с ним
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 27 2012, 06:27
|

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

|
Цитата(andries5 @ Oct 26 2012, 22:24)  Пугает. Так как надо обсчитать каждый регистр. А наглядности нет. Инициализация проводится один раз по включению, и написав ее с использованием ст. библиотек получим уверенную инициализацию без ошибок. Вот как оно задается. Написано один раз. Ошибок не наблюдал ни разу.  Куда уж больше наглядности? CODE /* Port bit configuration table */ typedef enum { IN_ANALG, GPO_PP10, GPO_PP02, GPO_PP50, // Input Analog, GP Output Push-pull 10-2-50MHz IN_FLOAT, GPO_OD10, GPO_OD02, GPO_OD50, // Input Float (reset state), GP Output Open-drain 10-2-50MHz IN_PD_PU, AFO_PP10, AFO_PP02, AFO_PP50, // Input Pull-down/Pull-up, Alt Func Push-pull CFG_void, AFO_OD10, AFO_OD02, AFO_OD50 // void(illegal), Alt Func Open-drain 10-2-50MHz } CFG_MODE;
/*! ******************************************************************************* * @brief Port Low/High byte configuration * @details Конфигурация байтов порта целиком * @param PORT - имя порта (A..G) * @param CM15..CM00 - конфигурация битов 15..0 * @return * @note Используется перечисляемый тип CFG_MODE * @note Для IN_PD_PU нужный pull-down, pull-up задается в ODR */ #define GPIO_PORTL_CFG(PORT,CM07,CM06,CM05,CM04,CM03,CM02,CM01,CM00) \ GPIO##PORT->CRL = ((uint32_t)CM07<<28|CM06<<24|CM05<<20|CM04<<16|CM03<<12|CM02<<8|CM01<<4|CM00)
#define GPIO_PORTH_CFG(PORT,CM15,CM14,CM13,CM12,CM11,CM10,CM09,CM08) \ GPIO##PORT->CRH = ((uint32_t)CM15<<28|CM14<<24|CM13<<20|CM12<<16|CM11<<12|CM10<<8|CM09<<4|CM08)
/*! ******************************************************************************* * @brief Bit of Low/High byte Port configuration * @details Конфигурация одиночного бита порта * @param PORT - имя порта (A..G) * @param BIT - номер бита (0..15) * @param CM - конфигурация бита * @return * @note Используется перечисляемый тип CFG_MODE * @note Для IN_PD_PU нужный pull-down, pull-up задается в ODR */ #define GPIO_LBIT_CFG(PORT,BIT,CM) \ GPIO##PORT->CRL = GPIO##PORT->CRL & (~(0xf<<BIT*4)) | (CM<<BIT*4)
#define GPIO_HBIT_CFG(PORT,BIT,CM) \ GPIO##PORT->CRH = GPIO##PORT->CRH & (~(0xf<<(BIT-8)*4)) | (CM<<(BIT-8)*4) По-прежнему... пугает?
Сообщение отредактировал IgorKossak - Oct 27 2012, 16:55
Причина редактирования: [codebox] для длинного кода!!!!!
|
|
|
|
|
Oct 27 2012, 07:08
|
Участник

Группа: Участник
Сообщений: 56
Регистрация: 15-01-09
Из: Moldova
Пользователь №: 43 421

|
Цитата(ViKo @ Oct 27 2012, 09:27)  По-прежнему... пугает? Так нет, просто привык к STD Lib.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|