你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 C++开发

[复制链接]
蓝凌风 发布时间:2016-4-21 20:28
  每次写代码的时候,写外设的初始化都要去复制已经写好的或者是官方的例程,再根据自己的需求来修改,重复性的工作太多,就想到用C++来封装下STM32的库函数,顺便学习下C++,感受下面向对象的强大。
    硬件平台:STM32F4-Discovery
    开发平台:MDK5.14(本来是用VS2013 +VisualGDB的,想到坛友基本都是用MDK的,又改成MDK)
   先看Main
  1. #include "system.h"

  2. System *stm32f407;//系统接口指针

  3. void btnhandle(void *arg)  //按键回调处理函数
  4. {
  5.          delay->delay_ms(20);
  6.         if (stm32f407->btn->ReadData() == true)
  7.                 stm32f407->led2->Toggle();
  8. }

  9. void tim6handle(void *arg)  //定时器中断处理函数
  10. {
  11.         stm32f407->led2->Toggle();
  12. }

  13. int main()
  14. {
  15.         stm32f407 = new System;//构建系统接口类
  16.         stm32f407->tim2->startIT((void*)tim6handle, NULL);//调用TIM类的中断启动函数,只要传入中断回调函数实现自己的功能,并不需要知道中断是要怎么处理的
  17.         uint8_t recvdata[100];
  18.   for (;;)
  19.   {
  20.           stm32f407->led1->Toggle();//在system中初始化,就可以直接调用类函数
  21.           if (true == stm32f407->Debug->IsGetRecv)//串口自动接收标志
  22.           {
  23.                   stm32f407->Debug->RecvData(recvdata);//串口接收函数,传入Buffer,得到接收的数据
  24.                   stm32f407->Debug->SendData(recvdata, stm32f407->Debug->RecvDataLen, 100);
  25.           }
  26.           delay->delay_ms(500);
  27.   }
  28. }
复制代码

    再看System类的初始化
  1. void System::init()
  2. {
  3.         HAL_Init();
  4.         SystemClock_Config();
  5. //外设初始化
  6.   delay = new timerdelay;                //系统延时初始
  7.         Debug = new Usart(USART3, 115200, Usart::USART_IT, 200); //Debug 串口输出初始化,只要传入用的串口号,跟波特率,传输的模式,还有接收Buffer的大小,就可以完成初始化
  8.         led1 = new LED(GPIOD, GPIO_PIN_14, true, LED::highlevel);//LED类,继承OutputPort类,只要传入LED对应的GPIO,跟Pin,还有LED电平控制,就可以完成初始化
  9.         led2 = new LED(GPIOD, GPIO_PIN_12, false, LED::highlevel);
  10.         btn = new InputPort(GPIOA, GPIO_PIN_0, GPIO_MODE_IT_RISING, (void*)btnhandle, NULL); //输入类,传入GPIO,PIN,中断触发模式,回调指针,回调参数,完成初始化
  11.         tim2 = new Timer_base(TIM2, 16800, 10000);
  12.         BoardInfo();
  13. }
复制代码



OutputPort类:
  1. class OutputPort
  2. {
  3. public:
  4.         OutputPort(GPIO_TypeDef* mPORT, uint16_t mGPIO_PIN, bool initialState);//OutputPort类构建函数,简单传入三个参数
  5.         OutputPort(GPIO_TypeDef* mPORT, uint16_t mGPIO_PIN, uint32_t GPIO_Speed, uint32_t GPIO_PuPd, bool initialState);//构建函数重载,可以传入更多的参数
  6.         ~OutputPort();
  7.         void H(void);//类函数,构建的类都是调用同函数就可以实现,减少代码的重复
  8.         void L(void);
  9.         inline void  RegH(){PORT->BSRR |= GPIO_PIN;        }//内联函数,直接代码替换成寄存器操作,提高执行效率
  10.         inline void  RegL(){ PORT->BSRR |= GPIO_PIN << 16; }
  11.         GPIO_TypeDef* PORT;
  12.         uint16_t GPIO_PIN;
  13. private:
  14. protected:

  15. };

  16. LED类:
  17. class LED :public OutputPort
  18. {
  19. public:
  20.         LED(GPIO_TypeDef* mPORT, uint16_t mGPIO_PIN, bool initialState, uint8_t mCtlVolLev) : OutputPort(mPORT, mGPIO_PIN, initialState), CtlVolLev(mCtlVolLev){};//继承OutputPort类,并增加新的参数
  21.          ~LED();
  22.          void ON();
  23.          void OFF();
  24.          void Toggle();
  25.          enum{ lowlevel, highlevel };
  26. private:
  27. protected:
  28.         uint8_t CtlVolLev;    //LED 1为高电平  0为低电平
  29. };
复制代码



  UART类:
  1. extern uint8_t UART_Recv_Timeout[5];//Time Tick

  2. class Usart
  3. {
  4. public:
  5.         enum tranmode
  6.         {
  7.                 USART_Normal, //普通发送
  8.                 USART_IT,    //中断发送接收,接收自动判断超时完成接收
  9.                 USART_DMA    //DMA发送接收,UART闲时中断自动接收DMA接收完成
  10.         };//类构建时传入,类函数根据输入的类别发送接收
  11.         Usart(USART_TypeDef *USARTx, uint32_t BaudRate, tranmode mmode,uint16_t mRecvBuffSize);
  12.         void SendData(uint8_t data);
  13.         void SendData(uint8_t *pData, uint16_t Size, uint32_t Timeout);
  14.         uint16_t RecvData(uint8_t *pData);
  15.         uint16_t RecvDataLen; //接收到数据长度
  16.         UART_HandleTypeDef UartHandle;
  17.         uint8_t IsGetRecv;   //接收标志
  18.         uint8_t isSendOk ;  //发送完成标志
  19.         tranmode mode;
  20.         void Printf(const char* fmt, ...);
  21.         ~Usart();

  22. private:
  23.         uint16_t RecvBuffSize;
  24.         uint8_t *RecvBuff;
  25.         uint8_t SendBuff[100];
  26.         void USART_DMA_Config(UART_HandleTypeDef *UartHandle);
  27. };

  28. void Do_UART_Recv(uint8_t i);//接收超时处理函数
复制代码


     C++面向对象最大的好处是,只要定义一个类,相同的外设只要传入参数构建类,就可以调用类函数来实现功能,不需要为每个外设再重新写代码。而且封装好了类,只需要知道传入什么参数,可以调用什么接口来实现自己的功能就可以了,不需要再去了解类里面是怎么来实现的。目前就封装了GPIO,UART,TIM Base,SPI等几个外设,可以给大家体验下面向对象的强大,提供一些封装函数的思路,更具体的代码可以下载附件的工程。
STM32F4_Cpp.zip (3.72 MB, 下载次数: 104)
收藏 8 评论11 发布时间:2016-4-21 20:28

举报

11个回答
harvardx 回答时间:2016-4-22 00:10:44
不错 不过现实的单片机c++应用 怕也只是止步于此了.
power568 回答时间:2016-4-22 09:47:59
最近也有这个想法,但是还没实施,先学习了...
风子 回答时间:2016-4-22 10:23:07
楼主可以参考Mbed的实现
wuzhujian 回答时间:2016-4-22 14:26:30
如果使用模板,生成的代码效率,比用C写的还高。
湉湉 回答时间:2016-4-23 21:10:51
先学习下  谢谢分享
helen9898 回答时间:2016-4-26 17:39:56
高手,现在只能观望了。以后有机会再应用吧
auto_ele 回答时间:2016-4-28 11:13:52
不错,我们好多的项目,已经这么做了,效果不错,就是类和类之间传值有点麻烦,其他的都OK,写的程序,都按照“流”执行,思路清晰。
未来的趋势就是单片机会越来越多的支持高级语言的开发,比如C#,ST官网也针对F4有例程,基于.NET MICRO FRAMEWORK的,最近一直研究,有兴趣,可以一起搞。
蓝凌风 回答时间:2016-4-29 09:03:44
auto_ele 发表于 2016-4-28 11:13
不错,我们好多的项目,已经这么做了,效果不错,就是类和类之间传值有点麻烦,其他的都OK,写的程序,都按 ...

.NET MICRO FRAMEWORK我去年就有研究,写过一些文章,只能是玩玩,实际上没太多的胜任
auto_ele 回答时间:2016-5-16 21:34:44
蓝凌风 发表于 2016-4-29 09:03
.NET MICRO FRAMEWORK我去年就有研究,写过一些文章,只能是玩玩,实际上没太多的胜任 ...

较LINUX之类的系统,它把硬件层和应用层完全分开,只要写好CLR就可以。
12下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版