
#include "mc9s12xhy256.h"


#include "XHY_PWM.h"
//唤醒和首次上电时调用一次
void  PWM_Wake_Up_Init(void)
{
 //各个通道参数初始化设定，使能
PWM_Channel_Init(PWM_CH5_PIN34_PP5, PWM_CLOCK_SA , PWM_POL_POS , PWM_LEFT_ALIGN)  ;    
PWM_Channel_Set_Freq(PWM_CH5_PIN34_PP5, 2850 )  ;
PWM_Channel_Set_Duty(PWM_CH5_PIN34_PP5, 0 ) ;
PWM_Channel_Enable(PWM_CH5_PIN34_PP5,1);     

PWM_Channel_Init(PWM_CH7_PIN36_PP7, PWM_CLOCK_SB , PWM_POL_POS , PWM_LEFT_ALIGN)  ;    
PWM_Channel_Set_Freq(PWM_CH7_PIN36_PP7, 2850 )  ;
PWM_Channel_Set_Duty(PWM_CH7_PIN36_PP7, 0 ) ;
PWM_Channel_Enable(PWM_CH7_PIN36_PP7,1);     

//PWM_Channel_Init(PWM_CH6_PIN35_PP6, PWM_CLOCK_SB , PWM_POL_POS , PWM_LEFT_ALIGN)  ;       
//PWM_Channel_Set_Freq(PWM_CH6_PIN35_PP6, 2850 )   ;       
//PWM_Channel_Set_Duty(PWM_CH6_PIN35_PP6, 0 )   ;    
//PWM_Channel_Enable(PWM_CH6_PIN35_PP6,1);      

//蜂鸣器
PWM_Channel_Init(PWM_CH0_PIN29_PP0, PWM_CLOCK_SA , PWM_POL_POS , PWM_LEFT_ALIGN)  ;      
PWM_Channel_Set_Freq(PWM_CH0_PIN29_PP0, 1000 )   ;       
PWM_Channel_Set_Duty(PWM_CH0_PIN29_PP0, 0 )   ;    
PWM_Channel_Enable(PWM_CH0_PIN29_PP0,1);        

}
//休眠时调用一次
void  PWM_Sleep_Init(void)
{
        PWM_Channel_Enable(PWM_CH5_PIN34_PP5, 0 );
        PWM_Channel_Enable(PWM_CH7_PIN36_PP7, 0 );
      //  PWM_Channel_Enable(PWM_CH6_PIN35_PP6, 0 );
        PWM_Channel_Enable(PWM_CH0_PIN29_PP0, 0 );
        
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//PWM模块的初始化//一般首次上电调用一次即可
void PWM_Init(void)
{
	PWME = 0;   
	PWMPOL = 0; 
	PWMCLK = 0; 
	PWMCAE = 0; 
	PWMCTL = 0; 

	PWMCTL_CON67 = PWM_Channel_67_Cascade_Mode;
	PWMCTL_CON45 = PWM_Channel_45_Cascade_Mode;
	PWMCTL_CON23 = PWM_Channel_23_Cascade_Mode;
	PWMCTL_CON01 = PWM_Channel_01_Cascade_Mode;

	PWMPRCLK = (PWM_CLOCK_B_DIV << 4) | PWM_CLOCK_A_DIV; //设置PWM clock A/B 的频率
	PWMSCLA = PWMSCLAREG;								 //设置PWM clock SA
	PWMSCLB = PWMSCLBREG;								 //设置PWM clock SB
}
//PWM各个通道的初始化
//通道极性应设置为电路有效电平
// PWM通道 0 / 1 / 4 / 5 可以选择 clock A / clock SA 中的一个作为其时钟输入
// PWM通道 2 / 3 / 6 / 7 可以选择 clock B / clock SB 中的一个作为其时钟输入
//对齐一般选择左对齐
void PWM_Channel_Init(_PWMCHPIN_Type Pin, _PWMClock_Select ClkSrc, _PWMPolarity_Select Pol, _PWMAlign_Select Cae)
{
	INT8U ChBit;
	INT8U Chanel;

	Chanel = Pin >> 4;
	if (Chanel > 7)
		return;

	ChBit = 1 << Chanel;

	if (ClkSrc & 0X01)
		PWMCLK |= ChBit;
	else
		PWMCLK &= ~ChBit;
	if (Pol)
		PWMPOL |= ChBit;
	else
		PWMPOL &= ~ChBit;
	if (Cae)
		PWMCAE |= ChBit;
	else
		PWMCAE &= ~ChBit;

	switch (Chanel)
	{
	case 0:
		PTPRRL &= 0b00001110;
		PTPRRL |= (Pin & 0x01) << 0;
		break; //CH0
	case 1:
		PTPRRL &= 0b00001101;
		PTPRRL |= (Pin & 0x01) << 1;
		break; //CH1
	case 2:
		PTPRRL &= 0b00001011;
		PTPRRL |= (Pin & 0x01) << 2;
		break; //CH2
	case 3:
		PTPRRL &= 0b00000111;
		PTPRRL |= (Pin & 0x01) << 3;
		break; //CH3
	case 4:
		PTPRRH &= 0b11111100;
		PTPRRH |= (Pin & 0x03) << 0;
		break; //CH4
	case 5:
		PTPRRH &= 0b11110011;
		PTPRRH |= (Pin & 0x03) << 2;
		break; //CH5
	case 6:
		PTPRRH &= 0b11001111;
		PTPRRH |= (Pin & 0x03) << 4;
		break; //CH6
	case 7:
		PTPRRH &= 0b00111111;
		PTPRRH |= (Pin & 0x03) << 6;
		break; //CH7
	default:;  //异常
	}
}
//PWM各个通道频率设置//通道周期寄存器设置
void PWM_Channel_Set_Freq(_PWMCHPIN_Type Pin, INT32U Freq)
{
	INT8U ChBit;
	INT8U RegVal;
	INT8U Chanel;
	INT8U *pReg;
	INT32U Prescaler;
	INT32U ClkFreq;

	Chanel = Pin >> 4;
	if (Chanel > 7)
		return;

	ChBit = 1 << Chanel;

	if (ChBit & 0x33) // 0 / 1 / 4 / 5 通道,使用clock A/SA
	{
		if (PWMCLK & ChBit) //使用clock SA
			ClkFreq = PWM_CLOCK_SA_Real_FREQ;
		else //使用clock A
			ClkFreq = PWM_CLOCK_A_FREQ;
	}
	else // 2 / 3 / 6 / 7 通道,使用clock B/SB
	{
		if (PWMCLK & ChBit) //使用clock SB
			ClkFreq = PWM_CLOCK_SB_Real_FREQ;
		else //使用clock B
			ClkFreq = PWM_CLOCK_B_FREQ;
	}

	if (PWMCAE & ChBit)
		ClkFreq /= 2;

	Prescaler = ClkFreq / Freq;

	if (Prescaler > 255)
		RegVal = 255;
	else
		RegVal = (INT8U)Prescaler;

	if (RegVal == 0)
		RegVal = 1;

	pReg = &PWMPER0 + Chanel;
	*pReg = RegVal;
}
//通道占空比设置
void PWM_Channel_Set_Duty(_PWMCHPIN_Type Pin, INT8U Dty)
{
	INT8U ChBit;
	INT8U Chanel;
	INT8U *pPERReg;
	INT8U *pDTYReg;
	INT16U Val;

	Chanel = Pin >> 4;
	if (Chanel > 7)
		return;

	ChBit = 1 << Chanel;

	if (Dty > 100)
		Dty = 100;

	pPERReg = &PWMPER0 + Chanel; //周期
	pDTYReg = &PWMDTY0 + Chanel; //占空比


	Val = (INT16U)Dty;
	Val *= (INT16U)(*pPERReg);
	*pDTYReg = (INT8U)(Val / 100);
}

//通道开启和关闭。1开启，0关闭
void PWM_Channel_Enable(_PWMCHPIN_Type Pin, INT8U Onoff)
{
	INT8U ChBit, Chanel;

	Chanel = Pin >> 4; 
	if (Chanel > 7)
		return;

	ChBit = 1 << Chanel;
	if (Onoff)
		PWME |= ChBit;
	else
		PWME &= ~ChBit;
}
//级联通道的频率设置
void PWM_Channel_Cascade_Set_Freq(_PWMCHPIN_Type Pin, INT32U Freq)
{
	INT8U ChBit;
	INT16U RegVal;
	INT8U Chanel;
	INT16U *pReg;
	INT32U Prescaler;
	INT32U ClkFreq;

	Chanel = Pin >> 4;
	if (Chanel > 7)
		return;
	if (Chanel & 0x01)
	{
		ChBit = 1 << Chanel;
		if (ChBit & 0x33) // 0 / 1 / 4 / 5 通道,使用clock A/SA
		{
			if (PWMCLK & ChBit) //使用clock SA
				ClkFreq = PWM_CLOCK_SA_Real_FREQ;
			else //使用clock A
				ClkFreq = PWM_CLOCK_A_FREQ;
		}
		else // 2 / 3 / 6 / 7 通道,使用clock B/SB
		{
			if (PWMCLK & ChBit) //使用clock SB
				ClkFreq = PWM_CLOCK_SB_Real_FREQ;
			else //使用clock B
				ClkFreq = PWM_CLOCK_B_FREQ;
		}

		if (PWMCAE & ChBit)
			ClkFreq /= 2;

		Prescaler = ClkFreq / Freq;

		if (Prescaler > 65535)
			RegVal = 65535;
		else
			RegVal = (INT16U)Prescaler;

		if (RegVal == 0)
			RegVal = 1;

		pReg = (&PWMPER01 + (Chanel >> 1));
		*pReg = RegVal;
	}
}
//级联通道占空比设置
void PWM_Channel_Cascade_Set_Duty(_PWMCHPIN_Type Pin, INT8U Dty)
{
	INT8U ChBit;
	INT8U Chanel;
	INT16U *pPERReg;
	INT16U *pDTYReg;
	INT32U Val;

	Chanel = Pin >> 4;
	if (Chanel > 7)
		return;
	if (Chanel & 0x01)
	{
		ChBit = 1 << Chanel;

		if (Dty > 100)
			Dty = 100;

		pPERReg = (&PWMPER01 + (Chanel >> 1)); //周期
		pDTYReg = (&PWMDTY01 + (Chanel >> 1)); //占空比

		Val = (INT32U)Dty;
		Val *= (INT32U)(*pPERReg);
		*pDTYReg = (INT16U)(Val / 100);
	}
}

