STM32 "Ядро" для STM32F03xx

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,407
976
58
Марий-Эл
Попытка написания ядра для STM32 для более удобного написания прошивок без использования HAL.

Это ядро пишется под STM32 Cube IDE с использованием CMSIS и ничего более.
Широко распространнённые ядра под Arduino IDE и под PlatformIO или какие либо другие IDE здесь применяться не будут.

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

Все библиотеки для различных устройств будут писаться на базе Ардуиновских библиотек и библиотек Алекса Гайвера. https://alexgyver.ru/
Так как они проверены многими поколениями начинающих программистов и имеют устояшиеся алгоритмы.

Данное ядро будет написано под STM32F030F4P6, но на другие МК, в будущем, будет добавляться код с помощью условного компилирования тех частей кода,
который характерен только для определённых МК. Код, который независим полностью от МК, будет для всех общим.

В данном случае в этом ядре написаны следующие функции:
1. Инициализация тактового генератора на максимальную частоту с внутренним RC генератором, с внешним кварцем на 8МГц будет добавлено позже;
2. Инициализация системного таймера SysTick.
3. Функции millis(), micros(), delay() которые очень часто используются для организации временных задержек.
4. Функция delayMicroseconds() пока не дописана, вместо неё стоит заглушка.

В данный пакет включена библиотека для работы с кнопкам, написанная на основе GyverButton.

Пакет полностью рабочий.
По мере продвижения проекта на данном МК, будут переписываться другие библиотеки и добавляться в данный пакет.

Со временем выделю для каждой библиотеки свой подкаталог и буду писать их туда. Библиотеки не будут иметь защиту от "дурака". Поэтому придётся в STM32CubeMX точно планировать какой вывод и какая периферия и на какие выводы будет выведена.


Чуть позже, если нужно, допишу для чего каждый каталог.
 
Изменено:

Un_ka

★★✩✩✩✩✩
13 Июл 2020
243
77
других форумов.
Чуть позже, если нужно, допишу для чего каждый каталог.
Нужно.
В какой среде программирования писали?

В ней же будет что-то на подобии ?
C++:
volatile void delayMicroseconds(uint16_t US)
{
  uint32_t Counter = micros();
  while((US+Counter) > micros())
  {
    asm("nop");
  }
}
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,407
976
58
Марий-Эл
В какой среде программирования писали?
CubeIDE
В ней же будет что-то на подобии ?
Это пока заглушка. Она даёт большую погрешность на малых задержках.
Я ещё не придумал как это реализовать.
В этом коде используется "nop" т.к. без неё оптимизатор не компилирует этот код. Попытка сказать ему "низя" ни к чему не привела. А он уже вносит погрешность. Плюс математические вычисления в начале цикла. Да и в самой функции micros() есть математика. Пусть и выполняется меньше микросекунды, но идёт накопление погрешности. Уход в функцию и возвращение из неё - ещё один источник погрешности.
 
  • Лойс +1
Реакции: Matveyugru

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,407
976
58
Марий-Эл
@Старик Похабыч, В данном случае delay() даёт погрешность 4 микросекунды.
а вот delayMicroseconds() данной реализации даёт погрешность 4-7 микросекунд. Так что им 1мкС выдержку не сделать.
У меня есть реализация на отдельном таймере без прерываний, но она в использовании сложна. И задействует отдельный таймер.
Я сначала так сделал. Потом перевёл на таймер SysTick, так как он есть в любом МК.
Люди вот советуют делать на сторожевом таймере. Но он может пригодится для использования по прямому назначению.
 
  • Лойс +1
Реакции: Matveyugru

bort707

★★★★★★✩
21 Сен 2020
3,058
910
У меня есть реализация на отдельном таймере без прерываний, но она в использовании сложна. И задействует отдельный таймер.
в стм-ках куча таймеров, не то что АВР
Как правило делают задержки на отдельном обычном(general-purpose)таймере - так как они часто остаются неиспользованными
 

Волков Олег

★✩✩✩✩✩✩
13 Дек 2020
6
14
Держи код для delay microseconds:
Delay_us:
#define    DWT_CYCCNT    *(volatile unsigned long *)0xE0001004
#define    DWT_CONTROL   *(volatile unsigned long *)0xE0001000
#define    SCB_DEMCR     *(volatile unsigned long *)0xE000EDFC


void DWT_Init(void)
{
        //разрешаем использовать счётчик
        SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
         //обнуляем значение счётного регистра
    DWT_CYCCNT  = 0;
         //запускаем счётчик
    DWT_CONTROL |= DWT_CTRL_CYCCNTENA_Msk;
}



static __inline uint32_t delta(uint32_t t0, uint32_t t1)
{
    return (t1 - t0);
}
void delay_us(uint32_t us)
{
      uint32_t t0 =  DWT->CYCCNT;
      uint32_t us_count_tic =  us * (SystemCoreClock/1000000);
      while (delta(t0, DWT->CYCCNT) < us_count_tic) ;
}
Но я не понимаю, зачем Вы делаете двойную работу, когда можно не писать ядро под ардуино, а просто программировать в родной среде, использовать родной программатор, нормальный дебаг, кучу плюх полезных и горя не знать.
 
  • Лойс +1
Реакции: bort707

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,407
976
58
Марий-Эл
@Волков Олег, Я не хочу использовать DWT. Так как я лишусь отладки.

когда можно не писать ядро под ардуино,
Я не пишу ядро под ардуино. Я пишу набор программ, что бы использовать ардуиновские библиотеки.
Зачем мне сидеть и ломать башку над алгоритмом, копаться в чужом коде. У меня уже столько вариантов библиотек для кнопок штук 10 и все написаны или криво или ещё чем то не устраивают.
Мне нравятся библиотеки Алекса. Простые, логичные. Я просто переписал часть отвечающую за ввод информации с пина, остальное ничего не трогал. Сегодня за 15 минут навялил GyverTimer. Благодаря тому, что часть функций, таких как millis() и micros() уже написаны.

Допустим мы имеем какой то MK, у него 3 SPI и возможность переназначения выводов. Я пишу драйвер, который позволяет выбирать любой из них и нужные мне выводы. После этого все команды приёма/передачи делаю такими же как в ардуиновском ядре. Пусть они внутри и будут отличаться от ардуиновских, но для внешней программы это будет не заметно.
Теперь я могу взять практически любую библиотеку от ардуины требующую передачу по SPI, допустим для дисплея, и без потерь использовать её.
 

Un_ka

★★✩✩✩✩✩
13 Июл 2020
243
77
других форумов.
Допустим мы имеем какой то MK, у него 3 SPI и возможность переназначения выводов. Я пишу драйвер, который позволяет выбирать любой из них и нужные мне выводы. После этого все команды приёма/передачи делаю такими же как в ардуиновском ядре. Пусть они внутри и будут отличаться от ардуиновских, но для внешней программы это будет не заметно.
Теперь я могу взять практически любую библиотеку от ардуины требующую передачу по SPI, допустим для дисплея, и без потерь использовать её.
Для этого вроде название есть. Вы создаёте ядро с API Arduino, так сказать.

Могу тестировать на STM32f401re.
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,407
976
58
Марий-Эл
Для этого вроде название есть. Вы создаёте ядро с API Arduino, так сказать.
Не совсем.
Могу тестировать на STM32f401re.
У меня такого в наличии нет, но попробую.

Столкнулся ещё с такой фигнёй. Ещё не проверил. Есть каталог Startup в нём скрипт. Я пока ещё не понял для чего он. При компиляции не используется. Но используется при отладке. Как сделать так, что бы при отладке подключался нужный скрипт, пока не знаю.

А Ваш МК буду иметь ввиду. Попробую что нибудь написать.
Ещё вопрос. Отладчик есть возможность запустить?
 
  • Лойс +1
Реакции: Matveyugru