⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hw_pwm.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:
/*********************************************************************************
*     Copyright (C),2004-2005,  Fuzhou Rockchip Co.,Ltd.
*         All Rights Reserved
*          V1.00
* FileName :  Hw_pwm.c
* Author :  lzy
* Description:
* History  :
*   <author>  <time>    <version>    <desc>
*    lzy        07/23/29        1.0     ORG
$Log: Hw_pwm.c,v $
Revision 1.4  2008/07/21 03:31:55  Administrator
PWM 频率切换 BUG!

Revision 1.3  2008/06/19 04:43:33  Administrator
代码整理!

Revision 1.2  2008/05/29 12:34:38  HXY
PWM_Stop中恢复关闭PWM clock的动作,以便背光灭时关闭PWM clock

Revision 1.1.1.1  2008/05/07 04:15:08  Administrator
no message

Revision 1.1.1.1  2008/03/06 13:29:07  Lingzhaojun
no message

Revision 1.8  2007/11/16 09:46:39  Lingzhaojun
提交linzhenyuan驱动修改

Revision 1.7  2007/11/10 04:29:33  Huangxinyu
调试修改

Revision 1.6  2007/11/02 03:55:15  Xiexiuxin
更改 PWM_PowerOnInit

Revision 1.5  2007/10/23 08:26:12  Huangxinyu
调试后修改bug

Revision 1.4  2007/10/15 09:18:49  Huangxinyu
根据RK27提交修改driver

Revision 1.3  2007/10/08 02:38:46  Lingzhaojun
添加版本自动注释脚本
*log : HJ    07/10/19
   修改PWM_PowerOnInit,增加Scu_ClockEnable()
   去除变量pwmfreq
   修改PWM_SetFreq()接口

*********************************************************************************/
#include "include.h"
#include "hw_include.h"
#include "hw_pwm.h"
#include "hw_pll.h"


void PWM_SetFreq(PWM_CH_t pwm_ch, UINT32 nHz);
void PWM_SetRate(PWM_CH_t pwm_ch, UINT32 rate);
static  pPWMReg_t pPWMReg[4] =
{
    (pPWMReg_t)APB0_PWM_BASE,
    (pPWMReg_t)(APB0_PWM_BASE + 0x10),
    (pPWMReg_t)(APB0_PWM_BASE + 0x20),
    (pPWMReg_t)(APB0_PWM_BASE + 0x30)
};

static  UINT32 PwmFreq[PWM_MAX_CH] = {NULL, NULL, NULL, };
static  UINT32 PwmRate[PWM_MAX_CH] = {NULL,NULL,NULL,};

#define PWM_DIV    PWM_DIV2          //   PWM_DIV32

/**************************************************************************
* 函数描述:   初始化PWM, freq (1~~1024)
* 入口参数:   pwm_ch:    PWM 通道号
*                            nHz:         默认PWM 频率(Hz),
*                            rate:         默认占空比( 高电平时间/ 总时间)  0 -100
* 出口参数:    无
* 返回值:         无
***************************************************************************/
BOOL PWM_Init(PWM_CH_t pwm_ch, UINT32 nHz, UINT32 rate)
{
    UINT32  divh;

    if ((nHz == 0) || (pwm_ch >= PWM_MAX_CH) || (rate > 100))
        return FALSE;

    Scu_ClockEnable(PWM_CLOCK);

    PwmFreq[pwm_ch] = nHz;
    PwmRate[pwm_ch] = rate;

    pPWMReg[pwm_ch]->PWM_CTRL = PWM_DIV | PWM_RESET;

    divh = (1000 * Pll_get_apb_freq()) / nHz;
    divh = divh >> (1 + (PWM_DIV >> 9));

    pPWMReg[pwm_ch]->PWM_LRC = (0 == divh) ? 1 : divh;

    PWM_SetRate(pwm_ch, rate);

    pPWMReg[pwm_ch]->PWM_CNTL = 0x0;
    pPWMReg[pwm_ch]->PWM_CTRL = PWM_DIV | PWM_ENABLE | PWM_TimeEN;

    return TRUE;
}

/**************************************************************************
* 函数描述:  停止PWM 输出
* 入口参数:  pwm_ch:      PWM 通道号
* 出口参数:  无
* 返回值:       无
***************************************************************************/
void PWM_Stop(PWM_CH_t pwm_ch)
{
    pPWMReg[pwm_ch]->PWM_CTRL &= ~(PWM_ENABLE | PWM_TimeEN);

#if (RK2710 != CHIPTYPE)
    Scu_ClockDisable(PWM_CLOCK);
#endif

}


/**************************************************************************
* 函数描述:  停止PWM 输出
* 入口参数:  pwm_ch:      PWM 通道号
* 出口参数:  无
* 返回值:       无
***************************************************************************/
void PWM_DeInit(PWM_CH_t pwm_ch)
{
    pPWMReg[pwm_ch]->PWM_CTRL &= ~(PWM_ENABLE | PWM_TimeEN);
	PwmRate[pwm_ch] = 0;
	PwmFreq[pwm_ch] = 0;
    Scu_ClockDisable(PWM_CLOCK);

}

/**************************************************************************
* 函数描述: 调整PWM 占空比
* 入口参数:  pwm_ch:      PWM 通道号
*            rate:        默认占空比(0~~100 高电平时间/ 总时间)
* 出口参数:  无
* 返回值:       无
***************************************************************************/
void PWM_SetRate(PWM_CH_t pwm_ch, UINT32 rate)
{
    UINT32 divh, divtotal;

    Scu_ClockEnable(PWM_CLOCK);
	PwmRate[pwm_ch] = rate;
    divtotal = ReadReg32(&pPWMReg[pwm_ch]->PWM_LRC);
    //divtotal = pPWMReg[pwm_ch]->PWM_LRC;
    divh = divtotal * rate / 100;
    pPWMReg[pwm_ch]->PWM_HRC = divh ? divh : 1;

    pPWMReg[pwm_ch]->PWM_CTRL |= PWM_ENABLE | PWM_TimeEN;

}

/**************************************************************************
* 函数描述:  根据APB 频率调整PWM 参数
* 入口参数:  APBfreq:      APB 频率(Hz)
* 出口参数:  无
* 返回值:       无
***************************************************************************/
void PWM_UpdateApbFreq(PWM_CH_t pwm_ch, UINT32 nKHz)
{
    UINT32 divl, divh, divtotal, pwmfreq, tmp;

    DECLARE_CUP_SR;
    Scu_ClockEnable(PWM_CLOCK);
    //divl = pPWMReg[pwm_ch]->PWM_LRC;
    //divh = pPWMReg[pwm_ch]->PWM_HRC;

    pwmfreq = PwmFreq[pwm_ch];
    if (pwmfreq)
    {
// add to avoid other code  interrupt the setting to change PWM frequence. lzy 4.14
        ENTER_CRITICAL();
        tmp = (1000 * nKHz) / pwmfreq;
        tmp = tmp >> (1 + (PWM_DIV >> 9));
        divtotal = (0 == tmp) ? 1 : tmp;
        tmp =  divtotal*PwmRate[pwm_ch]/100;   
        pPWMReg[pwm_ch]->PWM_CNTL = 0x0;
        pPWMReg[pwm_ch]->PWM_LRC = divtotal;
        pPWMReg[pwm_ch]->PWM_HRC = tmp;
        EXIT_CRITICAL();
    }
}

/**************************************************************************
* 函数描述:  根据APB 频率调整所有PWM 通道的频率参数
* 入口参数:  APBfreq:      APB 频率(KHz)
* 出口参数:  无
* 返回值:       无
***************************************************************************/
void PWM_UpdateAllApbFreq(UINT32 nKHz)
{
    UINT16 cnt = PWM_MAX_CH;

    while (cnt)
    {
        PWM_UpdateApbFreq(cnt - 1, nKHz);
        cnt--;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -