通用模块设计–面向对象设计
- 模块设计背景
- 模块设计思想
- 代码的实现
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