疯狂单片机--用C++写STM32程序-STM32PIN

2019-04-15 12:45发布

现单片机已经白菜价了,可用的资源也不断丰富起来. 有一天我突发奇想,用C++写单片机不是更方便.(相信很多人有类似的想法,不过在网上找到的参考资料也太少了) 话说很多编译器本身是支持C++,大部分人认为C++效率C低,我想说的是当年Android刚出来的时候,也受到了很多人的抵触... 手上正好有块STM32开发板,就拿它开刀了: 一.把库中的.C文件改成.CPP       二.定义一个GPIO的类 单片机的helloworld,那就是流水灯.

要是能够简化定义成这样子就好理解了   STM32PIN DS1_N(PF,6);
STM32PIN DS2_N(PF,7);
STM32PIN DS3_N(PF,8);
STM32PIN DS4_N(PF,9); 于是我定义了下面这么一个类   //stm32pin.h #pragma once typedef struct tagGPIO_PIN { uint32_t periph;//eg:RCC_APB2Periph_GPIOF GPIO_TypeDef* port; //eg:GPIOF uint16_t pin; //eg:GPIO_Pin_10 GPIOMode_TypeDef mode; //eg.GPIO_Mode_IN_FLOATING; GPIOSpeed_TypeDef speed; //eg.GPIO_Speed_50MHz }GPIO_PIN; enum STM32_PORT_INDEX { PA=0,PB,PC,PD,PE,PF,PG }; struct { uint32_t p_periph; GPIO_TypeDef* p_port; }PERIPH_PORT[]= { RCC_APB2Periph_GPIOA,GPIOA, RCC_APB2Periph_GPIOB,GPIOB, RCC_APB2Periph_GPIOC,GPIOC, RCC_APB2Periph_GPIOD,GPIOD, RCC_APB2Periph_GPIOE,GPIOE, RCC_APB2Periph_GPIOF,GPIOF, RCC_APB2Periph_GPIOG,GPIOG, }; //简化书写 #define GM_AIN GPIO_Mode_AIN //模拟输入模式 #define GM_IN_FLOATING GPIO_Mode_IN_FLOATING //浮空输入模式 #define GM_IPD GPIO_Mode_IPD //下拉输入模式 #define GM_IPU GPIO_Mode_IPU //上拉输入模式 #define GM_OUT_OD GPIO_Mode_Out_OD //开漏输出模式 #define GM_OUT_PP GPIO_Mode_Out_PP //通用推挽输出模式 #define GM_AFOD GPIO_Mode_AF_OD //复用功能开漏输出 #define GM_AFPP GPIO_Mode_AF_PP //复用功能推挽输出 /*--------------------如何定义STM32PIN--------------------------------------*/ // //eg: // STM32PIN key1(RCC_APB2Periph_GPIOC,GPIOC,GPIO_Pin_1,GM_IN_FLOATING); // STM32PIN pins(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,GPIOC,GPIO_Pin_1|GPIO_Pin_10); // STM32PIN EnTk(PA,0); class STM32PIN { private: GPIO_PIN m_gpio; public: ~STM32PIN() { } STM32PIN() { } STM32PIN( STM32_PORT_INDEX indexPort, uint16_t indexPin, //只能取0~15对应GPIO_Pin_0~GPIO_Pin_15 GPIOMode_TypeDef p_mode=GM_OUT_PP, GPIOSpeed_TypeDef p_speed=GPIO_Speed_50MHz ) //对于输入Speed应为0 { reset(PERIPH_PORT[indexPort].p_periph, PERIPH_PORT[indexPort].p_port, (uint16_t)1<BSRR = m_gpio.pin; } inline void low(void) { //GPIO_ResetBits(m_gpio.port, m_gpio.pin); m_gpio.port->BRR = m_gpio.pin; } inline bool ishigh() { // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET if( m_gpio.port->IDR & m_gpio.pin) { return true; } else { return false; } } inline bool islow() { // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET if( m_gpio.port->IDR & m_gpio.pin) { return false; } else { return true; } } void toggle(uint32_t t=1000,bool bLoop=true) { while(bLoop) { high(); for(int i=0;i 从上面的类,可以看到,让GPIO拉高使用high(),拉使用low(),
为了能产生高效的代码,其中大部分函数使用内联,
将 GPIO_SetBits() GPIO_ResetBits()函数调用改写成寄存器方式
 //GPIO_SetBits(m_gpio.port, m_gpio.pin);
  inline void high(void)
{
m_gpio.port->BSRR = m_gpio.pin;
}
//GPIO_ResetBits(m_gpio.port, m_gpio.pin);
 inline void low(void) {         m_gpio.port->BRR = m_gpio.pin;
 } 于是流水灯的程序就可以写这样子:     //main.cpp #include "stm32pin.h" int main(void) { STM32PIN DS1_N(PF,6); STM32PIN DS2_N(PF,7); STM32PIN DS3_N(PF,8); STM32PIN DS4_N(PF,9); uint8_t i=0; while(true) { i++; i & 0x01 ? DS1_N.low():DS1_N.high(); i & 0x02 ? DS2_N.low():DS2_N.high(); i & 0x04 ? DS3_N.low():DS3_N.high(); i & 0x08 ? DS4_N.low():DS4_N.high(); for(uint32_t i=0;i<10000000;i++); } }
  接着让USER2键按下,流水灯反过来计数,只要这样定义   STM32PIN USER2(PD,3,GM_IN_FLOATING); 使用的时候这样写 if( USER2.islow() )  { //要执行的动作 }     #include "stm32pin.h" int main(void) { STM32PIN DS1_N(PF,6); STM32PIN DS2_N(PF,7); STM32PIN DS3_N(PF,8); STM32PIN DS4_N(PF,9); STM32PIN USER2(PD,3,GM_IN_FLOATING); uint8_t i=0; while(true) { i++; if( USER2.islow() ) { i & 0x08 ? DS1_N.low():DS1_N.high(); i & 0x04 ? DS2_N.low():DS2_N.high(); i & 0x02 ? DS3_N.low():DS3_N.high(); i & 0x01 ? DS4_N.low():DS4_N.high(); } else { i & 0x01 ? DS1_N.low():DS1_N.high(); i & 0x02 ? DS2_N.low():DS2_N.high(); i & 0x04 ? DS3_N.low():DS3_N.high(); i & 0x08 ? DS4_N.low():DS4_N.high(); } for(uint32_t i=0;i<10000000;i++); } }
未完待续....