STM32实战三 C++ IO.cpp

这一章开始编写代码,主要是两个方面,一是C++,二是进行简单的IO封装。其它教程一般是用C语言,从按键或LED灯开始,比较直观,容易上手,但与实际应用有一定的区别,这里要做的是实用控制程序,开始就比较正规,C++是发展趋势,所以就从这里开始。

说是C++,实际是C和C++的混合程序,系统提供的都是C,新写的代码是C++,先从简单的IO开始,添加两个文件IO.cpp和IO.h代码如下:

IO.h

#ifndef __IO__
#define __IO__

extern "C" {	// 按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段
#pragma diag_remark 368		//消除 warning: #368-D: class "<unnamed>" defines no constructor to initialize the following:

#include "stm32f10x.h"

#pragma diag_default 368	// 恢复368号警告
}

// 通用IO
class IO
{
// Construction
public:
	IO(GPIO_TypeDef* GPIOx, u16 nPin, GPIOMode_TypeDef GPIO_Mode, u16 nLevel);	// 输出时设置初始电平,0低,1高,其它不设置
		
// Properties
public:
  GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_TypeDef* m_GPIOx;
	u16 m_nPin;

private:

// Methods
public:
		
// Overwrite
public:
};

#endif

IO.cpp

/**
  ******************************************************************************
  * @file			IO.cpp
  * @author		Mr. Hu
  * @version	V1.0.0 STM32F103VET6
  * @date			05/19/2019
  * @brief		通用端口初始化
	*					
  ******************************************************************************
  * @remarks
  *
  */ 
	
extern "C" {	// 兼容C,按C语言编译,Keil5中的包含文件已经加入了C++兼容,不用再加这一段
#pragma diag_remark 368			//消除 warning:  #368-D: class "<unnamed>" defines no constructor to initialize the following:

#include "stm32f10x_tim.h"

#pragma diag_default 368	// 恢复368号警告
}

#include "IO.h"

/**
  * @date		05/19/2019
  * @brief  初始化端口.
  * @param	GPIOx: where x can be (A..G) to select the GPIO peripheral.
  * @param	nPin_x: specifies the port bits to be written.
  *   This parameter can be any combination of nPin_x where 
  *   x can be (0..15).
  * @param	GPIO_Mode: 输入输出模式.
  * @param	nLevel: 输出时初始电平0低,1高,其它无效,初始化端口之前设置,避免开机跳动.
  * @retval None
  */
IO::IO(GPIO_TypeDef* GPIOx, u16 nPin_x,	GPIOMode_TypeDef GPIO_Mode, u16 nLevel)
	: m_GPIOx( GPIOx )
	, m_nPin( nPin_x )
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(nPin_x));

	u32 RCC_APB2Periph_GPIOx =	// 获取对应的RCC参数
		GPIOx != GPIOA ? GPIOx != GPIOB ? GPIOx != GPIOC ? GPIOx != GPIOD ? GPIOx != GPIOE
		? 0 : RCC_APB2Periph_GPIOE : RCC_APB2Periph_GPIOD : RCC_APB2Periph_GPIOC : RCC_APB2Periph_GPIOB : RCC_APB2Periph_GPIOA;

	// 使能端口, 开启按键端口时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE);
	
	// 先设置输出状态,避免开机时跳动。
	if(nLevel == 0)
		GPIO_ResetBits(GPIOx, nPin_x);	// 设置低电平
	else if(nLevel == 1)
		GPIO_SetBits(GPIOx, nPin_x);		// 设置高电平
	// 输入状态不设置
	
	// 配置端口,用最低的采样频率,过滤高频干扰,延长寿命,需要高频时在外部重设
  GPIO_InitStructure.GPIO_Pin = nPin_x;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode;       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;	// 用最低的采样频率
  GPIO_Init(GPIOx, &GPIO_InitStructure);  					// 初始化端口
}

所有与C语言有关的代码用extern "C" { ... ... } 包括起来,告诉编译器是C语言,只能从C++中调用C语言,不能从C中调用C++。 

还有一个要改动的地方,stm32f10x.h 中240行,原语句是 typedef enum {FALSE = 0, TRUE = !FALSE} bool; 修改成:

// C++ 编译时出现错误:..\CMSIS\stm32f10x.h(240): error:  #65: expected a ";"
// 增加C++兼容代码,如果是C++用BOOL,否则用原来的bool
#ifdef __cplusplus
	typedef enum {FALSE = 0, TRUE = !FALSE} BOOL;
#else
	typedef enum {FALSE = 0, TRUE = !FALSE} bool;
#endif

需要说明的是,上面的封装不太完善,勉强能用,以后再修改。

STM32实战系列源码,按键/定时器/PWM/ADC/DAC/DMA/滤波
STM32实战一 初识单片机
STM32实战二 新建工程
STM32实战三 C++ IO.cpp
STM32实战四 定时器和按键
STM32实战五 板载LED显示数据
STM32实战六 PWM加移相正交
STM32实战七 数字滤波
STM32实战八 DAC/ADC
STM32实战九 编码器
STM32开发过程的常见问题

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值