[uquote="Oxford",url="/forum/viewtopic.php?p=3758011#p3758011"]VladislavS есть переменная которая меняется скажем uint8_ t X, как будешь записывать значение в порт через BSRR? Покажи код.[/uquote]Ну, в отличии от Эдика, я парень хитрый. К тому же, ты решил поиграть на моём поле.
Код то будет простой.
Код: Выделить всё
uint8_t X = GPIOA->IDR; // Сделаем чтобы X была переменной, а не константой
PinList<GpioB<0xFF00>> bus8bit; // Определим шину на старшие 8 бит GPIOB
bus8bit = X; // Запишем в неё данные
А вот во что это скомпилируется, это как раз и интересно. А вариантов тут может быть два.
1. На процессоре STM32F103 без байтового доступа к регистрам
Компилятор выберет вот такой метод и запишет через BSRR
Код: Выделить всё
template<uint32_t PM=PinsMask>
static void inline write(uint16_t data)
{
if constexpr (PM == 0xFFFF)
base()->ODR = data;
else
base()->BSRR = (PM << 16) | (data & PM);
}
Листинг
Код: Выделить всё
//uint8_t X = GPIOA->IDR;
LDR.N R1,??main_0 ;; 0x40010808
LDR R0,[R1, #+0]
//PinList<GpioB<0xFF00>> bus8bit;
//bus8bit = X;
LSLS R0,R0,#+24
LSRS R0,R0,#+16
ORR R0,R0,#0xFF000000
STR R0,[R1, #+1032]
2. На процессоре STM32F303 c байтовым доступом к регистрам
Компилятор выберет вот такой метод и запишет через ODR
Код: Выделить всё
template<uint32_t PM=PinsMask>
static void inline write(uint16_t data)
{
if constexpr (PM == 0xFFFF)
base()->ODR = data;
else if constexpr (PM == 0x00FF)
*(volatile uint8_t*)&base()->ODR = data;
else if constexpr (PM == 0xFF00)
*((volatile uint8_t*)&base()->ODR + 1) = data >> 8;
else
base()->BSRR = (PM << 16) | (data & PM);
}
Листинг
Код: Выделить всё
//uint8_t X = GPIOA->IDR;
LDR.N R0,??main_0 ;; 0x48000010
LDR R1,[R0, #+0]
//PinList<GpioB<0xFF00>> bus8bit;
//bus8bit = X;
STRB R1,[R0, #+1029]
Ну вот как-то так.
[uquote="Oxford",url="/forum/viewtopic.php?p=3758011#p3758011"]Прерывания другая история, это все равно контроллируемый код и однопоточный.[/uquote]Хм. Если в основном цикле я делаю неатомарный доступ R-M-W к порту и из прерывания к этому же порту идёт обращение... То всё!
Спойлер
Код можно было и короче написать. Но это неважно, результат тот же.
Код: Выделить всё
uint8_t X = GPIOA->IDR;
PinList<GpioB<0xFF00>>::write(X);
Добавлено after 4 hours 17 minutes 21 second:
Ну куда же вы все разбежались? Я ещё не показал коронный номер, которому меня
Reflector научил.
Копируем младшие 8 бит порта в старшие 8 бит в обратном порядке: PB0->PB15, PB1->PB14, PB2->PB13, PB3->PB12, PB4->PB11, PB5->PB10, PB6->PB9 и PB7->PB8.
Код: Выделить всё
PinList<PB_7, PB_6, PB_5, PB_4, PB_3, PB_2, PB_1, PB_0 > bus_low;
PinList<PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15> bus_high;
bus_high = bus_low;
//Листинг
LDR.N R1,??main_0 ;; 0x48000410
LDRB R0,[R1, #+0]
RBIT R0,R0
LSRS R0,R0,#+24
STRB R0,[R1, #+5]