Dima1060 0 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Здравствуйте! У меня на плате полно разных сигналов управления от STM32F429. В программе нужно ими всеми манипулировать. Использовать стандартные функции HAL неудобно, при написании программы придется часто отвлекаться на плату, чтобы посмотреть, где ножки реально расположены. Даже если дефайном присвоить имя какому то выводу, непонятно на каком он порте - надо смотреть плату. HAL_GPIO_WritePin(GPIOA,DAC_RESET,GPIO_PIN_SET); Коллега оборачивает такие вещи в функции void gpioDACRESET(void) { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); } Но это тоже не дело. Подскажите, как вы решаете такие проблемы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 66 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Определите понятные названия и используйте тот же HAL_GPIO_WritePin: #define DACRESET GPIO_PIN_5 #define DACRESET_port GPIOA #define DACRESET_active GPIO_PIN_SET #define DACRESET_deactive GPIO_PIN_RESET HAL_GPIO_WritePin(DACRESET_port, DACRESET, DACRESET_active); Коллега оборачивает такие вещи в функции Коллега не умеет пользоваться определениями, можно записать так: #define gpioDACRESET HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET) и потом просто вызывать: gpioDACRESET; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Сильно доработанные напильником макросы имени Аскольда Волкова: // pin define examples: // LED on GPIOA, bit 1, active level high, // key on GBIOB, bit 6, active level low #define LED A, 1, H #define KEY B, 6, L #define CS1 C, 1, L #define CS2 C, 2, L // usage example: #include "pin_macros.h" void send_spi(uint32_t volatile * cs_pin_bitband); void test() { DRIVER(LED, OUTPUT); TOGGLE(LED); // toggle LED if ( ACTIVE(KEY) ) // if key pressed { ON(LED); // turn LED on } if ( !ACTIVE(KEY) ) // if key not pressed { OFF(LED); // turn LED off } // works on Cortex-M3 and higher send_spi(BITBAND_OUT(CS1)); send_spi(BITBAND_OUT(CS2)); } void send_spi(uint32_t volatile * cs_pin_bitband) { cs_pin_bitband = 0; ..... cs_pin_bitband = 1; } разумеется, определения всех ног и #include < pin_macros.h > вынесены в заголовочный файл (hardware.h). STM32_pin_macros.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Юзаю регистры сброса и установки, можно даже одновременно (приоритет у сброса). Никакими дополнительными макросами-шмакросами не пользуюсь, кроме тех, которыми манипулирую битами регистра. Тем более, функциями-... Читайте Референс мануал. #define LED_ON() (GPIOB->BSRR = 1 << 1 + 16) //!< Включить светодиод (Low) #define LED_OFF() (GPIOB->BSRR = 1 << 1) //!< Выключить светодиод (High) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 40 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Юзаю регистры сброса и установки, можно даже одновременно (приоритет у сброса). Никакими дополнительными макросами-шмакросами не пользуюсь, кроме тех, которыми манипулирую битами регистра. Тем более, функциями-... Читайте Референс мануал. #define LED_ON() (GPIOB->BSRR = 1 << 1 + 16) //!< Включить светодиод (Low) #define LED_OFF() (GPIOB->BSRR = 1 << 1) //!< Выключить светодиод (High) Особенно если надо код с HAL ужать или надо быстро - через BRR/BSRR самое то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
.crz 0 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Определяю ножки и порты дефайнами: #define IPNUT_PIN_0 GPIO_PIN_0 #define IPNUT_PORT_0 GPIOA #define IPNUT_PIN_1 GPIO_PIN_3 #define IPNUT_PORT_1 GPIOA #define IPNUT_PIN_2 GPIO_PIN_0 #define IPNUT_PORT_2 GPIOB #define IPNUT_PIN_3 GPIO_PIN_1 #define IPNUT_PORT_3 GPIOB #define IPNUT_PIN_4 GPIO_PIN_0 #define IPNUT_PORT_4 GPIOC , объединяю их в массивы: const uint16_t inputPin[]={IPNUT_PIN_0, IPNUT_PIN_1, IPNUT_PIN_2, IPNUT_PIN_3, IPNUT_PIN_4, IPNUT_PIN_5, IPNUT_PIN_6, IPNUT_PIN_7, IPNUT_PIN_8, IPNUT_PIN_9, IPNUT_PIN_10, IPNUT_PIN_11, IPNUT_PIN_12, IPNUT_PIN_13, IPNUT_PIN_14, IPNUT_PIN_15}; const GPIO_TypeDef* inputPort[]={ IPNUT_PORT_0, IPNUT_PORT_1, IPNUT_PORT_2, IPNUT_PORT_3, IPNUT_PORT_4, IPNUT_PORT_5, IPNUT_PORT_6, IPNUT_PORT_7, IPNUT_PORT_8, IPNUT_PORT_9, IPNUT_PORT_10, IPNUT_PORT_11, IPNUT_PORT_12, IPNUT_PORT_13, IPNUT_PORT_14, IPNUT_PORT_15}; инициализацию делаю с помощью HAL: GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = inputPin[gpioNum]; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = gpioContext[gpioNum].pull; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(inputPort[gpioNum], &GPIO_InitStruct); читаю и устанавливаю через bit-banding: #define GPIO_PIN_ISTATE(PORT,PIN) &(*(__I uint32_t *)(PERIPH_BB_BASE + ((((uint32_t)&((PORT)->IDR)) - PERIPH_BASE) << 5) + ((PIN) << 2))) #define GPIO_PIN_ISET(PORT,PIN) (*(__I uint32_t *)(PERIPH_BB_BASE + ((((uint32_t)&((PORT)->ODR)) - PERIPH_BASE) << 5) + ((PIN) << 2))) #define IPNUT_PIN_STATE(a) GPIO_PIN_ISTATE(inputPorts[a], inputPin[a]) #define IPNUT_PIN_SET(a) GPIO_PIN_ISET(inputPorts[a], inputPin[a]) const uint32_t * inputState[]={ GPIO_PIN_ISTATE(IPNUT_PORT_0, (IPNUT_PIN_0)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_1, (IPNUT_PIN_1)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_2, (IPNUT_PIN_2)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_3, (IPNUT_PIN_3)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_4, (IPNUT_PIN_4)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_5, (IPNUT_PIN_5)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_6, (IPNUT_PIN_6)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_7, (IPNUT_PIN_7)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_8, (IPNUT_PIN_8)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_9, (IPNUT_PIN_9)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_10, (IPNUT_PIN_10)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_11, (IPNUT_PIN_11)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_12, (IPNUT_PIN_12)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_13, (IPNUT_PIN_13)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_14, (IPNUT_PIN_14)>>1), GPIO_PIN_ISTATE(IPNUT_PORT_15, (IPNUT_PIN_15)>>1)}; if (*inputState[i]) { ... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Подскажите, как вы решаете такие проблемы? У меня два подхода 1) В сложных контроллерах типа ARM использую осмысленные макросы. #define INIT_RS_DIR_PIN() do \ { PORTE_PCR16 = PORT_PCR_MUX(1) |PORT_PCR_DSE_MASK; \ GPIOE_PSOR = 0x01 << 16; \ GPIOE_PDDR |= 0x01 << 16; \ } while (0) #define SET_TRANSMIT() GPIOE_PCOR = 0x01 << 16 #define SET_RECEIVE() GPIOE_PSOR = 0x01 << 16 2) В простых контроллерах типа MSP430 использую более сложные макросы, определяющие назначение портов, их направление и т.д. Но этот вариант сложный, и он требует высшего уровня оптимизации, оправдан, если много проектов на одной плате. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
turnon 1 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Вся плата описана в pinout.h и например, светодиод: #define PIN_LED_GREEN GPIOA, GPIO_Pin_8 Есть макрос gpioSet(GPIO_TypeDef* GPIOx, PIN_TYPE pin, uint8_t state); Вызываю соотв. gpioSet(PIN_LED_GREEN, true) или gpioSet(PIN_LED_GREEN, false). В итоге манипулирую только объектами платы (PIN_LED_GREEN), м не портами и пинами (GPIOA, GPIO_Pin_8). Также при новой версии железа достаточно поправить только pinout.h Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба Даже если дефайном присвоить имя какому то выводу, непонятно на каком он порте - надо смотреть плату. Коллега оборачивает такие вещи в функции Но это тоже не дело. Подскажите, как вы решаете такие проблемы? Два экрана. На одном всегда открыта плата. Схема платы специально сделана так чтобы понятен был и порт, и функция, и аттрибуты порта. На именах сигналов не зацикливаюсь, переназываю их в течении проекта много раз. Могу в течении дня им несколько раз названия менять. Вся программа пишется так чтобы выдерживать постоянный непрерывный рефакторинг. Не память должна подстраиваться под программу, а программа под память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 40 6 июля, 2016 Опубликовано 6 июля, 2016 · Жалоба На схеме использую названия вида SIGNAL_PIN - например BUTTON_LEFT_PA1 В программе #define BUTTON_LEFT PA1 или #define BUTTON_LEFT_PA1 PA1 (как обычно PA0 = 0, ..., PB0 = 0x10, ..., PC0 = 0x20 и т.д) если через макрос делается инициализация (а таких 99.9%) то простейшие макросы переделывают PA0 в нужные маски и порты Если runtime - то тоже не проблема переделать в порт/маску или bit-banding. Хотя это конечно даже обсуждения не стоит. Дергать ногами большого ума не надо. Вот что то красивое изобразить - это да. Например нормальную (irq/dma) поддержку CAN со всеми mailbox'ами и fifo, или i2c/i2s. С spi/uart проще конечно. Тут без школы танцев не обойтись. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slavka012 0 7 июля, 2016 Опубликовано 7 июля, 2016 · Жалоба На схеме использую названия вида SIGNAL_PIN - например BUTTON_LEFT_PA1 В программе #define BUTTON_LEFT PA1 или #define BUTTON_LEFT_PA1 PA1 (как обычно PA0 = 0, ..., PB0 = 0x10, ..., PC0 = 0x20 и т.д) Примерно также. #define B1_PIN (M_PORT0 | 13) #define B2_PIN (M_PORT1 | 30) #define B3_PIN (M_PORT0 | 12) #define B4_PIN (M_PORT1 | 31) #define NEW_BUZZ_PIN (M_PORT2 | 1) (т.е. В1 это PORT0.13 etc) Далее используются следующие функции для установки периферии и пуллапов и пулдаунов. ConfigPin2(NEW_VOL_PIN, 0x2, 0x00); ConfigPin2(NEW_BUZZ_PIN, BRIGHTNESS_PIN_PWM_MODE, PULL_DOWN); Включить пин на выход SetPinOut(NEW_BUZZ_PIN); И установить выходной уровень пина: SetPin(SENS_ENA); ClrPin(SENS_ENA); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 7 июля, 2016 Опубликовано 7 июля, 2016 · Жалоба https://github.com/antongus/stm32tpl - макросы Аскольда Волкова, которые творчески допилил АНТОХА. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 7 июля, 2016 Опубликовано 7 июля, 2016 · Жалоба Вся плата описана в pinout.h и например, светодиод: Также при новой версии железа достаточно поправить только pinout.h Не знал, что можно делать такие дефайны #define PIN_LED_GREEN GPIOA, GPIO_Pin_8 это позволяет одному имени PIN_LED_GREEN присвоить сразу и порт GPIOA и ножку порта GPIO_Pin_8! очень не хотелось писать отдельные дефайны типа такого: #define PIN_LED_GREEN GPIO_Pin_8 #define PORT_LED GPIOA и потом рулить не очень удобно HAL_GPIO_WritePin(PORT_LED,PIN_LED_GREEN,GPIO_PIN_SET); а тут получается намного проще можно сделать #define PIN_LED_GREEN GPIOA, GPIO_Pin_8 HAL_GPIO_WritePin(PIN_LED_GREEN,GPIO_PIN_SET); а зачем Вам еще и макрос и как Вы его определяете gpioSet(GPIO_TypeDef* GPIOx, PIN_TYPE pin, uint8_t state) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 192 7 июля, 2016 Опубликовано 7 июля, 2016 · Жалоба Не память должна подстраиваться под программу, а программа под память. Т.е. - если что-то забыли, то в проге этот кусок должен исчезнуть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 7 июля, 2016 Опубликовано 7 июля, 2016 · Жалоба Всегда и на всех архитектурах использую решение на основе "макросов Аскольда" - благодаря этому моя наработанная библиотека цепляется к любому проекту и постоянно пополняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться