当前位置:   article > 正文

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

stm32 c++

现单片机已经白菜价了,可用的资源也不断丰富起来.

有一天我突发奇想,用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);

于是我定义了下面这么一个类

 

  1. //stm32pin.h
  2. #pragma once
  3. typedef struct tagGPIO_PIN
  4. {
  5. uint32_t periph;//eg:RCC_APB2Periph_GPIOF
  6. GPIO_TypeDef* port; //eg:GPIOF
  7. uint16_t pin; //eg:GPIO_Pin_10
  8. GPIOMode_TypeDef mode; //eg.GPIO_Mode_IN_FLOATING;
  9. GPIOSpeed_TypeDef speed; //eg.GPIO_Speed_50MHz
  10. }GPIO_PIN;
  11. enum STM32_PORT_INDEX
  12. {
  13. PA=0,PB,PC,PD,PE,PF,PG
  14. };
  15. struct
  16. {
  17. uint32_t p_periph;
  18. GPIO_TypeDef* p_port;
  19. }PERIPH_PORT[]=
  20. {
  21. RCC_APB2Periph_GPIOA,GPIOA,
  22. RCC_APB2Periph_GPIOB,GPIOB,
  23. RCC_APB2Periph_GPIOC,GPIOC,
  24. RCC_APB2Periph_GPIOD,GPIOD,
  25. RCC_APB2Periph_GPIOE,GPIOE,
  26. RCC_APB2Periph_GPIOF,GPIOF,
  27. RCC_APB2Periph_GPIOG,GPIOG,
  28. };
  29. //简化书写
  30. #define GM_AIN GPIO_Mode_AIN //模拟输入模式
  31. #define GM_IN_FLOATING GPIO_Mode_IN_FLOATING //浮空输入模式
  32. #define GM_IPD GPIO_Mode_IPD //下拉输入模式
  33. #define GM_IPU GPIO_Mode_IPU //上拉输入模式
  34. #define GM_OUT_OD GPIO_Mode_Out_OD //开漏输出模式
  35. #define GM_OUT_PP GPIO_Mode_Out_PP //通用推挽输出模式
  36. #define GM_AFOD GPIO_Mode_AF_OD //复用功能开漏输出
  37. #define GM_AFPP GPIO_Mode_AF_PP //复用功能推挽输出
  38. /*--------------------如何定义STM32PIN--------------------------------------*/
  39. // //eg:
  40. // STM32PIN key1(RCC_APB2Periph_GPIOC,GPIOC,GPIO_Pin_1,GM_IN_FLOATING);
  41. // STM32PIN pins(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,GPIOC,GPIO_Pin_1|GPIO_Pin_10);
  42. // STM32PIN EnTk(PA,0);
  43. class STM32PIN
  44. {
  45. private:
  46. GPIO_PIN m_gpio;
  47. public:
  48. ~STM32PIN()
  49. {
  50. }
  51. STM32PIN()
  52. {
  53. }
  54. STM32PIN( STM32_PORT_INDEX indexPort,
  55. uint16_t indexPin, //只能取0~15对应GPIO_Pin_0~GPIO_Pin_15
  56. GPIOMode_TypeDef p_mode=GM_OUT_PP,
  57. GPIOSpeed_TypeDef p_speed=GPIO_Speed_50MHz ) //对于输入Speed应为0
  58. {
  59. reset(PERIPH_PORT[indexPort].p_periph,
  60. PERIPH_PORT[indexPort].p_port,
  61. (uint16_t)1<<indexPin,//根据GPIO_Pin_x对应规则
  62. p_mode,
  63. p_speed );
  64. }
  65. STM32PIN( uint32_t p_periph,
  66. GPIO_TypeDef* p_port,
  67. uint16_t p_pins, //可以或上多引脚
  68. GPIOMode_TypeDef p_mode=GPIO_Mode_Out_PP,
  69. GPIOSpeed_TypeDef p_speed=GPIO_Speed_50MHz ) //对于输入Speed应为0
  70. {
  71. reset( p_periph,
  72. p_port,
  73. p_pins, //可以或上多引脚
  74. p_mode,
  75. p_speed );
  76. }
  77. void reset( GPIOMode_TypeDef p_mode=GPIO_Mode_Out_PP )
  78. {
  79. if(m_gpio.mode==p_mode)return;
  80. reset( m_gpio.periph,
  81. m_gpio.port,
  82. m_gpio.pin, //可以或上多引脚
  83. p_mode,
  84. m_gpio.speed );
  85. m_gpio.mode=p_mode;
  86. }
  87. void reset( uint32_t p_periph,
  88. GPIO_TypeDef* p_port,
  89. uint16_t p_pins, //可以或上多引脚,如片外RAM扩展的定义
  90. GPIOMode_TypeDef p_mode=GPIO_Mode_Out_PP,
  91. GPIOSpeed_TypeDef p_speed=GPIO_Speed_50MHz )
  92. {
  93. m_gpio.periph = p_periph;
  94. m_gpio.port = p_port;
  95. m_gpio.pin = p_pins;
  96. m_gpio.mode=p_mode;
  97. m_gpio.speed=p_speed;
  98. GPIO_InitTypeDef tmp_InitType;//临时产生
  99. tmp_InitType.GPIO_Pin= m_gpio.pin ;
  100. tmp_InitType.GPIO_Mode=m_gpio.mode;
  101. tmp_InitType.GPIO_Speed=m_gpio.speed;
  102. RCC_APB2PeriphClockCmd( m_gpio.periph, ENABLE );
  103. GPIO_Init( m_gpio.port ,&tmp_InitType);
  104. }
  105. inline bool get(void)
  106. {
  107. if( ishigh() )
  108. {
  109. return true;
  110. }
  111. else
  112. {
  113. return false;
  114. }
  115. }
  116. inline void set(bool bs)
  117. {
  118. if(bs)
  119. {
  120. high();//GPIO_SetBits(m_gpio.port, m_gpio.pin);
  121. }
  122. else
  123. {
  124. low();//GPIO_ResetBits(m_gpio.port, m_gpio.pin);
  125. }
  126. }
  127. inline void invert(void)
  128. {
  129. if ( ishigh() )
  130. {
  131. low();//GPIO_ResetBits(m_gpio.port, m_gpio.pin);
  132. }
  133. else
  134. {
  135. high();//GPIO_SetBits(m_gpio.port, m_gpio.pin);
  136. }
  137. }
  138. inline void high(void)
  139. {
  140. //GPIO_SetBits(m_gpio.port, m_gpio.pin);
  141. m_gpio.port->BSRR = m_gpio.pin;
  142. }
  143. inline void low(void)
  144. {
  145. //GPIO_ResetBits(m_gpio.port, m_gpio.pin);
  146. m_gpio.port->BRR = m_gpio.pin;
  147. }
  148. inline bool ishigh()
  149. {
  150. // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET
  151. if( m_gpio.port->IDR & m_gpio.pin)
  152. {
  153. return true;
  154. }
  155. else
  156. {
  157. return false;
  158. }
  159. }
  160. inline bool islow()
  161. {
  162. // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET
  163. if( m_gpio.port->IDR & m_gpio.pin)
  164. {
  165. return false;
  166. }
  167. else
  168. {
  169. return true;
  170. }
  171. }
  172. void toggle(uint32_t t=1000,bool bLoop=true)
  173. {
  174. while(bLoop)
  175. {
  176. high();
  177. for(int i=0;i<t;i++);
  178. low();
  179. for(int i=0;i<t;i++);
  180. }
  181. }
  182. };

从上面的类,可以看到,让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;
 }

于是流水灯的程序就可以写这样子:

 

 

  1. //main.cpp
  2. #include "stm32pin.h"
  3. int main(void)
  4. {
  5. STM32PIN DS1_N(PF,6);
  6. STM32PIN DS2_N(PF,7);
  7. STM32PIN DS3_N(PF,8);
  8. STM32PIN DS4_N(PF,9);
  9. uint8_t i=0;
  10. while(true)
  11. {
  12. i++;
  13. i & 0x01 ? DS1_N.low():DS1_N.high();
  14. i & 0x02 ? DS2_N.low():DS2_N.high();
  15. i & 0x04 ? DS3_N.low():DS3_N.high();
  16. i & 0x08 ? DS4_N.low():DS4_N.high();
  17. for(uint32_t i=0;i<10000000;i++);
  18. }
  19. }


 

接着让USER2键按下,流水灯反过来计数,只要这样定义

 

STM32PIN USER2(PD,3,GM_IN_FLOATING);

使用的时候这样写

if( USER2.islow() ) 

{

//要执行的动作

}

 

 

  1. #include "stm32pin.h"
  2. int main(void)
  3. {
  4. STM32PIN DS1_N(PF,6);
  5. STM32PIN DS2_N(PF,7);
  6. STM32PIN DS3_N(PF,8);
  7. STM32PIN DS4_N(PF,9);
  8. STM32PIN USER2(PD,3,GM_IN_FLOATING);
  9. uint8_t i=0;
  10. while(true)
  11. {
  12. i++;
  13. if( USER2.islow() )
  14. {
  15. i & 0x08 ? DS1_N.low():DS1_N.high();
  16. i & 0x04 ? DS2_N.low():DS2_N.high();
  17. i & 0x02 ? DS3_N.low():DS3_N.high();
  18. i & 0x01 ? DS4_N.low():DS4_N.high();
  19. }
  20. else
  21. {
  22. i & 0x01 ? DS1_N.low():DS1_N.high();
  23. i & 0x02 ? DS2_N.low():DS2_N.high();
  24. i & 0x04 ? DS3_N.low():DS3_N.high();
  25. i & 0x08 ? DS4_N.low():DS4_N.high();
  26. }
  27. for(uint32_t i=0;i<10000000;i++);
  28. }
  29. }


未完待续....

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/1004308
推荐阅读
相关标签
  

闽ICP备14008679号