Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Генератор начального кода для STM32F4хх
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
aleks-falcon
Изучая STM32F4хх, написал генератор начального кода для некоторых модулей. Возможны опечатки и ошибки в программе, будьте внимательны! Следующим напишу генератор для всех таймеров. Подключайтесь к написанию модулей. Нажмите для просмотра прикрепленного файла
SyncLair
Я так понимаю в OO я этим не смогу пользоваться ? У меня OO 3.0
izerg
Чем эта программа лучше того что дают сами ST?
Екселя на компе нет, и чем это открывать без него?
Allregia
Цитата(aleks-falcon @ Oct 21 2012, 09:16) *
Изучая STM32F4хх, написал генератор начального кода для некоторых модулей. Возможны опечатки и ошибки в программе, будьте внимательны! Следующим напишу генератор для всех таймеров. Подключайтесь к написанию модулей. Нажмите для просмотра прикрепленного файла


Задумка хорошая, только сохранять лучше в xls (т.е. в формате до Оффис-2007)
Aner
Цитата(izerg @ Oct 21 2012, 14:23) *
Чем эта программа лучше того что дают сами ST?
Екселя на компе нет, и чем это открывать без него?

опен оффисом.
Boriska
Отличная штука получилась. На мой взгляд, очень полезная программа.
ViKo
А почему GRIO, а не GPIO?
aleks-falcon
Опечатка. Исправим.
kolobok0
Цитата(aleks-falcon @ Oct 21 2012, 11:16) *
...генератор начального кода...


+1
поддерживаю вашу идею

и сразу мысля:
не всегда в оси стоит железячные дела и офисы.
т.е. вот у меня (как пример) работа ведётся под виртуалками. софтверное направление, железячное, всякие там вэбы-сайты, деловая переписка... и т.д... иначе ось быстро засирается и надёжность падает.
aleks-falcon
Новый файл с исправлениями. Нажмите для просмотра прикрепленного файла
Rash
а не затруднит ли выложить в версиях офиса с расширением xls
aleks-falcon
Цитата(Rash @ Oct 24 2012, 10:54) *
а не затруднит ли выложить в версиях офиса с расширением xls

Макросы работать не будут.
Allregia
Цитата(aleks-falcon @ Oct 24 2012, 16:54) *
Макросы работать не будут.

Значит, их надо написать так чтобы работали.
Aner
Не факт.
vlad_new
Уменя то же не фурычит. Говорит офис старый стоит. Хочется взглянуть чо это такое, стоит ли винды ворошить ради этого ? Там хоть портами можно управлять? Или это такая же лабуда как STM впаривает! Вот если бы кто нибудь визард типа как у silabs для армов написал. Я бы точно купил бы. Я даже хочу их армы использовать из за этого, вот только их пока сюда не визут.
Aner
не визут ... и правильно! - сырые они. Юзайте STM32.
( Пипец, кто грамоте вас учил ...)
ViKo
Я посмотрел предложенный генератор с помощью LibreOffice. Макросы нужно разрешить.
Посмотрел (инициализацию портов)... и удалил. Мне это не нужно. Используются те же структуры инициализации, что и в библиотеке от ST. Очень неэффективно.
KARLSON
А мне понравилась)
Хочется как всегда большего, для первой серии например конфигуратор)
Allregia
Цитата(ViKo @ Oct 25 2012, 06:35) *
Я посмотрел предложенный генератор с помощью LibreOffice. Макросы нужно разрешить.
Посмотрел (инициализацию портов)... и удалил. Мне это не нужно.


Ну можно вообще на ассемблере писать, или сразу в машинных кодах....

Цитата
Используются те же структуры инициализации, что и в библиотеке от ST.


И это правильно!

Цитата
Очень неэффективно.


Кого интересует эффективность выполняемого как правило один раз в программе, при ее старте? К тому-же, е надо себя считать умнее компилятора - все там достаточно эффективно.
ViKo
Цитата(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

Я пошел вторым путем.
Allregia
Цитата(ViKo @ Oct 26 2012, 10:03) *
Меня.


Это ради бога.
Просто всегда надо иметь ввиду, что "проблемы индейцев, шерифа не волнуют".

Цитата
Тупить тоже не надо. Код, пример которого показываю, сочинил не компилятор.



Это не код, это исходный текст. Код - это то. во что его компилятор превратит.
И ничего особо страшного, я там не увидел.
ViKo
Цитата(Allregia @ Oct 26 2012, 18:01) *
Это не код, это исходный текст. Код - это то. во что его компилятор превратит.

Пусть будет "текст"...
Цитата
И ничего особо страшного, я там не увидел.

Это я уже понял...
А вот как сделано у меня. rolleyes.gif
Код
;;;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]

Не пугает?
andries5
Цитата(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);
}

KRS
Цитата(ViKo @ Oct 25 2012, 08:35) *
Используются те же структуры инициализации, что и в библиотеке от ST. Очень неэффективно.

Да там вся библиотека неэффективна.
И имена на пол строки, код вроде и читаем, но простые вещи выглядят в тексте очень сложно. Вся легкость пропадает.

Минус подхода - нужен какой то офис (у меня на компах например его просто нет, только вьювер стоит) и нет текстового файла конфигурации. Т.е. diff можно сделать только результата, а не исходника!

Я для себя уже с 90х годов пошел по пути сохранения такой конфигурации в обычном текстовом файле в простом формате.
А сейчас перешел на python там вообще все красиво получается. потому что если надо что то особенное тут же можно и вписать...
AHTOXA
Цитата(KRS @ Oct 27 2012, 01:42) *
А сейчас перешел на python там вообще все красиво получается. потому что если надо что то особенное тут же можно и вписать...

А можно примерчик, как это выглядит?
KRS
Цитата(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, там ноги муторно настраивать регистры по разному называются, исключения есть...
AHTOXA
Цитата(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;

Так я имею все настройки проекта в одном месте. Единственный недостаток - сразу не видно, какие ноги используются какими модулями. Пока мирюсь с нимsm.gif
ViKo
Цитата(andries5 @ Oct 26 2012, 22:24) *
Пугает. Так как надо обсчитать каждый регистр. А наглядности нет. Инициализация проводится один раз по включению, и написав ее с использованием ст. библиотек получим уверенную инициализацию без ошибок.

Вот как оно задается. Написано один раз. Ошибок не наблюдал ни разу. sm.gif
Куда уж больше наглядности?
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)

По-прежнему... пугает?
andries5
Цитата(ViKo @ Oct 27 2012, 09:27) *
По-прежнему... пугает?

Так нет, просто привык к STD Lib.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.