Чт янв 24, 2019 17:00:51
Чт янв 24, 2019 17:46:28
Чт янв 24, 2019 18:53:04
Чт янв 24, 2019 18:59:49
GCC например. В отличие от компилятора кейла, полностью бесплатный и без ограничений.Satarych писал(а):Какие вообще существуют компиляторы для ARM?
Чт янв 24, 2019 22:38:41
Пт янв 25, 2019 20:05:37
Вообще на Keil'е сидел только потому, что им пользовался человек, который меня с STM'ками знакомил. Так больше исторически сложилось) Попробовал VS+VisualGDB, вполне неплохо, пока всё нравится. Есть только одно но, у меня другой товарищ на Линуксе сидит и пользуется Эклипсом. Я его тоже попробую, но почитав отзывы, не проникся. Раз уж решился менять IDE, то хотелось бы, чтоб она на Линуксе заводилась, чтоб в одной среде работать. Может кто подскажет ещё мультиплатформенные варианты, кроме Эклипса?VladislavS писал(а):Satarych, если решил С++ заняться, то выкидывай Keil, его туда толком не завезли. Переходи на что-нибудь на основе GCC, там C++17 отлично работает. Посмотри VisualGDB, например.
Как по мне, добавлять заголовочники в проект это уже совсем костыли, но вдруг кому пригодится.If user wants C++ code to be evaluated inside a header file, there are two ways. If a cpp file includes the header file, then it will be evaluated as C++. Alternatively, go to the Project dialog and right click on a source group folder. Add the header file as an existing file. Then in the Project dialog, right click on the file. Go to Options for File... => Properties tab => File Type field. Set the type to C++ Source file. User may receive a fatal error message, if DSC is turned on and the file type is not set to C++.
Пт янв 25, 2019 22:17:09
Под линукс не так много IDE и почти все они на эклипсе. Посмотрите еще бесплатную IDE EmBitz. Она для винды, но под вайном в линуксе скорее всего будет работать, исключая разве что отладку, потому что нужен доступ к USB, и под вайном не факт что заработает.Satarych писал(а):Раз уж решился менять IDE, то хотелось бы, чтоб она на Линуксе заводилась
Сб янв 26, 2019 06:08:16
Сб янв 26, 2019 09:09:39
Сб янв 26, 2019 09:57:41
Пн янв 28, 2019 13:58:55
Можно посмотреть стек вызовов, а также просматривать и модифицировать регистры и память, ставить и удалять брейкпойнты, вычислять выражения и всё то же самое, что обычно при отладке можно.
Пн янв 28, 2019 14:14:08
Пн янв 28, 2019 14:40:07
Вт янв 29, 2019 17:15:22
Вт янв 29, 2019 17:36:40
Сб фев 02, 2019 22:11:32
// Возможные режимы работы Gpio в Stm32f10x
enum class Stm32GpioMode
{
// Inputs
Analog_Inp = 0x0, // 0b0000
Floating_Inp = 0x4, // 0b0100
Pull_Dn_Inp = 0x08, // 0b01000
Pull_Up_Inp = 0x18, // 0b11000
// Output 10MHz
GP_PP_10MHzOut = 0x1, // 0b0001
GP_OD_10MHzOut = 0x5, // 0b0101
AF_PP_10MHzOut = 0x9, // 0b1001
AF_OD_10MHzOut = 0xD, // 0b1101
// Outputs 2MHz
GP_PP_2MHzOut = 0x2, // 0b0010
GP_OD_2MHzOut = 0x6, // 0b0110
AF_PP_2MHzOut = 0xA, // 0b1010
AF_OD_2MHzOut = 0xE, // 0b1110
// Outputs 50MHz
GP_PP_50MHzOut = 0x3, // 0b0011
GP_OD_50MHzOut = 0x7, // 0b0111
AF_PP_50MHzOut = 0xB, // 0b1011
AF_OD_50MHzOut = 0xF, // 0b1111
// Исходное состояние выхода
log0_InitOut = 0x00, // 0b00000
log1_InitOut = 0x10 // 0b10000
};
class Stm32Gpio
{
public:
Stm32Gpio() = delete;
Stm32Gpio(GPIO_TypeDef *const gpio, const uint16_t pinMask);
void init(Stm32GpioMode gpioMode) const; // Функция настройки (инициализации) пинов GPIO
void set() const; // Функция включения ножки на лог "1"
void clr() const; // Функция выключения ножки на лог "0"
void tgl() const; // Функция изменяет состояние ножки на противоположное
bool get() const; // Функция возвращает текущее состояние ножек
private :
GPIO_TypeDef *const m_gpio;
const uint16_t m_pinMask;
};
// Конструктор
Stm32Gpio::Stm32Gpio(GPIO_TypeDef *const gpio, const uint16_t pinMask)
: m_gpio (gpio), m_pinMask (pinMask) {}
// Функция настройки (инициализации) ножек порта GPIO
void Stm32Gpio::init(Stm32GpioMode gpioMode) const
{
// Включаем тактирование порта
//using namespace stm32Rcc_Ns;
//coreRcc.enableHardwareClock (m_gpio);
// !NOTE! Временная затычка, пока не починю верхние 2 строки
if (m_gpio == GPIOA) RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
if (m_gpio == GPIOB) RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
if (m_gpio == GPIOC) RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
if (m_gpio == GPIOD) RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
if (m_gpio == GPIOE) RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;
//if (m_gpio == GPIOF) RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
//if (m_gpio == GPIOG) RCC->APB2ENR |= RCC_APB2ENR_IOPGEN;
// 5-й бит аргумента gpioMode содержит исходное состояние ножек
// Если там лог "1" - инициализируем на лог "1"
if((uint32_t)gpioMode & 0x10)
m_gpio->BSRR = m_pinMask;
// Иначе, если лог "0" - инициализируем на лог "0"
else
m_gpio->BRR = m_pinMask;
// Стираем 5-й бит в аргументе pinMode
gpioMode = (Stm32GpioMode)((uint32_t)gpioMode & 0xF);
// Перебираем первые 8 ножек
for(uint8_t pinNum = 0 ; pinNum < 8 ; ++pinNum)
{
// Если нужно настроить данную ножку
if(m_pinMask & (0x1 << pinNum))
{
// Настройки каждой ножки занимают по 4 бита в регистре
// Преобразуем номер ножки в необходимое смещение в регистре
// Зачищаем редактируемую часть регистра
m_gpio->CRL &= ~(0xF << (pinNum * 4));
// Выставляем нужный режим работы ножки
m_gpio->CRL |= ((uint32_t)gpioMode << (pinNum * 4));
}
}
// Перебираем последние 8 ножек
for(uint8_t pinNum = 0 ; pinNum < 8 ; ++pinNum)
{
// Если нужно настроить данную ножку
if(m_pinMask & (0x1 << (pinNum + 8)))
{
// Настройки каждой ножки занимают по 4 бита в регистре
// Преобразуем номер ножки в необходимое смещение в регистре
// Зачищаем редактируемую часть регистра
m_gpio->CRH &= ~(0xF << (pinNum * 4));
// Выставляем нужный режим работы пина
m_gpio->CRH |= ((uint32_t)gpioMode << (pinNum * 4));
}
}
}
// Функция включения ножки на лог "1"
void Stm32Gpio::set() const
{
m_gpio->BSRR = m_pinMask;
}
// Функция выключения ножки на лог "0"
void Stm32Gpio::clr() const
{
m_gpio->BRR = m_pinMask;
}
// Функция изменяет состояние ножки на противоположное
void Stm32Gpio::tgl() const
{
m_gpio->ODR ^= m_pinMask;
}
// Функция возвращает текущее состояние ножек
bool Stm32Gpio::get() const
{
return m_gpio->IDR & m_pinMask;
}
const Stm32Gpio led0 (GPIOA, 1<<8);
const Stm32Gpio led1 (GPIOD, 1<<2);
int main()
{
led0.init (Stm32GpioMode::GP_PP_2MHzOut);
led1.init (Stm32GpioMode::GP_PP_2MHzOut);
for (;;)
{
led0.clr();
led1.set();
Delay();
led0.set();
led1.clr();
Delay();
}
}
// Описываем структуру, идентичную нашему классу по содержанию переменных
struct GpioStruct
{
GPIO_TypeDef *m_gpio;
uint16_t m_pinMask;
};
// Создаём её глобальный константный экземпляр
const GpioStruct led1 = {GPIOD, 1<<2};
// Довольно варварски преобразуем тип и подсовываем вместо исходного класса
int main()
{
led0.init(Stm32GpioMode::GP_PP_2MHzOut);
((const Stm32Gpio*)&led1)->init(Stm32GpioMode::GP_PP_2MHzOut);
for (;;)
{
led0.clr();
((const Stm32Gpio*)&led1)->set();
Delay();
led0.set();
((const Stm32Gpio*)&led1)->clr();
Delay();
}
}
Сб фев 02, 2019 22:58:34
template<uint32_t gpioBase, uint32_t pin, uint32_t af>
class PinT
{
public:
static constexpr uint32_t pinMask = 1 << pin;
static _always_inline_ auto base() { return reinterpret_cast<GPIO_TypeDef*>(gpioBase); }
PinT() {}
PinT(PinMode mode) { ... }
static void set() { base()->BSRR = pinMask; }
static void clear() { base()->BSRR = 0x10000 << pin; }
static void toggle() { base()->BSRR = (0x10000 << pin) | (~base()->ODR & pinMask); }
static void write(bool data) { base()->BSRR = (0x10000 | data) << pin; }
static bool read() { return base()->IDR & pinMask; }
};
template<uint32_t pin, uint32_t af = 0>
using PinA = PinT<GPIOA_BASE, pin, af>;
template<uint32_t pin, uint32_t af = 0>
using PinB = PinT<GPIOB_BASE, pin, af>;
PinA<5> led1;
using led2 = PinB<3>;
led1.set();
led2::toggle();
// Функция изменяет состояние ножки на противоположное
void Stm32Gpio::tgl() const
{
m_gpio->ODR ^= m_pinMask;
}
Вс фев 03, 2019 14:10:07
// Функция изменяет состояние ножки на противоположное
void Stm32Gpio::tgl() const
{
m_gpio->ODR ^= m_pinMask;
}
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
class Stm32Gpio
{
public:
void init(Stm32GpioMode gpioMode) const; // Функция настройки (инициализации) пинов GPIO
virtual void set() const; // Функция включения ножки на лог "1"
virtual void clr() const; // Функция выключения ножки на лог "0"
virtual void tgl() const; // Функция изменяет состояние ножки на противоположное
virtual bool get() const; // Функция возвращает текущее состояние ножек
};
// Функция настройки (инициализации) ножек порта GPIO
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
void Stm32Gpio <m_gpio, m_pinMask>::init(Stm32GpioMode gpioMode) const
{
// Включаем тактирование порта
//using namespace stm32Rcc_Ns;
//coreRcc.enableHardwareClock (m_gpio);
// !NOTE! Временная затычка, пока не починю верхние 2 строки
if (m_gpio == GPIOA) RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
if (m_gpio == GPIOB) RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
if (m_gpio == GPIOC) RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
if (m_gpio == GPIOD) RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
if (m_gpio == GPIOE) RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;
//if (m_gpio == GPIOF) RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
//if (m_gpio == GPIOG) RCC->APB2ENR |= RCC_APB2ENR_IOPGEN;
// 5-й бит аргумента gpioMode содержит исходное состояние ножек
// Если там лог "1" - инициализируем на лог "1"
if((uint32_t)gpioMode & 0x10)
m_gpio->BSRR = m_pinMask;
// Иначе, если лог "0" - инициализируем на лог "0"
else
m_gpio->BRR = m_pinMask;
// Стираем 5-й бит в аргументе pinMode
gpioMode = (Stm32GpioMode)((uint32_t)gpioMode & 0xF);
// Перебираем первые 8 ножек
for(uint8_t pinNum = 0 ; pinNum < 8 ; ++pinNum)
{
// Если нужно настроить данную ножку
if(m_pinMask & (0x1 << pinNum))
{
// Настройки каждой ножки занимают по 4 бита в регистре
// Преобразуем номер ножки в необходимое смещение в регистре
// Зачищаем редактируемую часть регистра
m_gpio->CRL &= ~(0xF << (pinNum * 4));
// Выставляем нужный режим работы ножки
m_gpio->CRL |= ((uint32_t)gpioMode << (pinNum * 4));
}
}
// Перебираем последние 8 ножек
for(uint8_t pinNum = 0 ; pinNum < 8 ; ++pinNum)
{
// Если нужно настроить данную ножку
if(m_pinMask & (0x1 << (pinNum + 8)))
{
// Настройки каждой ножки занимают по 4 бита в регистре
// Преобразуем номер ножки в необходимое смещение в регистре
// Зачищаем редактируемую часть регистра
m_gpio->CRH &= ~(0xF << (pinNum * 4));
// Выставляем нужный режим работы пина
m_gpio->CRH |= ((uint32_t)gpioMode << (pinNum * 4));
}
}
}
// Функция включения ножки на лог "1"
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
void Stm32Gpio <m_gpio, m_pinMask>::set() const
{
m_gpio->BSRR = m_pinMask;
}
// Функция выключения ножки на лог "0"
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
void Stm32Gpio <m_gpio, m_pinMask>::clr() const
{
m_gpio->BRR = m_pinMask;
}
// Функция изменяет состояние ножки на противоположное
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
void Stm32Gpio <m_gpio, m_pinMask>::tgl() const
{
m_gpio->ODR ^= m_pinMask;
}
// Функция возвращает текущее состояние ножек
template <GPIO_TypeDef *m_gpio, uint16_t m_pinMask>
bool Stm32Gpio <m_gpio, m_pinMask>::Stm32Gpio::get() const
{
return m_gpio->IDR & m_pinMask;
}
Stm32Gpio <GPIOD, 1<<2> led1;
'(GPIO_TypeDef*)((1073741824 + 65536) + 5120)' is not a valid template argument for 'GPIO_TypeDef*' because it is not the address of a variable
Вс фев 03, 2019 14:23:54
Почему? Массив структур имеет смысл. Лучше чем множество дефайнов и код короче и понятней.Satarych писал(а):нормальные люди так делать не будут
Вс фев 03, 2019 14:38:55
Почему? Массив структур имеет смысл. Лучше чем множество дефайнов и код короче и понятней.Satarych писал(а):нормальные люди так делать не будут