📄 pwm.c
字号:
/***********************************************Copyright (c)*********************************************
** Guangzou ZLG-MCU Development Co.,LTD.
**
** http://www.zlgmcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name: Pwm.c
** Last modified Date: 2007-11-13
** Last Version: 1.0
** Descriptions: PWM源文件,所有驱动的实现代码都在这实现
**
**--------------------------------------------------------------------------------------------------------
** Created by: LiXiaoCheng
** Created date: 2007-11-13
** Version: 1.0
** Descriptions: 初始版本
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
** Version:
** Descriptions:
**
*********************************************************************************************************/
#include "Config.h"
#include "PwmPrevate.h"
#include "Pwm.h"
/*********************************************************************************************************
定义一个PWM设备结构体变量
*********************************************************************************************************/
static __PWM_INFO GpwiData;
/*********************************************************************************************************
为移植方便,使用一个指针数组来存放结构体变量的指针
*********************************************************************************************************/
const __PPWM_INFO GppwiDataTab[__PWM_MAX_NUM] = {&GpwiData};
/*********************************************************************************************************
定义PWM寄存器基地址
*********************************************************************************************************/
const uint32 GuiPwmBaseAddrTab[__PWM_MAX_NUM] = {PWM0_BASE_ADDR};
/*********************************************************************************************************
定义PWM匹配通道表,用于程序快速查找匹配通道
*********************************************************************************************************/
const uint32 GucMRxTab[__PWM_MAX_CHANLE+1] = {__B_PWM_MR0, __B_PWM_MR1, __B_PWM_MR2,
__B_PWM_MR3, __B_PWM_MR4, __B_PWM_MR5,
__B_PWM_MR6};
/*********************************************************************************************************
** Function name: __pwmGetus
** Descriptions: pwm毫秒转换为高精度频率转换函数
** Input parameters: uiUsTime 输入us时间值
** Output parameters: NONE
** Returned value: 返回输入时间转换的频率值
*********************************************************************************************************/
static int32 __pwmUsToFre (uint32 uiUsTime)
{
uint32 uiResult;
uint32 uiResultFloat;
uint32 uiTemp;
uiResult = (uiUsTime * __PWM_US); /* 计算出PWM整数周期部分 */
if (uiUsTime > 10000) { /* 补偿部分,长时间的补偿 */
uiTemp = uiUsTime / 10000;
uiResultFloat = uiUsTime / 100000;
uiTemp = __PWM_H_US_DECI * (uiTemp - uiResultFloat);
uiResult += uiTemp;
}
uiResultFloat = (uiUsTime / 10000) * __PWM_TT_US_DECI; /* 计算在10000us以上小数部分频率*/
uiResult += uiResultFloat;
uiUsTime = (uiUsTime % 10000); /* 计算在1000us以上小数部分频率*/
uiResultFloat = (uiUsTime / 1000) * __PWM_T_US_DECI;
uiResult += uiResultFloat;
uiUsTime = (uiUsTime % 1000); /* 计算在100us以小数部分上频率 */
uiResultFloat = (uiUsTime / 100) * __PWM_H_US_DECI;
uiResult += uiResultFloat;
return uiResult;
}
/*********************************************************************************************************
** Function name: __pwmInit
** Descriptions: pwm初始化函数,结构体传入参数
** Input parameters: uiArgID 部件ID,0表示使用PWM0设备
** pArgData 传入参数的结构体指针
** Output parameters: NONE
** Returned value: OPERATE_FAIL 初始化失败
** OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
static int32 __pwmInit (uint32 uiArgID, __PPWM_PARM pArgData)
{
volatile uint32 *puiBaseAddr;
uint32 uiOffBase;
if (uiArgID >= __PWM_MAX_NUM) { /* 传入ID号错误 */
return OPERATE_FAIL;
}
if (!pArgData) { /* 传入参数指针错误 */
return OPERATE_FAIL;
}
/*
* 对参数进行判断
*/
if (pArgData->uiMode > __PWM_MODE_MAX) { /* 判断工作模式是否是正确 */
return OPERATE_FAIL;
}
if (pArgData->uiPeriod == 0 || pArgData->uiPeriod == -1) { /* 判断PWM频率 */
return OPERATE_FAIL;
}
/*
* 对设备结构体进行初始化
*/
GppwiDataTab[uiArgID]->puiAddrBase = (uint32*)GuiPwmBaseAddrTab[uiArgID];
GppwiDataTab[uiArgID]->uiOffBase = 0;
GppwiDataTab[uiArgID]->ucMode = (uint8)pArgData->uiMode;
/*
* 对硬件进行初始化
*/
puiBaseAddr = GppwiDataTab[uiArgID]->puiAddrBase;
uiOffBase = GppwiDataTab[uiArgID]->uiOffBase;
puiBaseAddr[__B_PWM_PR << uiOffBase] = 0; /* 分频值为0 */
puiBaseAddr[__B_PWM_PCR << uiOffBase] = 0; /* 禁止所有PWM输出 */
puiBaseAddr[__B_PWM_MR0 << uiOffBase] = __pwmUsToFre(pArgData->uiPeriod);
/* 设置频率 */
if (pArgData->uiMode == __PWM_MODE_TIME) {
puiBaseAddr[__B_PWM_MCR << uiOffBase] = (3 << 0); /* 设定让MRO匹配时TC中断复位 */
} else {
puiBaseAddr[__B_PWM_MCR << uiOffBase] = (1 << 0); /* PWM模式MRO匹配不中断 */
}
puiBaseAddr[__B_PWM_TCR << uiOffBase] = (1 << 3); /* 使能PWM */
puiBaseAddr[__B_PWM_LER << uiOffBase] |= (1 << 0);
return OPERATE_SUCCESS;
}
/*********************************************************************************************************
** Function name: pwmInit
** Descriptions: pwm初始化函数,字符串参数传入
** Input parameters: uiArgID 部件ID,0表示使用PWM0设备
** pucData 传入参数字符串指针指针,传入的参数有
** PwmMode 表示让PWM为上面模式,0表示把PWM用作定时器,1表示把PWM用作PWM
** PwmPeriod 表示PWM输出周期或定时器定时值,单位为us
** eg:"PwmMode=0 PwmPeriod=1000"表示使用定时器模式,定时1000us
** Rsv 保留参数
** Output parameters: NONE
** Returned value: OPERATE_FAIL 初始化失败
** OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
int32 pwmInit (uint32 uiArgID,
char *pucData,
void *Rsv)
{
uint32 uiTemp[7] ={-1, -1, -1, -1, -1, -1, -1};
Rsv = Rsv;
if (!pucData) {
return OPERATE_FAIL;
}
ImpCmd(Tab_PWM, pucData, uiTemp);
return __pwmInit(uiArgID, (__PPWM_PARM)uiTemp);
}
/*********************************************************************************************************
** Function name: __pwmModeSet
** Descriptions: pwm模式设置参数,结构体传入参数
** Input parameters: uiArgID 部件ID,0表示使用PWM0设备
** uiChanle 设置的通道范围:1 - 6
** pArgData 传入参数的结构体指针
** Output parameters: NONE
** Returned value: OPERATE_FAIL 设置失败
** OPERATE_SUCCESS 设置成功
*********************************************************************************************************/
static int32 __pwmModeSet (uint32 uiArgID,
uint32 uiChanle,
__PPWM_PARM pArgData)
{
volatile uint32 *puiBaseAddr;
uint32 uiOffBase;
if (uiArgID >= __PWM_MAX_NUM) { /* 传入ID号错误 */
return OPERATE_FAIL;
}
if (!pArgData) { /* 传入参数指针错误 */
return OPERATE_FAIL;
}
if (GppwiDataTab[uiArgID]->ucMode == __PWM_MODE_TIME) { /* 如果为定时器模式,不允许设置*/
return OPERATE_FAIL;
}
if (uiChanle < 1 || uiChanle > 6) { /* 没有0通道 */
return OPERATE_FAIL;
}
puiBaseAddr = GppwiDataTab[uiArgID]->puiAddrBase; /* 获取寄存器基地址 */
uiOffBase = GppwiDataTab[uiArgID]->uiOffBase;
if (pArgData->uiOutCtrl == __PWM_OUTPIN_DIS) { /* 禁止该通道PWM输出 */
puiBaseAddr[__B_PWM_PCR << uiOffBase] &= ~(1 << (uiChanle + 8));
return OPERATE_SUCCESS;
}
if (pArgData->uiEdg > __PWM_EDG_MAX) { /* 判断是边沿输出是否正确 */
return OPERATE_FAIL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -