/* ****************************************************************************** * * @file pwm.c * @brief pwm module * @ic sy8835 * * @version 1.0 * @date 2024/11/01 09:50:40 * @author Alex Xu * * Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd. * All Rights Reserved * * History: * Revision Date Author Desc * 1.0.0 2024/11/01 Alex build this file * Description:PWM功能中,4个通道公用一个源;也就是分频数(PWM_PRE0)、计数初值(PWM0_REL)只有一个,通过更改PWMx_CMP设置不同通道PWM输出的占空比。 ****************************************************************************** */ #include "pwm.h" #ifdef PWM_ENABLE /******************************************************************************\ Macro definitions \******************************************************************************/ /******************************************************************************\ Variables definitions \******************************************************************************/ /******************************************************************************\ Functions definitions \******************************************************************************/ /* ******************************************************************************* * void PWM_Disable(Pwm_Channels_e nPWM_Ch) * * Description : PWM Disable PWM按通道禁能 * * Arguments : None * Returns : * Notes : * ******************************************************************************* */ void PWM_Disable(Pwm_Channels_e nPWM_Ch) { SFRADDR = MFP_CTL1; SFRDATA &= ~( 0x03 << (nPWM_Ch * 2) ); if(nPWM_Ch == PWM_ALL) { SFRADDR = MFP_CTL1; SFRDATA = 0x00; } } /* ******************************************************************************* * void PWM_Init_Set(uint8_t nPWM_PRE,uint8_t nPWM_REL) * * Description : PWM Set1 设置PWM输出时钟分频、频率参数。 例如:PWM输出PWM频率10kHz,占空比50%。 则参数设置如下:PWM计数器时钟Fre(pwm) = Fre(sys)/PWM_PRE = 12M / n^PWM_PRE = 12M / 8 = 1.5MHz, PWM_REL = 255 - 1.5M / 10K = 255-150 = 105, nPWM_CMP = 105 + 150 * (1-50%) = 180。 * * Arguments : uint8_t nPWM_PRE --- PWM counter reload value * uint8_t nPWM_REL --- PWM compare value * * Returns : NONE * Notes : NONE * ******************************************************************************* */ void PWM_Init_Set(uint8_t nPWM_PRE,uint8_t nPWM_REL) { SFRADDR = PWM_PRE; //PWM clock divide setting SFRDATA = nPWM_PRE & 0x07; SFRADDR = PWM_REL; //PWM counter reload value SFRDATA = nPWM_REL; SFRADDR = PWM_CTL; SFRDATA = 0x01; } /* ******************************************************************************* * void PWM_Duty_Set(Pwm_Channels_e nPWM_Ch,uint8_t nPWM_CMP) * * Description : PWM Set 按通道设置PWM输出占空比参数。 例如:PWM输出PWM频率10kHz,占空比50%。 则参数设置如下:PWM计数器时钟Fre(pwm) = Fre(sys)/PWM_PRE = 11.0592M / n^PWM_PRE = 11.0592M / 8 = 1.38MHz, PWM_REL = 255 - 1.5M / 10K = 255-150 = 105, nPWM_CMP = 105 + 150 * (1-50%) = 180。 * * Arguments : nPWM_Ch (PWM0 ~ PWM3); * uint8_t nPWM_CMP --- PWM compare value * * Returns : NONE * Notes : NONE * ******************************************************************************* */ void PWM_Duty_Set(Pwm_Channels_e nPWM_Ch,uint8_t nPWM_CMP) { SFRADDR = MFP_CTL1; SFRDATA &=~( 0x03 << nPWM_Ch*2 ); SFRDATA |= 0x01 << nPWM_Ch*2; SFRADDR = P1_OE; SFRDATA |= 0x01 << nPWM_Ch; if(nPWM_Ch == PWM_CH0) { PWM0_CMP = nPWM_CMP; } else if(nPWM_Ch == PWM_CH1) { PWM1_CMP = nPWM_CMP; } else if(nPWM_Ch == PWM_CH2) { PWM2_CMP = nPWM_CMP; } else if(nPWM_Ch == PWM_CH3) { PWM3_CMP = nPWM_CMP; } } #if 0 /* ******************************************************************************* * void HuXi_Led(Pwm_Channels_e nPWM_Ch, uint8_t Delay_Timer) * * Description : 呼吸灯功能函数 * * Arguments : Pwm_Channels_e nPWM_Ch:对应的PWM通道 uint8_t Delay_Timer:更改一次PWM输出占空比所需的时间。 * Returns : None * Notes : 注意PWM初始化设置中的PWM counter reload value,从而限定了PWM compare value的大小。 * ******************************************************************************* */ void HuXi_Led(Pwm_Channels_e nPWM_Ch, uint8_t Delay_Timer) { static uint8_t nHuXi_Cnt; static uint8_t nHuXi_Timer_Cnt; static bit HuXi_Dir_Flg; nHuXi_Timer_Cnt++; if(nHuXi_Timer_Cnt <= Delay_Timer) return; nHuXi_Timer_Cnt = 0; if(!HuXi_Dir_Flg) { nHuXi_Cnt += 2; if( nHuXi_Cnt >= 254 ) { HuXi_Dir_Flg = 1; nHuXi_Cnt = 3; } } else { nHuXi_Cnt -= 2; if(nHuXi_Cnt <= 3) { HuXi_Dir_Flg = 0; nHuXi_Cnt = 3; } } PWM_Duty_Set(nPWM_Ch, nHuXi_Cnt); } #endif #endif