通用模块设计–面向对象设计

通用模块设计–面向对象设计

  1. 模块设计背景
  2. 模块设计思想
    这里写图片描述
  3. 代码的实现
    GPIO_PWM.c
/*****************=======================================*********** 
 * 文件名  :GPIO_PWM.c
 * 描述    :主要是利用 GPIO的模拟来实现PWM的功能。
                  思想:
                        1.通过对周期和占空比的配置,利用计数器,实现PWM的调节。
                        2.单独设计 PWM通道的GPIO的电平的翻转
    主要函数:
                // 内部函数
                1. PWM_GPIO_Init()  --内部调用
                2.PWM_GPIO_Map_Init()  ---内部调用
        3.gpio_pwm.ext_fun.dis_pwm=GPIO_PWM_Dis; //关闭PWM
        4.gpio_pwm.ext_fun.set_channel_pwm=GPIO_PWM_Channel_Period_8_Duty_Set;//设置周期和占空比
        5.gpio_pwm.ext_fun.set_channel_status=GPIO_PWM_Channel_Status_Set;//设置PWM的状态(包括:初始化,停止)

                 //以下为外部调用,利用面向对象编程 
                6.void Gpio_PWM_Thread()---PWM 线程
                7.bool GPIO_PWM_Init(void)---初始化
*          
 * 硬件平台:
 *         
 * 硬件连接:
 * 库版本  :
 *
 * 作者    :BrantYu
 * 日期    :
 * 修改历史:
 * v1.0:
*******************************************************************/

/* common  Includes ------------------------------------------------------------------*/
#include "common.h"
#include "STM32F10X.h"

/* User  Includes ------------------------------------------------------------------*/
#include "gpio_pwm.h"
#include "formula_config.h"
/* Micro  define  ------------------------------------------------------------------*/


#define PWM_OUT_LOGIC (1)  //1:正逻辑,0:反逻辑


#define PWM_CHANNEL_0_GPIO            (GPIOB)
#define PWM_CHANNEL_0_GPIO_RCC   (RCC_APB2Periph_GPIOB)
#define PWM_CHANNEL_0_GPIO_PIN    (GPIO_Pin_5)

#define PWM_CHANNEL_1_GPIO            (GPIOE)
#define PWM_CHANNEL_1_GPIO_RCC   (RCC_APB2Periph_GPIOE)
#define PWM_CHANNEL_1_GPIO_PIN    (GPIO_Pin_5)

/* Type  define  ------------------------------------------------------------------*/
// 函数指针定义
/*
  void (*pfunc) (void);
  u8   (*pfunc) (u8,u8);
*/




/*Eextern  variable  And function  Declaration------------------------------------------*/
extern  void rt_kprintf(const char *fmt, ...);

/* Local   variable  And function  Declaration-------------------------------------------*/


/* Global   variable  And function  Declaration------------------------------------------*/



/* User    code  As below     ----------------------------------------------------------*/

/**************************************************
@ 作者:BrantYu In suzhou
@ 函数名称:
@ 调用关系(内部/外部):
@ 作用:
@ 参数:
    输入参数:
        1:无
    输入参数:无  
    返回:无
@ 修改历史:
    时间:
    修改内容:无
**************************************************/


/**************************************************
@ 作者:BrantYu In suzhou
@ 函数名称:T_PWM_FUNCTION
@ 调用关系(内部/外部):
@ 作用: 禁止PWM,set_channel_status,set_channel_pwm,只要设置了后两者之一,就会自动启动PWM 自动装载模式
@ 参数:
    输入参数:
        1:无
    输入参数:无  
    返回:无
@ 修改历史:
    时间:
    修改内容:无
**************************************************/



T_PWM gpio_pwm;




void Gpio_PWM_Thread(void)//USED TO THREAD
{
u8 i;
u8 haved_convert=0;
if(gpio_pwm.en==0){return;}

//关闭所有的PWM 通道
 if(gpio_pwm.status==STATUS_PWM_ALL_STOP)
 {
     /* 线程上锁,使得其他线程没有权限占用CPU,中断除外 */
    rt_enter_critical();
     for(i=0;i<gpio_pwm.haved_map_channels;i++)
     {
      gpio_pwm.channel[i].status=STATUS_PWM_STOP;
      gpio_pwm.channel[i].fgpio_out(!PWM_GPIO_OUT_VALID);    
     }
     gpio_pwm.en=0;

     /* 线程解锁,线程重新获得权限 */
     rt_exit_critical();
     return;
 }

 //Debug_Printf("\r\nGpio_PWM_Thread ");
 //开始PWM channel
  for(i=0;i<PWM_CHANNEL_CNT_MAX;i++)
 {

      if((gpio_pwm.channel[i].status)==STATUS_PWM_START)
      {
          if( gpio_pwm.channel[i].ccr>1){ gpio_pwm.channel[i].ccr--;}
          else if(gpio_pwm.channel[i].ccr==1)
          {
              #if(PWM_OUT_LOGIC)//PWM输出和驱动的 正逻辑的
              if(gpio_pwm.channel[i].ccr_cpy==PWM_ARR_MAX)
              {
              gpio_pwm.channel[i].fgpio_out(PWM_GPIO_OUT_VALID);
              gpio_pwm.channel[i].haved_convert=0;
              }
              else
              {
              gpio_pwm.channel[i].fgpio_out(!PWM_GPIO_OUT_VALID);
              gpio_pwm.channel[i].ccr=0;
              gpio_pwm.channel[i].haved_convert=1;
              }

              #else//PWM 输出 和驱动 反逻辑的
              gpio_pwm.channel[i].fgpio_out(!PWM_GPIO_OUT_VALID);
              gpio_pwm.channel[i].ccr=0;
              gpio_pwm.channel[i].haved_convert=1;  
              #endif

          }
          else{}

          if( gpio_pwm.channel[i].arr>1){ gpio_pwm.channel[i].arr--;}
          else if( gpio_pwm.channel[i].arr==1)
          {

            if(gpio_pwm.channel[i].haved_convert==1)
            { 
                #if(PWM_OUT_LOGIC)//PWM输出和驱动的 正逻辑的
                 gpio_pwm.channel[i].fgpio_out(PWM_GPIO_OUT_VALID);
                 gpio_pwm.channel[i].haved_convert=0;                   
                #else
                  if(gpio_pwm.channel[i].ccr_cpy!=gpio_pwm.channel[i].arr_cpy)//如果相等 即:100%的占空比,那么就不需要翻转了,只有在不相等的情况下翻转
                  {gpio_pwm.channel[i].fgpio_out(PWM_GPIO_OUT_VALID);}            
                  gpio_pwm.channel[i].haved_convert=0;              
                #endif                      
            }

            gpio_pwm.channel[i].ccr=gpio_pwm.channel[i].ccr_cpy;
            gpio_pwm.channel[i].arr=gpio_pwm.channel[i].arr_cpy;
          }
          else{}
      }  
 } 

}

static void GPIO_PWM_Channel_All_Init(void)
{
 u8 i;
 for(i=0;i<gpio_pwm.haved_map_channels;i++)
 {  
  gpio_pwm.channel[i].fgpio_out(!PWM_GPIO_OUT_VALID);
  gpio_pwm.channel[i].arr_cpy=gpio_pwm.channel[i].arr=0;
  gpio_pwm.channel[i].ccr_cpy=gpio_pwm.channel[i].ccr=0;
  gpio_pwm.channel[i].status=STATUS_PWM_STOP;
  gpio_pwm.channel[i].haved_convert=0;
 }


}

static void GPIO_PWM_Dis(void)
{
gpio_pwm.status=STATUS_PWM_ALL_STOP;
User_OS_Delay(DEFAULT_WAITE_STICKS,UNIT_STICK);//务必延时一会,使得PWM线程得到 CPU的使用权限,安全的关闭所有的PWM 通道
}

void GPIO_PWM_Channel_Status_Set(u8 channel,u8 status)
{

   gpio_pwm.channel[channel].status=status;
    if(status==STATUS_PWM_START)
    {
    gpio_pwm.channel[channel].arr=2;    //务必 >=1,使得占空比按照温度指定的值进行 输出PWM
    gpio_pwm.channel[channel].arr_cpy=2;//务必 >=1,使得占空比按照温度指定的值进行 输出PWM

    gpio_pwm.channel[channel].ccr=0;     //务必 =0 使得 无法翻转
    gpio_pwm.channel[channel].ccr_cpy=0;    //务必 =0 使得 无法翻转
    gpio_pwm.channel[channel].haved_convert=0;
    }

}

void GPIO_PWM_Channel_Period_8_Duty_Set(u8 channel,u32 arr,u32 ccr)
{
gpio_pwm.channel[channel].arr_cpy=arr;
gpio_pwm.channel[channel].ccr_cpy=ccr;
}



//---------------GPIO SET/RESET  FUNCTION--------------
/**************************************************
@ 作者:BrantYu In suzhou
@ 函数名称:PWM_Channel_1_Gpio_Out()
@ 调用关系(内部/外部):内部
@ 作用:提供IO的输出
@ 参数:
    输入参数:
        1:status:表示个GPIO的输出状态,(1:有效态度,0:无效态)
    输出参数:无  
    返回:无
@ 修改历史:
    时间:
    修改内容:无
**************************************************/
static void PWM_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(PWM_CHANNEL_0_GPIO_RCC,ENABLE);
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin   = PWM_CHANNEL_0_GPIO_PIN;
    GPIO_Init(PWM_CHANNEL_0_GPIO, &GPIO_InitStructure);

      RCC_APB2PeriphClockCmd(PWM_CHANNEL_1_GPIO_RCC,ENABLE);
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin   = PWM_CHANNEL_1_GPIO_PIN;
    GPIO_Init(PWM_CHANNEL_1_GPIO, &GPIO_InitStructure);

}

//-----CHANNEL OUT FUNCTION -------------
static void  PWM_Channel_0_Gpio_Out(u8 status) 
{
//Debug_Printf("\r\n PWM_Channel_0_Gpio_Out  status=%d",status);
if(status==1){GPIO_SetBits(PWM_CHANNEL_0_GPIO, PWM_CHANNEL_0_GPIO_PIN);}
else{GPIO_ResetBits(PWM_CHANNEL_0_GPIO, PWM_CHANNEL_0_GPIO_PIN);}
}

static void  PWM_Channel_1_Gpio_Out(u8 status) 
{
//Debug_Printf("\r\n PWM_Channel_1_Gpio_Out  status=%d",status);
if(status==1){GPIO_SetBits(PWM_CHANNEL_1_GPIO, PWM_CHANNEL_1_GPIO_PIN);}
else{GPIO_ResetBits(PWM_CHANNEL_1_GPIO, PWM_CHANNEL_1_GPIO_PIN);}
}

//-----------PWM channel OUT 函数的 映射关系----------------------------
void PWM_GPIO_Map_Init(void)
{
gpio_pwm.channel[0].fgpio_out=PWM_Channel_0_Gpio_Out;
gpio_pwm.channel[1].fgpio_out=PWM_Channel_1_Gpio_Out;
//gpio_pwm.channel[2].fgpio_out=PWM_Channel_2_Gpio_Out;
gpio_pwm.haved_map_channels=2;
}






//======================================================
bool GPIO_PWM_Init(void)
{
PWM_GPIO_Init();
PWM_GPIO_Map_Init();

 gpio_pwm.en=0;//禁止 PWM的使能
 gpio_pwm.status=STATUS_PWM_ALL_STOP;//线程的 关闭所有的通道
 GPIO_PWM_Channel_All_Init();//手动初始化所有的通道,仅仅在初始化的时候才用到

gpio_pwm.ext_fun.dis_pwm=GPIO_PWM_Dis;//线程中关闭所有的PWM通道
gpio_pwm.ext_fun.set_channel_pwm=GPIO_PWM_Channel_Period_8_Duty_Set;
gpio_pwm.ext_fun.set_channel_status=GPIO_PWM_Channel_Status_Set;

return true;
}

GPIO_PWM.h

/* Ctrl + h 将GPIO_PWM 替换 需要的 字符串*/
//GPIO_PWM

#ifndef  GPIO_PWM_HH_
#define  GPIO_PWM_HH_ 

#ifndef  GPIO_PWM_GOLBAL
#define  GPIO_PWM_EXT   extern 
#else
#define  GPIO_PWM_EXT
#endif


/* common  Includes ------------------------------------------------------------------*/
#include "common.h"
#include "stm32f10x_it.h"
#include "STM32F10X.h"

/* User  Includes ------------------------------------------------------------------*/



/* Micro  define  ------------------------------------------------------------------*/



/* Type  define  ------------------------------------------------------------------*/

// 函数指针定义
/*
  void (*pfunc) (void);
  u8   (*pfunc) (u8,u8);
*/

#define PWM_GPIO_OUT_VALID  (0)


#define  PWM_CHANNEL_CNT_MAX (2)


typedef enum __T_STATUS_PWM
{
    STATUS_PWM_INIT=0X30,
    STATUS_PWM_START,
    STATUS_PWM_STOP,
    STATUS_PWM_IDLE,
    STATUS_PWM_ALL_STOP,
}T_STATUS_PWM;


typedef struct _T_GPIO_PWM
{
u8 status;
u8 haved_convert;
u8 model;
u32 ccr;
u32 arr;
u32 ccr_cpy;
u32 arr_cpy;
void (*fgpio_out)(u8 status);
}T_GPIO_PWM;

typedef struct _T_PWM_FUNCTION
{
void (*set_channel_status)(u8 channel,u8 status);
void (*set_channel_pwm)(u8 channel,u32 arr,u32 ccr);
void (*dis_pwm)(void);
}T_PWM_FUNCTION;

typedef struct _T_PWM
{
u8 haved_map_channels;
T_GPIO_PWM channel[PWM_CHANNEL_CNT_MAX];
u8 en;
T_PWM_FUNCTION  ext_fun;
u8 status;
}T_PWM;

/*Eextern  variable  And function  Declaration------------------------------------------*/
GPIO_PWM_EXT T_PWM gpio_pwm;
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值