Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
STM32 новичку в ARM что к чему
Так я сделал и пользуюсь по человечески
Проект я этот сделал за 2 дня на второй день плату изготовил и впаял в телек.
Теперь у меня ящик включается и выключается от пульта ТВ приставки )))
Одной кнопкой два девайса. И голову не забивал всякой ерундой и время не тратил.
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Знаешь, я бы постеснялся такое выкладывать
Код: Выделить всё
TIM3->DIER |= TIM_DIER_CC1IE;
TIM3->DIER |= TIM_DIER_CC2IE;
TIM3->DIER |= TIM_DIER_CC3IE;
TIM3->DIER |= TIM_DIER_CC4IE;А я не стесняюсь. Но ты можешь навести красоту и сэкономить. Все в твоих руках дерзай.
А мне так код воспринимать легче. Не все требует оптимизации. Оптимизация должна быть разумная.
А мне так код воспринимать легче. Не все требует оптимизации. Оптимизация должна быть разумная.
Последний раз редактировалось Oxford Вт окт 13, 2020 02:57:17, всего редактировалось 2 раза.
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Я неоднократно выкладывал разные классы USB на разные контроллеры. Утаптываются в 2 кб. Любуйся.
VladislavS да нет мне не нужно я не использую сторонние библиотеки в своих проектах. Максимум от вендоров проверенные либы через тестирование, если надо будет я напишу что мне нужно.
Если говорить о USB-UART я микрухи ставлю так проще и надежнее.
Если говорить о USB-UART я микрухи ставлю так проще и надежнее.
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
[uquote="VladislavS",url="/forum/viewtopic.php?p=3905820#p3905820"]А "портянки" это точно не ко мне, я как раз за лаконичность и читаемость кода.[/uquote]
Это С++ читаемый? Ну-ну…
Особенно когда там используются шаблоны. Прямо читабельный донельзя!
Это С++ читаемый? Ну-ну…
Особенно когда там используются шаблоны. Прямо читабельный донельзя!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Я на гитхабе, в ЖЖ
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3905894#p3905894"]Это С++ читаемый? Ну-ну…
Особенно когда там используются шаблоны. Прямо читабельный донельзя![/uquote]
Что в шаблонах нечитаемого? Угловые скобки вместо обычных?
Особенно когда там используются шаблоны. Прямо читабельный донельзя![/uquote]
Что в шаблонах нечитаемого? Угловые скобки вместо обычных?
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Этот текст легко читает любой знающий корейский язык. Намёк понятен? Почему каждый считает, что должен с лёгкостью читать неизвесьный ему язык программирования?이 텍스트는 한국어를 아는 사람이 쉽게 읽을 수 있습니다.
Я уже говорил ansi c стандарт. Все остальное твоя личная головная боль.
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
За меня не надо думать и переживать. За себя лучше беспокойтесь. Вам даже оператор l= избыточен. Смотрите какая штука есть. 
Добавлено after 14 minutes 9 seconds:
Дабы новичкам было интересно и полезно читать тему, она всё же для них, предлагаю в качестве обучения выгрести весь избыточный код из функции представленной вот в этом сообщении.
Добавлено after 4 minutes 30 seconds:
Oxford, так что там про вход в прерывания на С++ было до удаления? Форум всё помнит, нельзя просто так взять и стереть
Добавлено after 14 minutes 9 seconds:
Дабы новичкам было интересно и полезно читать тему, она всё же для них, предлагаю в качестве обучения выгрести весь избыточный код из функции представленной вот в этом сообщении.
Добавлено after 4 minutes 30 seconds:
Oxford, так что там про вход в прерывания на С++ было до удаления? Форум всё помнит, нельзя просто так взять и стереть
Ниче тебе это знать не надо
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
как по мне, "специалисту" С++, в шаблонах крайне сложно уследить за тем, что куда подставляется и когда. т.е. где "шаблон" для подстановки, а где "как есть" все останется. вот я на все эти ваши С++ версии смотрю - вроде нутром понимаю, как там и что, но страшно даже пробовать...Reflector писал(а):Что в шаблонах нечитаемого?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
ARV, вы же в аргументах функций не путаетесь. В круглых скобках пишете переменные и константы. С шаблоном всё то же самое, только скобки угловые и параметры это типы и константы.
Добавлено after 10 minutes 15 seconds:
[uquote="Oxford",url="/forum/viewtopic.php?p=3905942#p3905942"]Ниче тебе это знать не надо[/uquote]Фух, а то я уже думал что-то такое страшное открылось.
Добавлено after 10 minutes 15 seconds:
[uquote="Oxford",url="/forum/viewtopic.php?p=3905942#p3905942"]Ниче тебе это знать не надо[/uquote]Фух, а то я уже думал что-то такое страшное открылось.
Код: Выделить всё
extern "C" void SysTick_Handler()
{
PA_15::toggle();
}Код: Выделить всё
SysTick_Handler:
LDR.N R1,??DataTable1_6 ;; 0x4001080c
LDR R2,[R1, #+0] ;; Read ODR
LSLS R3,R2,#+16
MOV R0,#+32768
BPL.N ??SysTick_Handler_0
STR R0,[R1, #+8] ;; Write BRR
BX LR
??SysTick_Handler_0:
STR R0,[R1, #+4] ;; Wtite BSRR
BX LR ;; return - Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
VladislavS, что бы поморгать светодиодом, мне в проект пришлось добавить 12 каких-то файлов (со счету сбился) + одну папку, там куча файлов, + еще одну папку, там то же куча файлов,
и поморгать-то поморгал,
но вот эток сожалению не собралось, может что то отсутствует, может еще кучу файлов подкинуть надо?
Вы бы свой примерчик не выложили в минимальной конфигурации?
и поморгать-то поморгал,
но вот это
Код: Выделить всё
typedef PinList<Pb1, Pb0, Pb2, Pb1, Pc3, Pc4, Pc5> Group1;Вы бы свой примерчик не выложили в минимальной конфигурации?
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="ARV",url="/forum/viewtopic.php?p=3905949#p3905949"]как по мне, "специалисту" С++, в шаблонах крайне сложно уследить за тем, что куда подставляется и когда. т.е. где "шаблон" для подстановки, а где "как есть" все останется. вот я на все эти ваши С++ версии смотрю - вроде нутром понимаю, как там и что, но страшно даже пробовать...[/uquote]
А с макросами не то же самое? Только при написании макроса придется для каждой строки слеши добавлять, аргументы в скобки брать и все вместе в цикл заворачивать, потом при вызове опять аргументы в скобки и при этом еще и типы не известны, соответственно никакого контроля типов тоже нет.
А с макросами не то же самое? Только при написании макроса придется для каждой строки слеши добавлять, аргументы в скобки брать и все вместе в цикл заворачивать, потом при вызове опять аргументы в скобки и при этом еще и типы не известны, соответственно никакого контроля типов тоже нет.
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Извини, библиотека не для распространения. Давай я лучше простенький пример придумаю как С++ позволяет оптимизировать код. Заодно и шаблон пощупаем. Как раз для начинающих.
Задача: функция toggle для произвольного количества бит в порту STM32F1.
Для начала обзаведёмся служебной функцией, которая считает количество установленных бит.Вроде ничего особенного, но если на входе константа, то компилятор посчитает значение этой функции на этапе компиляции.
Ну, всё готово, чтобы сделать наш класс. Естественно, он будет шаблонным.Начинается всё с параметров шаблонаВ первый будем передавать с каким портом контроллера работать (GPIOA, GPIOB и так далее). Во второй маску, какие биты в порту будут задействованы. Второму параметру зададим значение по умолчанию - оно будет использоваться, если параметр не будет указан.
Попросим компилятор проверить, что пользователь не захотел пустую маску использовать. В нашем примере это неуместно.
Дальше идёт приватная функция base().Её значение мы будем использовать как указатель на используемый порт. Наш класс не знает же до момента компиляции с каким портом будет работать.
Конструктор. Тут всё статическое, конструктор по сути и не нужен, пускай компилятор сам разберётся с ним.
Ну всё, все подготовительные работы закончены. Осталось метод toggle() разобрать. Тут будут наши оптимизации. С ходу просматривается три варианта развития событий:
1. Используются все биты в порту. Тогда напрашивается cделать инверсию ODR = ~ODR. Мы ведь ничего не испортим.
2. Если ипользуется один бит в порту, то смотрим в каком состоянии вывод и сбрасываем/устанавливаем его записью маски в BRR/BSRR.
3. Используется несколько бит в порту. Наиболее общий случай. Читаем ODR и через BSRR что надо скидываем, что надо устанавливаем.
Ну что, проверим на практике?
1. Будем работать со всем портом. Маску не будем указывать, она задастся по умолчанию.
2. Попробуем с одним пином в порту.
3. А теперь два бита в порту
Благодаря возможностям языка программирования компилятор на этапе компиляции просчитал значение функции countSetBits(), внутри метода toggle() выбрал наилучший вариант кода и выкинул остальные!
Вроде для начала ничего сложного, правда ведь?
2Злопыхатели: это учебный пример!
Задача: функция toggle для произвольного количества бит в порту STM32F1.
Для начала обзаведёмся служебной функцией, которая считает количество установленных бит.
Код: Выделить всё
static inline constexpr uint32_t countSetBits(uint32_t value)
{
uint32_t bits = 0;
while (value)
{
value &= value - 1;
bits++;
}
return bits;
}Ну, всё готово, чтобы сделать наш класс. Естественно, он будет шаблонным.
Код: Выделить всё
template <uint32_t GpioID, uint16_t PM=0xFFFF>
class TSimplePort
{
static_assert(PM>0, "Wrong mask");
static inline auto base() { return (GPIO_TypeDef*)GpioID; }
public:
TSimplePort() = default;
static inline void toggle()
{
if constexpr (PM == 0xFFFF)
base()->ODR = ~base()->ODR;
else
if constexpr (countSetBits(PM)==1)
if(base()->ODR & PM) base()->BRR = PM; else base()->BSRR = PM;
else
base()->BSRR = (PM << 16) | (~base()->ODR & PM);
}
};Код: Выделить всё
template <uint32_t GpioID, uint16_t PM=0xFFFF>Попросим компилятор проверить, что пользователь не захотел пустую маску использовать. В нашем примере это неуместно.
Код: Выделить всё
static_assert(PM>0, "Wrong mask");Код: Выделить всё
static inline auto base() { return (GPIO_TypeDef*)GpioID; }Конструктор. Тут всё статическое, конструктор по сути и не нужен, пускай компилятор сам разберётся с ним.
Код: Выделить всё
TSimplePort() = default;1. Используются все биты в порту. Тогда напрашивается cделать инверсию ODR = ~ODR. Мы ведь ничего не испортим.
2. Если ипользуется один бит в порту, то смотрим в каком состоянии вывод и сбрасываем/устанавливаем его записью маски в BRR/BSRR.
3. Используется несколько бит в порту. Наиболее общий случай. Читаем ODR и через BSRR что надо скидываем, что надо устанавливаем.
Ну что, проверим на практике?
1. Будем работать со всем портом. Маску не будем указывать, она задастся по умолчанию.
Код: Выделить всё
using TestPort = TSimplePort<uint32_t(GPIOA_BASE)>;
TestPort::toggle();
LDR.W R5,??main_0 ;; 0x4001080c
LDR R0,[R5, #+0] ;; Read ODR
MVNS R0,R0
STR R0,[R5, #+0] ;; Write ODRКод: Выделить всё
using TestPort = TSimplePort<uint32_t(GPIOA_BASE), (1<<2)>;
TestPort::toggle();
LDR.W R5,??main_0 ;; 0x4001080c
LDR R0,[R5, #+0] ;; Read ODR
LSLS R1,R0,#+29
ITTEE MI
MOVMI R0,#+4
STRMI R0,[R5, #+8] ;; Write BRR
MOVPL R1,#+4
STRPL R1,[R5, #+4] ;; Write BSRR
Код: Выделить всё
using TestPort = TSimplePort<uint32_t(GPIOA_BASE), (1<<2)|(1<<1) >;
TestPort::toggle();
LDR.W R5,??main_0 ;; 0x4001080c
LDR R0,[R5, #+0] ;; Read ODR
MVNS R0,R0
AND R0,R0,#0x6
ORR R0,R0,#0x60000
STR R0,[R5, #+4] ;; Write BSRRБлагодаря возможностям языка программирования компилятор на этапе компиляции просчитал значение функции countSetBits(), внутри метода toggle() выбрал наилучший вариант кода и выкинул остальные!
Вроде для начала ничего сложного, правда ведь?
2Злопыхатели: это учебный пример!
надо бы это в тему про С++ перенести.
зачем base()? для этого примера ведь это не нужно?
зачем base()? для этого примера ведь это не нужно?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="ARV",url="/forum/viewtopic.php?p=3905992#p3905992"]зачем base()? для этого примера ведь это не нужно?[/uquote]Нужно. Передача указателей на структуры портов типа (GPIO_TypeDef*) через параметры шаблонов нарушают условия constexpr из-за того что там volatile внутри спрятан. Это ограничения языка такие. Напрашивалось передать GPIOA сразу через шаблон, но это не будет работать.
но ведь в параметре шаблона у нас uint32_t, что мешает его по месту использования принудительно кастовать к нужному типу?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


