最近要用到C++来写keil工程,要把之前的C工程变成C++工程,好家伙。
学习一下keil怎么建立一个C++工程,还有STM32在C++语言下怎么兼容C。
1.keil工程的魔法棒设置
我这里选择的是版本5,我看网上说要版本6,不是很理解。
然后选择不要使用微库,C++不支持MicroLIB
2.选择编译的方法
把C99Mode选项去掉,然后改成–cpp11
3.把中断函数全部都要加extern “C”
例如
或者在头文件中加上
#ifdef __cplusplus
extern "C" {
#endif
。。。。
。。。。
。。。
。。。
#ifdef __cplusplus
}
#endif
例如
/**
******************************************************************************
* @file Demonstrations/CM4/Inc/stm32h7xx_it.h
* @author MCD Application Team
* @brief This file contains the headers of the interrupt handlers for Cortex-M4.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2018 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32H7xx_IT_H
#define __STM32H7xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
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);
void HSEM2_IRQHandler(void);
void Error_Handler(void);
#ifdef __cplusplus
}
#endif
#endif /* __STM32H7xx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
4.都这里基本上C++的工程例程就建立起来了。
我用到的C++程度不深,可以说是和C没什么区别,
之前C写程序,都喜欢用全局变量,
现在写C++,就要把这个C++文件抽象成一个类,然后需要用到的全局变量都放进类里面。
这个编程思路逻辑我觉得就是C和C++最大的区别。
有时候写着写着就喜欢面向过程了,而C++是面向对象的,意思就是,我的这个函数完成的功能一定是这个对象的某一个行为。
这句话也很难理解,我过几天再来看都会觉得,这博主在写什么鬼。
再通俗一下,就是一个类成员函数里的变量,都必须只能是类里面所需要的,外界不能访问,只能通知这个对象,让这个对象告诉你要访问的东西,这样的类封装是最好的。
可是我现在写的工程几乎就是C。哈哈哈
下面是我i写的一个类,和网上的没法比。我只用到了继承,和一个类的基本功能,
可以看到,毫无C++的特性。。。。
class ADC__BasClass
{
public :
void ADC_DMA_Start_M4(ADC_TypeDef *ADCX);
uint8_t Find_MAX_VAL_POS_M4(uint32_t (*val_Sort),int length,uint8_t chn);
uint8_t Find_MIN_VAL_POS_M4(uint32_t (*val_Sort),int length,uint8_t chn);
void ADC_RegularChnConfig_M4(ADC_HandleTypeDef *hadc, u32 Chn, u32 Rank, u32 SamplingTime);
void ADC_DMA_Init_M4(ADC_HandleTypeDef* hadc);
WORD DichotomySearch(WORD TargetData, BYTE bOrder, const DWORD DataArray[], WORD ArryNum);
private:
};
class ADC1_Class: public ADC__BasClass
{
public:
uint32_t ADC_Average_Val_m4[ADC1_CHANNAL_NUM_m4];
uint8_t ubADCDualConversionComplete ; /* Set into ADC conversion complete callback */
ADC1_Class();
void ADC1_Init_M4();
ADC1_Collect ADC_Collect_Real_Name;
void CalBusBarVoltAndCurr_M4(void);
void CalDC26Voltage_M4(void);
void CalNtcAndPtcTemperature_M4(void);
void ADC1_DATA_Deal_Average_M4(void);
private:
};
extern ADC1_Class ADC1_API;
//以后ADC3负责ADC1的工作,ADC1可能去到M7那里处理电流。
class ADC3_Class: public ADC__BasClass
{
public:
uint32_t ADC3_Average_Val_m4[ADC3_CHANNAL_NUM_m4];
void ADC3_Init_M4();
ADC3_Collect ADC3_Collect_Real_Name;
void Cal_Break_Temperature(void);
void Cal_Bridge_Temperature(void);
void Cal_Motor_Temperature(void);
void Cal_IGBTABC_Temperature(void);
void Cal_5V_Detection (void);
void Cal_Bus_Current(void);
void Cal_Bus_Voltage(void);
void ADC3_DATA_Deal_Average_M4(void);
private:
};
extern ADC3_Class ADC3_API;
然后类成员函数的实现如下
void ADC3_Class::Cal_Break_Temperature(void)
{
static uint32_t dwTime = 0;
uint32_t dwADValTemp;
uint16_t wBrakeTemperature_Val;
// 1S 计算一次温度
if(lwTickCount_M4 >= dwTime + 1000)
{
dwTime = lwTickCount_M4;
//按照查找表方法计算NTC温度,BRAKE模块IGBT温敏电阻
dwADValTemp = ADC3_Average_Val_m4[3]; //最近8次的平均
wBrakeTemperature_Val = DichotomySearch(dwADValTemp, 1, NTCTempArray, 110);
dwBreak_Temp = (int)(wBrakeTemperature_Val + 1);
ADC3_Collect_Real_Name.wBreak_IGTB_temp_m4 = (WORD)(wBrakeTemperature_Val + 1);
}
}
void ADC3_Class::Cal_Bridge_Temperature(void)
{
static uint32_t dwTime = 0;
uint32_t dwADValTemp;
uint16_t wBridgeTemperature_Val;
// 1S 计算一次