花了点时间整理了一下以前在eclipse环境下使用C++写的stm32程序,此篇内容为GPIO操作部分,其他部分后续有时间会逐步放到csdn博客中分享出来,免得以后从事其他行业工作了,荒废了以前那么努力摸索出来的宝贵经验
1. 使用C++写stm32程序时需要考虑的几个问题
- stm32 属于配置相对很低的芯片,比不得PC机使用的CPU,具有相当有限的内存资源和闪存资源
- stm32 开发大多属于裸机开发,即使是使用到了UCOSIII等操作系统,开发程序的流程和PC端流程也完全不一样,PC端软件开发只需要开发出软件相关的部分,无需关心操作系统,但嵌入式不一样,即使有了操作系统支持,也需要直接将操作系统的源码一起编译,然后一起烧录,并不能通过写单个程序来扩展功能
- stm32 由于没有高级内存管理单元的支持,也没有操作系统软内存管理系统,因此不能使用任何动态分配内存的机制,除非自己使用高效算法实现自己的内存管理系统(如malloc, free). C++标准库里面的api基本都是动态内存,因此在开发裸机stm32程序时,请不要考虑使用任何STL里面的接口(你是大牛, 能自己高效无误实现allocator的情况下除外)
2. 封装GPIO需要考虑的几个问题
- GPIO 构造时的初始化
- GPIO 的基本配置
- GPIO 的常用操作
2.1 GPIO构造时的初始化
- 需要知道使用的哪个端口(以及哪个管脚)
- 需要知道使用的哪种模式(输入还是输出? 怎样的输入输出?)
所以我们给GPIO类的构造函数使用了俩个参数, 端口号, 管脚编号, 然后在构造函数内,使能该端口的时钟
2.2 GPIO的基本配置
- 配置是输入模式还是输出模式
- 如果是输入模式,选择何种输入模式
- 如果是输出模式,选择何种输出模式
2.3 GPIO常用操作
- 给端口输出某个值
- 给端口的某个管脚输出某个值
- 读端口的输入值
- 读端口某个管脚的输入值
- 读端口的输出值
- 读端口的某个管脚输出值
- 给端口(或某几个管脚)置位
- 给端口(或某几个管脚)复位
GPIO类封装的示例代码(stm32f10x系列)
头文件
/*
* GPIO.h
*
* Created on: 2018年3月19日
* Author: oyoung
*/
#ifndef GPIO_H_
#define GPIO_H_
namespace stm32 {
extern int log2(unsigned int value);
class GPIO {
public:
typedef enum {
Port_A,Port_B,Port_C,Port_D,Port_E,Port_F,Port_G
} Port;
typedef enum {
Pin_0 = 0x0001,
Pin_1 = 0x0002,
Pin_2 = 0x0004,
Pin_3 = 0x0008,
Pin_4 = 0x0010,
Pin_5 = 0x0020,
Pin_6 = 0x0040,
Pin_7 = 0x0080,
Pin_8 = 0x0100,
Pin_9 = 0x0200,
Pin_10 = 0x0400,
Pin_11 = 0x0800,
Pin_12 = 0x1000,
Pin_13 = 0x2000,
Pin_14 = 0x4000,
Pin_15 = 0x8000,
Pin_Low8 = 0x00ff,
Pin_High8 = 0xff00,
Pin_All = 0xffff
} Pin;
typedef enum {
Mode_Input,
Mode_Output_10MHz,
Mode_Output_2MHz,
Mode_Output_50MHz
} Mode;
typedef enum {
IOMode_I_Analog,
IOMode_I_Float,
IOMode_I_Pull_UpDown,
IOMode_I_Reserve,
IOMode_O_PushPull = IOMode_I_Analog,
IOMode_O_OpenDrain = IOMode_I_Float,
IOMode_O_Multiplex_PushPull = IOMode_I_Pull_UpDown,
IOMode_O_Multiplex_OpenDrain = IOMode_I_Reserve
} IOMode;
GPIO(Port);
GPIO(Port port, Pin pin);
/**
* 设置输出值
*/
void set