传统的STM32开发,使用的是C语言。C++中的一些高级特性,如引用、面向对象等,可以极大地提高代码的可读性和易维护性。
前置条件
开发板:STM32F103C8T6
开发环境:vscode+EIDE插件
编译器:arm-none-eabi-gcc v15.2.0
开发环境的适用方法,可以参考这篇博客:vscode+edie插件配置STM32开发环境,彻底摆脱KEIL
使用方法
还是以上述博客中的项目模板为例:
只需要将 main.c 文件改名为 main.cpp,就可以在main中使用C++特性了。
比如实现一个简单的 class LED :
- class LED
- {
- public:
- LED(GPIO_TypeDef *port, uint16_t pin, bool polarity = false)
- : port_(port), pin_(pin), polarity_(polarity), state_(false)
- {
- }
- void on()
- {
- if (this->polarity_ == true) {
- GPIO_SetBits(this->port_, this->pin_);
- } else {
- GPIO_ResetBits(this->port_, this->pin_);
- }
- this->state_ = true;
- }
- void off()
- {
- if (this->polarity_ == true) {
- GPIO_ResetBits(this->port_, this->pin_);
- } else {
- GPIO_SetBits(this->port_, this->pin_);
- }
- this->state_ = false;
- }
- void toggle()
- {
- if (this->state_ == true) {
- this->off();
- } else {
- this->on();
- }
- }
- bool state() const
- {
- return this->state_;
- }
- private:
- GPIO_TypeDef *port_;
- uint16_t pin_;
- bool polarity_; // true-高电平点亮,false-低电平点亮
- bool state_; // 当前状态:true-点亮,false-灭
- };
复制代码 其余初始化代码不变,定义 LED led{GPIOC, GPIO_PIN_13} 然后将死循环中的反转电平改为调用 led.toggle() 即可。
完整的程序如下所示:
- /*
- * ************************************************
- *
- * STM32 blink gcc demo
- *
- * CPU: STM32F103C8
- * PIN: PA1
- *
- * ************************************************
- */
- #include "stm32f10x.h"
- class LED;
- void delay(int x)
- {
- for (int i = 0; i < x; i++) {
- for (int j = 0; j < 1000; j++)
- __NOP();
- }
- }
- int main()
- {
- GPIO_InitTypeDef gpioDef;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- gpioDef.GPIO_Mode = GPIO_Mode_Out_PP;
- gpioDef.GPIO_Pin = GPIO_Pin_13;
- gpioDef.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOC, &gpioDef);
- auto led = LED{GPIOC, GPIO_Pin_13};
- while (true) {
- led.toggle();
- delay(5000);
- }
- }
复制代码 烧录,可以看到开发板上的LED正常闪烁。
注意事项
中断函数特殊处理
由于C++存在符号修饰特性,因此当定义中断服务函数的时候,一定要显示添加 extern "C" 关键字,否则可能会导致中断异常:
- extern "C" void TIM2_IRQHandler(){
- // your code here
- }
复制代码 一个一劳永逸的方法是,在 stm32f10x_it.h 文件中直接声明好所有的中断函数,ST官方已做好适配:
- /**
- ******************************************************************************
- * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h
- * @author MCD Application Team
- * @version V3.6.0
- * @date 20-September-2021
- * @brief This file contains the headers of the interrupt handlers.
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2011 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* Define to prevent recursive inclusion -------------------------------------*/
- #ifndef __STM32F10x_IT_H
- #define __STM32F10x_IT_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* Includes ------------------------------------------------------------------*/
- #include "stm32f10x.h"
- /* Exported types ------------------------------------------------------------*/
- /* Exported constants --------------------------------------------------------*/
- /* Exported macro ------------------------------------------------------------*/
- /* Exported functions ------------------------------------------------------- */
- /* System exception handlers */
- void NMI_Handler(void);
- void HardFault_Handler(void);
- void MemManage_Handler(void);
- void BusFault_Handler(void);
- void UsageFault_Handler(void);
- void SVC_Handler(void);
- void DebugMon_Handler(void);
- void PendSV_Handler(void);
- void SysTick_Handler(void);
- /* Peripheral interrupt handlers */
- void WWDG_IRQHandler(void);
- void PVD_IRQHandler(void);
- void TAMPER_IRQHandler(void);
- void RTC_IRQHandler(void);
- void FLASH_IRQHandler(void);
- void RCC_IRQHandler(void);
- void EXTI0_IRQHandler(void);
- void EXTI1_IRQHandler(void);
- void EXTI2_IRQHandler(void);
- void EXTI3_IRQHandler(void);
- void EXTI4_IRQHandler(void);
- void DMA1_Channel1_IRQHandler(void);
- void DMA1_Channel2_IRQHandler(void);
- void DMA1_Channel3_IRQHandler(void);
- void DMA1_Channel4_IRQHandler(void);
- void DMA1_Channel5_IRQHandler(void);
- void DMA1_Channel6_IRQHandler(void);
- void DMA1_Channel7_IRQHandler(void);
- void ADC1_2_IRQHandler(void);
- void USB_HP_CAN1_TX_IRQHandler(void);
- void USB_LP_CAN1_RX0_IRQHandler(void);
- void CAN1_RX1_IRQHandler(void);
- void CAN1_SCE_IRQHandler(void);
- void EXTI9_5_IRQHandler(void);
- void TIM1_BRK_IRQHandler(void);
- void TIM1_UP_IRQHandler(void);
- void TIM1_TRG_COM_IRQHandler(void);
- void TIM1_CC_IRQHandler(void);
- void TIM2_IRQHandler(void);
- void TIM3_IRQHandler(void);
- void TIM4_IRQHandler(void);
- void I2C1_EV_IRQHandler(void);
- void I2C1_ER_IRQHandler(void);
- void I2C2_EV_IRQHandler(void);
- void I2C2_ER_IRQHandler(void);
- void SPI1_IRQHandler(void);
- void SPI2_IRQHandler(void);
- void USART1_IRQHandler(void);
- void USART2_IRQHandler(void);
- void USART3_IRQHandler(void);
- void EXTI15_10_IRQHandler(void);
- void RTC_Alarm_IRQHandler(void);
- void USBWakeUp_IRQHandler(void);
- #ifdef __cplusplus
- }
- #endif
- #endif /* __STM32F10x_IT_H */
复制代码 当有 .cpp 文件中需要定义中断服务函数的时候,直接 #include "stm32f10x_it.h" 即可。
STL 适用建议
正常情况下,STL中的各种容器和算法可以正常使用,如 vector 等。但是由于嵌入式环境中内存资源有限,缺少内存管理器,所以 尽量避免使用 vector string 等涉及到动态内存分配的容器,而· array 等不涉及动态内存分配的静态容器可以正常使用。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |