打印
[STM32F1]

推荐下基于时间触发嵌入式及简易C++的单片机软件架构

[复制链接]
850|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fly1974|  楼主 | 2019-9-20 14:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 fly1974 于 2019-9-21 07:43 编辑

   对于单片机程序来讲,每个人有自己的做法,但基本原则是尽量保证设备上每个外设的实时性,程序结构简单易维护易扩展。   这些东西讲起来简单,但很多老工程师也很难做到,我的体会是时间触发潜入式的架构完全可以满足大多数单片机程序的要求,如果配合C++使用,那就更好了,建议一些保守的老工程师找相关资料研究一下,网上书和Demo Code都有,尽量不要别处心裁,导致写出来的程序即使有很多注释,别人接手后还是没法扩展和完善,个人一点体会,不喜请绕道勿喷,谢谢!

使用特权

评论回复
沙发
yklstudent| | 2019-9-21 09:30 | 只看该作者
为什么要这么干,对老工程师有什么好处?老板会加工资?

使用特权

评论回复
板凳
晓伍| | 2019-10-15 12:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
地板
八层楼| | 2019-10-15 12:14 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
5
观海| | 2019-10-15 12:16 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
6
guanjiaer| | 2019-10-15 12:42 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
heimaojingzhang| | 2019-10-15 12:49 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
21mengnan| | 2019-10-15 13:37 | 只看该作者
C就挺好的,真不知道C++哪儿好。

使用特权

评论回复
9
fly1974|  楼主 | 2019-10-17 08:42 | 只看该作者
本帖最后由 fly1974 于 2019-10-17 08:51 编辑
21mengnan 发表于 2019-10-15 13:37
C就挺好的,真不知道C++哪儿好。

C的定义格式一般如下,定义全局变量外加各自独立地驱动函数:
float   Temper=0;
float   Temper2=0;
float   Temper3=0;
float   Temper4=0;

C++的定义格式一般如下,定义一个统一的类,所有驱动函数公用,因此C++在代码复用上比C++更简洁,更容易扩展:
class  Ds18B20
{
   public:
     Ds18B20(GPIO_TypeDef* GPIOx,uchar Pos);
     void   GetT_SnrA(void);               //运行整个测温及读取温度过程
     void   SetPar18B20A(void);            //设置DS18B20测温分辨率和转换时间
     uint16_t CurT;                         //读取的当前温度,形式为0xXXXX,前三个数字XXX表示当前温度,最后一个X为小于1度的部分(十进制0~9)
     uint8_t  TaskID;
     uchar    Step;
     uchar    PhaseTInit;
     uchar    temp_low,temp_high;                     //错误设为char 类型时某些温度范围输出异常
     uint     temperature,GetTCounter;
     uchar    ReadTStep;
     uchar    GetTPhase;                    //
private:
     void  SetDir_PortSensorA_IN(void);
     void  SetDir_PortSensorA_Out(void);
     void  delay_us(uint DlyInt32);        //短延时使用,为uS量级
     uchar  CRC_OK1(uchar *p1,uchar num);  //CRC校验,查表法
     void  Write_18B20(unsigned char n); //往DS18B20中写一个字节
     unsigned char Read_18B20(void);     //从DS18B20读取一个字节
     uchar  Init (void);                  //18B20总线初始化
     uchar  Skip(void);                   //18B20跳过内部ROM匹配
     uchar  Convert (void);               //启动18B20温度转换
     uchar  ReadDo (void);                //发送读取18B20寄存器指令
     uchar  ReadTemp (void);              //传感器出错后返回100度,Error=8,传感器测得温度低于零下25度时返回100度,Error=0;
     uchar  GetStatus_SnrPort(void);      //读取温度传感器信号线输入信号,1为高电平,0为低电平
     unsigned long  CntTOK;
     unsigned long  CntTNG;
     unsigned long  CntInitNG;  
     uint16_t LastT;            
     uint16_t EverT;                      //?           
     uchar    BoxTPol;                    //温度正负判断辅助变量
     uchar    LastTPol;  
     uchar    EverTPol;
     uchar    Error;                     //传感器出错次数,用来控制干扰滤除        
     uchar    Buf18B20A[9];
    GPIO_InitTypeDef GPIO_InitStruct;        
    GPIO_TypeDef* MyGPIOx;
    uint16_t  MyGPIOxPin;
    uchar     MyPinPos;
    uint32_t  MyGpioMode,MyGpioMode_0;
};


Ds18B20 Ds18B20A(GPIOC,6);
Ds18B20 Ds18B20B(GPIOC,7);   
Ds18B20 Ds18B20C(GPIOC,8);   
Heater  HeaterA(GPIOB,12);
Heater  HeaterB(GPIOB,13);
Heater  HeaterC(GPIOB,14);
Motor   MotorX(GPIOA,0,GPIOB,0,GPIOA,8);
Motor   MotorY(GPIOB,8,GPIOC,4,GPIOA,9);
Motor   MotorZ(GPIOA,3,GPIOC,3,GPIOA,7);
Motor   MotorD(GPIOB,7,GPIOB,1,GPIOA,10);

  18B20 C 驱动的常规写法是每个传感器一套函数,如下:
void Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        P4DIR|=0X20;
        DQ0;

        _NOP();_NOP();                           //==延时5us===
        _NOP();_NOP();_NOP();
        if((n&0X01)==0X01)
        DQ1;
        else DQ0;
        n=n>>1;
       delay_us(640);                             //==延时50us 以上===
        DQ1;
    }
}

void Write_18B202(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        P4DIR|=0X10;
        DQ20;
        _NOP();_NOP();                           //==延时5us===
        _NOP();_NOP();_NOP();
        if((n&0X01)==0X01)
        DQ21;
        else DQ20;
        n=n>>1;
       delay_us(640);                             //==延时50us 以上===
        DQ21;
    }
}

而18B20 C++ 驱动的常规写法是共用一套函数:
Ds18B20::Ds18B20(GPIO_TypeDef* GPIOx,uchar Pos)  
{
  uint16_t  GPIOxPin;
  uint32_t  RCC_AHBPeriphGPIOx;
  
  GPIOxPin=(1<<Pos);
  if(GPIOx==GPIOA)  RCC_AHBPeriphGPIOx=RCC_APB2Periph_GPIOA;
  else if(GPIOx==GPIOB)  RCC_AHBPeriphGPIOx=RCC_APB2Periph_GPIOB;
  else if(GPIOx==GPIOC)  RCC_AHBPeriphGPIOx=RCC_APB2Periph_GPIOC;
  else if(GPIOx==GPIOD)  RCC_AHBPeriphGPIOx=RCC_APB2Periph_GPIOD;
  else if(GPIOx==GPIOF)  RCC_AHBPeriphGPIOx=RCC_APB2Periph_GPIOF;
  
  GPIO_InitStruct.GPIO_Pin = GPIOxPin;
  RCC_APB2PeriphClockCmd(RCC_AHBPeriphGPIOx, ENABLE);         
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOx, &GPIO_InitStruct);        
  MyGPIOx=GPIOx;
  MyGPIOxPin=GPIOxPin;
  MyPinPos=Pos;  
  Step=0xff;
  PhaseTInit=0xff;
  GetTCounter=0;
  ReadTStep=0xff;
  GetTPhase=0xff;
}

void Ds18B20::Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     //关systick中断
        SetDir_PortSensorA_Out();
        SA_DQ0;    delay_us(7);       //==延时0us---25us===
        if((n&0X01)==0X01)
        {
          SetDir_PortSensorA_IN();
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断   
          delay_us(100);        //64us delay_us(192)
        }
        else
        {
          if(ParSeting==0) SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;    //开systick中断
          delay_us(100);         //60uS delay_us(160);
          SetDir_PortSensorA_IN();  
          delay_us(16);          //10uS delay_us(32);
        }
        n=n>>1;
    }
}






使用特权

评论回复
10
yediezeus| | 2019-10-17 11:34 | 只看该作者

使用特权

评论回复
11
座机呀| | 2020-12-5 23:17 | 只看该作者
可以用C写单片机的时候,捎带点面向对象编程的思想,有时候是小段代码面向过程,大段代码面向对象

使用特权

评论回复
12
fly1974|  楼主 | 2020-12-8 15:40 | 只看该作者
座机呀 发表于 2020-12-5 23:17
可以用C写单片机的时候,捎带点面向对象编程的思想,有时候是小段代码面向过程,大段代码面向对象 ...

   是的,现在不管是IAR还是Keil,对C++面向对象都支持得很好,适当地用一些C++特性,对于编程优点还是很突出的!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:看得到未来;做得好现在。

29

主题

303

帖子

6

粉丝