Перейти к содержанию
    

Потребовалось еще public задать для функций класса. У меня было другое представление на этот счет. Что методы автоматически видны снаружи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что касается изменения состояния двух ножек одной записью, то это очень частный случай, и в общем виде не решается.

Я считаю, что запись в две ножки по отдельности подойдёт почти в любом случае. Если же прямо кровь из носу необходимо одной записью, то можно сделать как у вас.
Желательно, конечно, убедиться, что обе ножки в одном порту, и что BSRR тоже от этого порта:

#include "pin.h"
  
using Cs1 = Pin<'A', 1>;
using Cs2 = Pin<'A', 2>;

template <typename Pin1, typename Pin2>
struct TwoPins
{
	static_assert(Pin1::port_no == Pin2::port_no, "Two pins should be on the same port!");
	static void set(bool state1, bool state2)
	{
		auto maskToSet = Pin1::mask * state1 | Pin2::mask * state2;
		auto maskToReset = Pin1::mask * !state1 | Pin2::mask * !state2;
		Pin1::GPIOx->BSRR = maskToSet << 16 | maskToReset;
	}
};

void testTwoPins()
{
	using ChipSelects = TwoPins<Cs1, Cs2>;
	asm volatile("nop;");
	ChipSelects::set(true, true);
	asm volatile("nop;");
}

void testSeparatePins()
{
	asm volatile("nop;");
	Cs1::On();
	Cs2::On();
	asm volatile("nop;");
}

Вот во что компилируется testTwoPins:

 8000282:	f44f 22c0 	mov.w	r2, #393216	; 0x60000
 8000286:	4b02      	ldr	r3, [pc, #8]	; (8000290)
 8000288:	611a      	str	r2, [r3, #16]

А вот во что отдельные ножки:

 8000296:	2102      	movs	r1, #2
 8000298:	2204      	movs	r2, #4
 800029a:	4b03      	ldr	r3, [pc, #12]	; (80002a8)
 800029c:	6119      	str	r1, [r3, #16]
 800029e:	611a      	str	r2, [r3, #16]

Да, пару команд вы выиграли, но всегда ли это нужно?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот, собственно, результат моих изобретений(+ подмога). Устраивает.

Спойлер

template<char port, uint bit1, uint bit2>
class PinPair_c {
	static constexpr GPIO_TypeDef *Port = 
		port == 'A' ? GPIOA :
		port == 'B' ? GPIOB :
		port == 'C' ? GPIOC :
		port == 'D' ? GPIOD :
		port == 'E' ? GPIOE :
		port == 'G' ? GPIOG :
		GPIOH;

public:
	static void on1() { Port->BSRR = 1 << bit1 + 16; }
	static void on2() { Port->BSRR = 1 << bit2 + 16; }
	static void on()  { Port->BSRR = 1 << bit1 + 16 | 1 << bit2 + 16; }
	static void off() { Port->BSRR = 1 << bit1 | 1 << bit2; }
};

using Adc_cs = PinPair_c<'B', 13, 14>;
// PinPair_c<'B', 13, 14> Adc_cs;
  
// Adc_cs.on1();
Adc_cs::off();
PinPair_c<'B', 13, 14>::on2();

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько здесь необходим шаблон? Что-то я в смятении. Чем был плох просто класс? Тем, что я выбираю GPIO?

9 минут назад, AHTOXA сказал:

Желательно, конечно, убедиться, что обе ножки в одном порту, и что BSRR тоже от этого порта

Конечно. Это было заложено в схему изначально. Благо, сам себе рисовальщик схем.

Нужно ли именно одной командой? Нет. Но приятно иметь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, AHTOXA сказал:

Я не совсем понял вопрос. У вас же в результате тоже шаблон получился.

Я про свой и спрашиваю. Точно, нужен?

Без шаблона потребуется конструктор и т.д.? Проще не будет. Так понимаю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зависит от того, понадобится ли вам когда-нибудь такой класс с двумя другими ножками. Если да, то можно шаблон. Если нет - можно обойтись простым классом.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопрос задам. Есть ли возможность задать псевдоним для функции из класса? Заменить этот набор чем-нибудь попроще, Adc2_sel(); , например.

PinPair_c<'B', 13, 14>::on2();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Понял, нет. Указатель на функцию предлагают. Не хочу.

Можно с помощью #define подменить. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, ViKo сказал:

Понял, нет. Указатель на функцию предлагают. Не хочу.

inline static void Adc2_sel() { PinPair_c<'B', 13, 14>::on2(); }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, ViKo сказал:

Понял, нет. Указатель на функцию предлагают. Не хочу.

Можно с помощью #define подменить. 

лямбда, ее можно вставить хоть внутри другой функции, внутри "for" .... короче, область ее видимости ограничена местом объявления

auto Adc2_sel = []() { PinPair_c<'B', 13, 14>::on2(); };

используется как обычная функция:

Adc2_sel();

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Благодарю! Проверил оба варианта, работают. Forger-а поправил, добавил точку с запятой после (). 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 hours ago, ViKo said:

Есть ли возможность задать псевдоним для функции из класса?

Мне кажется, надо весь этот класс по-человечески назвать, и всё.

using Adc2_sel=PinPair_c<'B', 13, 14>;

 Adc2_sel::on2(); // почему 2 ?!

Adc2_sel::off();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 минуты назад, esaulenka сказал:

почему 2

У меня 2 вывода порта управляют выбором двух АЦП. Класс назван PinPair_c, в нем определены функции включения и выключения двух битов порта. Здесь, кстати, возможных комбинаций 9 штук - включить, выключить, не менять каждый из битов. Я уже думал задать все 9 функций, но мне в принципе не нравится такой класс. Хочу на все 16 битов порта создать класс, пока размышляю, как.

Создается объект Adc_sel, и из него используются функции управления первым, вторым или обоими битами. Или не создается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...