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

 
 
> Научите красиво дергать ножками STM32
Atlantis-
сообщение Jul 6 2016, 15:40
Сообщение #1


Местный
***

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



Здравствуйте!
У меня на плате полно разных сигналов управления от STM32F429. В программе нужно ими всеми манипулировать. Использовать стандартные функции HAL неудобно, при написании программы придется часто отвлекаться на плату, чтобы посмотреть, где ножки реально расположены. Даже если дефайном присвоить имя какому то выводу, непонятно на каком он порте - надо смотреть плату.
Код
HAL_GPIO_WritePin(GPIOA,DAC_RESET,GPIO_PIN_SET);

Коллега оборачивает такие вещи в функции
Код
void gpioDACRESET(void)
{
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
}

Но это тоже не дело. Подскажите, как вы решаете такие проблемы?
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 14)
HardEgor
сообщение Jul 6 2016, 15:57
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925



Определите понятные названия и используйте тот же 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);


Цитата(Atlantis- @ Jul 6 2016, 22:40) *
Коллега оборачивает такие вещи в функции

Коллега не умеет пользоваться определениями, можно записать так:
Код
#define gpioDACRESET HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET)

и потом просто вызывать:
gpioDACRESET;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 6 2016, 16:01
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Сильно доработанные напильником макросы имени Аскольда Волкова:
CODE
// 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 ( 2.17 килобайт ) Кол-во скачиваний: 34
 


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 6 2016, 16:49
Сообщение #4


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

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



Юзаю регистры сброса и установки, можно даже одновременно (приоритет у сброса). Никакими дополнительными макросами-шмакросами не пользуюсь, кроме тех, которыми манипулирую битами регистра. Тем более, функциями-...
Читайте Референс мануал.

Код
#define LED_ON()    (GPIOB->BSRR = 1 << 1 + 16)    //!< Включить светодиод (Low)
#define LED_OFF()    (GPIOB->BSRR = 1 << 1)        //!< Выключить светодиод (High)
Go to the top of the page
 
+Quote Post
x893
сообщение Jul 6 2016, 18:12
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Цитата(ViKo @ Jul 6 2016, 19:49) *
Юзаю регистры сброса и установки, можно даже одновременно (приоритет у сброса). Никакими дополнительными макросами-шмакросами не пользуюсь, кроме тех, которыми манипулирую битами регистра. Тем более, функциями-...
Читайте Референс мануал.

Код
#define LED_ON()    (GPIOB->BSRR = 1 << 1 + 16)    //!< Включить светодиод (Low)
#define LED_OFF()    (GPIOB->BSRR = 1 << 1)        //!< Выключить светодиод (High)


Особенно если надо код с HAL ужать или надо быстро - через BRR/BSRR самое то.
Go to the top of the page
 
+Quote Post
timurey
сообщение Jul 6 2016, 18:44
Сообщение #6





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



Определяю ножки и порты дефайнами:
Код
#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])
               {
                ...
               }



--------------------
timurey.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 6 2016, 19:12
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Atlantis- @ Jul 6 2016, 18:40) *
Подскажите, как вы решаете такие проблемы?

У меня два подхода
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 использую более сложные макросы, определяющие назначение портов, их направление и т.д.
Но этот вариант сложный, и он требует высшего уровня оптимизации, оправдан, если много проектов на одной плате.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
turnon
сообщение Jul 6 2016, 19:33
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 340
Регистрация: 17-10-14
Пользователь №: 83 207



Вся плата описана в 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
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jul 6 2016, 19:40
Сообщение #9


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Atlantis- @ Jul 6 2016, 18:40) *
Даже если дефайном присвоить имя какому то выводу, непонятно на каком он порте - надо смотреть плату.

Коллега оборачивает такие вещи в функции
Но это тоже не дело. Подскажите, как вы решаете такие проблемы?

Два экрана.
На одном всегда открыта плата.
Схема платы специально сделана так чтобы понятен был и порт, и функция, и аттрибуты порта.

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

Не память должна подстраиваться под программу, а программа под память.
Go to the top of the page
 
+Quote Post
x893
сообщение Jul 6 2016, 20:37
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



На схеме использую названия вида 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 проще конечно.

Тут без школы танцев не обойтись.
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Jul 7 2016, 02:12
Сообщение #11


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(x893 @ Jul 6 2016, 16:37) *
На схеме использую названия вида 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);


Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jul 7 2016, 06:34
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



https://github.com/antongus/stm32tpl - макросы Аскольда Волкова, которые творчески допилил АНТОХА.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Atlantis-
сообщение Jul 7 2016, 07:35
Сообщение #13


Местный
***

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



Цитата(turnon @ Jul 6 2016, 22:33) *
Вся плата описана в 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) ?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 7 2016, 08:27
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AlexandrY @ Jul 7 2016, 01:40) *
Не память должна подстраиваться под программу, а программа под память.

Т.е. - если что-то забыли, то в проге этот кусок должен исчезнуть biggrin.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jul 7 2016, 10:30
Сообщение #15


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Всегда и на всех архитектурах использую решение на основе "макросов Аскольда" - благодаря этому моя наработанная библиотека цепляется к любому проекту и постоянно пополняется.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
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 Текстовая версия Сейчас: 22nd August 2025 - 01:04
Рейтинг@Mail.ru


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