SI5351A的信号发生器驱动程序

IIC驱动部分请自己编写;该驱动程序是验证通过的。

#include "si5351a_cfg.h"

//===变量定义
SI5351A_HandlerType			g_SI5351ADevice0={0};
pSI5351A_HandlerType		pSI5351ADevice0=&g_SI5351ADevice0;

///
//函		数:
//功		能:参数初始化
//输入参数:
//输出参数:
//说		明:
//
void SI5351A_I2C_ParamsInit(SI5351A_HandlerType* SI5351Ax)
{
	//---初始化参数
	memset(SI5351Ax->msgClockCTRL,0x4F, SI5351A_CLKOUT_CHANNEL_SIZE);
	//---配置参数
	SI5351Ax->msgIsResetPll=0;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_Device0_Init(SI5351A_HandlerType* SI5351Ax)
{
	SI5351Ax->msgI2C.msgI2Cx = NULL;
	SI5351Ax->msgI2C.msgSCL.msgGPIOPort = GPIOB;
	SI5351Ax->msgI2C.msgSCL.msgGPIOBit = LL_GPIO_PIN_8;
	SI5351Ax->msgI2C.msgSDA.msgGPIOPort = GPIOB;
	SI5351Ax->msgI2C.msgSDA.msgGPIOBit = LL_GPIO_PIN_9;
	SI5351Ax->msgI2C.msgModelIsHW = 0;
	SI5351Ax->msgI2C.msgPluseWidth = 1;
	SI5351Ax->msgI2C.msgFuncDelayus = NULL;
	SI5351Ax->msgI2C.msgAddr = SI5351A_WADDR;
	SI5351Ax->msgI2C.msgClockSpeed = 0;
	return OK_0;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_Device1_Init(SI5351A_HandlerType* SI5351Ax)
{
	return OK_0;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_Device2_Init(SI5351A_HandlerType* SI5351Ax)
{
	return OK_0;
}

///
//函		数:
//功		能: 写单独模式
//输入参数:
//输出参数:
//说		明: 软件模拟I2C传输命令
//
UINT8_T SI5351A_SWI2C_WriteSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T val)
{
	UINT8_T _return = OK_0;
	//---启动并发送写操作
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), addr);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
	//---判断应答
	if (_return)
	{
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送寄存器数据
	I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), val);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
	//---判断应答
	if (_return)
	{
		_return = ERROR_3 + 1;
		goto GoToExit;
	}	
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明: 硬件I2C传输命令
//
UINT8_T SI5351A_HWI2C_WriteSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T val)
{
	return ERROR_1;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明: I2C传输命令
//
UINT8_T SI5351A_I2C_WriteSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T val)
{
	if (SI5351Ax->msgI2C.msgModelIsHW == 0)
	{
		//---软件模拟I2C
		return SI5351A_SWI2C_WriteSingle(SI5351Ax, addr, val);
	}
	else
	{
		//---硬件I2C
		return SI5351A_HWI2C_WriteSingle(SI5351Ax, addr, val);
	}
}

///
//函		数:
//功		能: 读单独模式
//输入参数:
//输出参数:
//说		明: 软件模拟I2C传输命令
//
UINT8_T SI5351A_SWI2C_ReadSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal)
{
	UINT8_T _return = OK_0;
	//---启动写数据
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), addr);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
	if (_return != OK_0)
	{
		//---发送数据失败
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	//---启动读取数据
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 0);
	if (_return != OK_0)
	{
		//---启动读数据失败
		_return = ERROR_4;
		goto GoToExit;
	}
	//---读取数据
	_return = I2CTask_MSW_ReadByte(&(SI5351Ax->msgI2C));
	//---发送应答信号
	I2CTask_MSW_SendACK(&(SI5351Ax->msgI2C), 1);
	if (pVal!=NULL)
	{
		*pVal=_return;
	}
	_return = OK_0;
	//---退出入口函数
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_HWI2C_ReadSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal)
{
	return ERROR_1;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明: I2C传输命令
//
UINT8_T SI5351A_I2C_ReadSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal)
{
	if (SI5351Ax->msgI2C.msgModelIsHW == 0)
	{
		//---软件模拟I2C
		return SI5351A_SWI2C_ReadSingle(SI5351Ax, addr, pVal);
	}
	else
	{
		//---硬件I2C
		return SI5351A_HWI2C_ReadSingle(SI5351Ax, addr, pVal);
	}
}

///
//函		数:
//功		能: 写Bulk模式
//输入参数:
//输出参数:
//说		明: 软件模拟I2C传输命令
//
UINT8_T SI5351A_SWI2C_WriteBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	UINT8_T _return = OK_0;
	UINT8_T i = 0;
	//---启动并发送写操作
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送地址
	I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), addr);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
	//---判断应答
	if (_return)
	{
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送数据
	for (i = 0; i < length; i++)
	{
		//---发送数据
		I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), pVal[i]);
		//---读取ACK
		_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
		//---判断应答
		if (_return)
		{
			_return = ERROR_4 + i;
			goto GoToExit;
		}
	}
	//---退出入口函数
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_HWI2C_WriteBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	return ERROR_1;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_WriteBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	if (SI5351Ax->msgI2C.msgModelIsHW == 0)
	{
		//---软件模拟I2C
		return SI5351A_SWI2C_WriteBulk(SI5351Ax, addr, pVal, length);
	}
	else
	{
		//---硬件I2C
		return SI5351A_HWI2C_WriteBulk(SI5351Ax, addr, pVal,length);
	}
}

///
//函		数:
//功		能: 读Bulk模式
//输入参数:
//输出参数:
//说		明: 软件模拟I2C传输命令
//
UINT8_T SI5351A_SWI2C_ReadBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	UINT8_T _return = OK_0;
	UINT16_T i = 0;
	//---启动写数据
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&(SI5351Ax->msgI2C), addr);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&(SI5351Ax->msgI2C));
	if (_return != OK_0)
	{
		//---发送数据失败
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	//---启动读取数据
	_return = I2CTask_MSW_START(&(SI5351Ax->msgI2C), 0);
	if (_return != OK_0)
	{
		//---启动读数据失败
		_return = ERROR_4;
		goto GoToExit;
	}
	for (i = 0; i < length; i++)
	{
		//---读取数据
		pVal[i] = I2CTask_MSW_ReadByte(&(SI5351Ax->msgI2C));
		if (i == (length - 1))
		{
			_return = 1;
		}
		//---发送应答信号
		I2CTask_MSW_SendACK(&(SI5351Ax->msgI2C), _return);
	}
	_return = OK_0;
	//---退出入口函数
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&(SI5351Ax->msgI2C));
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_HWI2C_ReadBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	return ERROR_1;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_ReadBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length)
{
	if (SI5351Ax->msgI2C.msgModelIsHW == 0)
	{
		//---软件模拟I2C
		return SI5351A_SWI2C_ReadBulk(SI5351Ax, addr, pVal, length);
	}
	else
	{
		//---硬件I2C
		return SI5351A_HWI2C_ReadBulk(SI5351Ax, addr, pVal, length);
	}
}



///
//fVCO is the PLL output, and must be between 600..900MHz,
//fVCO = fXTAL * (a + (b / c))
//fXTAL = the crystal input frequency
//a = an integer between 15 and 90
//b = the fractional numerator(0..1, 048, 575)
//c = the fractional denominator(1..1, 048, 575)
///

///
//函		数:
//功		能:设置pll时钟
//输入参数:	
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_ConfigMSNBReg(SI5351A_HandlerType* SI5351Ax, UINT8_T regMSNAddr, UINT32_T a, UINT32_T b, UINT32_T c)
{
	UINT32_T p1 = 0;
	UINT32_T p2 = 0;
	UINT32_T p3 = 0;

	if (b == 0)
	{
		p1 = (UINT32_T)(128 * a - 512);
		p2 = 0;
		p3 = c;
	}
	else
	{
		p1 = (UINT32_T)(128 * ((float)b / (float)c));
		p2 = (UINT32_T)(128 * b - c * p1);
		p1 = (UINT32_T)(128 * a + p1 - 512);
		p3 = c;
	}

	UINT8_T params[10];
	UINT8_T i = 0;
	UINT8_T temp;

	// Registers 26-27 for PLLA
	temp = ((p3 >> 8) & 0xFF);
	params[i++] = temp;
	temp = (UINT8_T)(p3 & 0xFF);
	params[i++] = temp;

	// Register 28 for PLLA
	temp = (UINT8_T)((p1 >> 16) & 0x03);
	params[i++] = temp;

	// Registers 29-30 for PLLA
	temp = (UINT8_T)((p1 >> 8) & 0xFF);
	params[i++] = temp;

	temp = (UINT8_T)(p1 & 0xFF);
	params[i++] = temp;

	// Register 31 for PLLA
	temp = (UINT8_T)((p3 >> 12) & 0xF0);
	temp += (UINT8_T)((p2 >> 16) & 0x0F);
	params[i++] = temp;

	// Registers 32-33 for PLLA
	temp = (UINT8_T)((p2 >> 8) & 0xFF);
	params[i++] = temp;

	temp = (UINT8_T)(p2 & 0xFF);
	params[i++] = temp;
	//---写入命令
	return SI5351A_I2C_WriteBulk(SI5351Ax, regMSNAddr, params, i);
}

//
//fOUT = fVCO / MSx
//a + b / c
//a = The integer value, which must be 4, 6 or 8 in integer mode(MSx_INT = 1)
//or 8..900 in fractional mode(MSx_INT = 0).
//b = The fractional numerator(0..1, 048, 575)
//c = The fractional denominator(1..1, 048, 575)
//

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_ConfigMSREG(SI5351A_HandlerType* SI5351Ax, UINT8_T regMSAddr, UINT32_T pllDIV, UINT32_T clkoutDIV)
{
	UINT32_T p1 = 0;
	UINT32_T p2 = 0;
	UINT32_T p3 = 0;
	//---a=pllDIV
	//---b=0
	//---c=1
	p1 = (UINT32_T)(128 * pllDIV - 512);
	p2 = 0;
	p3 = 1;
	UINT8_T params[10];
	UINT8_T i = 0;
	UINT8_T temp;

	// Registers 42-43 for CLK0
	temp = (UINT8_T)((p3 >> 8) & 0xFF);
	params[i++] = temp;
	temp = (UINT8_T)(p3 & 0xFF);
	params[i++] = temp;

	// Register 44 for CLK0
	temp = ((UINT8_T)((p1 >> 16) & 0x03) | clkoutDIV);
	params[i++] = temp;

	// Registers 45-46 for CLK0
	temp = (UINT8_T)((p1 >> 8) & 0xFF);
	params[i++] = temp;

	temp = (UINT8_T)(p1 & 0xFF);
	params[i++] = temp;

	// Register 47 for CLK0
	temp = ((UINT8_T)((p3 >> 12) & 0xF0)) | ((UINT8_T)((p2 >> 16) & 0x0F));
	params[i++] = temp;

	// Registers 48-49 for CLK0
	temp = (UINT8_T)((p2 >> 8) & 0xFF);
	params[i++] = temp;

	temp = (UINT8_T)(p2 & 0xFF);
	params[i++] = temp;

	//---写入命令
	return SI5351A_I2C_WriteBulk(SI5351Ax, regMSAddr, params, i);
}

///
//函		数:
//功		能:计算配置参数
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_CalcConfig(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, UINT64_T freq)
{
	UINT64_T pllFreq;
	UINT8_T  clkoutDIV = 0;
	UINT32_T a = 0;
	UINT32_T b = 0;
	UINT32_T c = 0;
	UINT32_T pllDIV = 0;
	//---输出时钟---8 KHz
	if (freq < 8000ULL)
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_128;
		freq <<= 7;
	}
	//---输出时钟---8-16 KHz
	else if ((freq >= 8000ULL) && (freq < 16000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_64;
		freq <<= 6;
	}
	//---输出时钟---16-32 KHz
	else if ((freq >= 16000ULL) && (freq < 32000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_32;
		freq <<= 5;
	}
	//---输出时钟---32-64 KHz
	else if ((freq >= 32000ULL) && (freq < 64000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_16;
		freq <<= 4;
	}
	//---输出时钟---64-128 KHz
	else if ((freq >= 64000ULL) && (freq < 128000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_8;
		freq <<= 3;
	}
	//---输出时钟---128-256 KHz
	else if ((freq >= 128000ULL) && (freq < 256000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_4;
		freq <<= 2;
	}
	//---输出时钟---256-512 KHz
	else if ((freq >= 256000ULL) && (freq < 512000ULL))
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_2;
		freq <<= 1;
	}
	else
	{
		clkoutDIV = SI5351A_CLKOUT_DIV_1;
	}
	//---校验输出频率下限
	if (freq < SI5351A_CLKOUT_MIN_HZ)
	{
		freq = SI5351A_CLKOUT_MIN_HZ;
	}
	//---校验输出频率上限
	if (freq > SI5351A_CLKOUT_MAX_HZ)
	{
		freq = SI5351A_CLKOUT_MAX_HZ;
	}
	//---锁相环频率:900 mhz,计算锁相环的分频数Fvco;
	pllDIV = (UINT32_T)(900000000 / freq);
	//---校验界限
	if (pllDIV > SI5351A_MS_A_MAX)
	{
		pllDIV = SI5351A_MS_A_MAX;
	}
	if (pllDIV < SI5351A_MS_A_MIN)
	{
		pllDIV = SI5351A_MS_A_MIN;
	}
	//---保证分频数偶数
	if ((pllDIV & 0x01) != 0)
	{
		pllDIV--;
	}
	//---重新计算PLL的频率
	pllFreq = pllDIV * freq;
	a = (UINT32_T)(pllFreq / SI5351A_CLK_HZ);
	b = (UINT32_T)(((pllFreq % SI5351A_CLK_HZ) * 1048575) / SI5351A_CLK_HZ);
	c = 1048575;
	//---校验界限
	if (b > SI5351A_PLL_B_MAX)
	{
		b -= 1048575;
		a++;
	}
	//---校验界限
	if (a > SI5351A_PLL_A_MAX)
	{
		a = SI5351A_PLL_A_MAX;
	}
	if (a < SI5351A_PLL_A_MIN)
	{
		a = SI5351A_PLL_A_MIN;
	}
	clkChannel=(clkChannel > (SI5351A_CLKOUT_CHANNEL_SIZE - 1)) ? (SI5351A_CLKOUT_CHANNEL_SIZE - 1) : clkChannel;
	//---配置PLLA
	SI5351A_I2C_ConfigMSNBReg(SI5351Ax, SI5351A_REG_MSNA_ADDR, a, b, c);
	//---配置MS,通道0的输出值
	clkoutDIV=SI5351A_I2C_ConfigMSREG(SI5351Ax, SI5351A_REG_MS0_ADDR + clkChannel * 18, pllDIV, clkoutDIV);
	//---校验是否复位PLL
	if (SI5351Ax->msgIsResetPll!=0)
	{
		//---复位PLL
		clkoutDIV= SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_PLL_RST_ADDR, SI5351A_PLL_RST_A);
	}
	//---使能通道CLK0输出
	// SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_CLK0_ADDR + clkChannel, SI5351Ax->msgClockCTRL[clkChannel]);
	return clkoutDIV;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_Init(SI5351A_HandlerType* SI5351Ax, void(*pFuncDelayus)(UINT32_T delay), UINT8_T isHWI2C)
{
	UINT8_T _return = OK_0;
	//---参数初始化
	SI5351A_I2C_ParamsInit(SI5351Ax);
	//---选择设备参数
	if ((SI5351Ax != NULL) && (SI5351Ax == SI5351A_TASK_ONE))
	{
		SI5351A_I2C_Device0_Init(SI5351Ax);
	}
	else if ((SI5351Ax != NULL) && (SI5351Ax == SI5351A_TASK_TWO))
	{
		SI5351A_I2C_Device1_Init(SI5351Ax);
	}
	else if ((SI5351Ax != NULL) && (SI5351Ax == SI5351A_TASK_THREE))
	{
		SI5351A_I2C_Device2_Init(SI5351Ax);
	}
	else
	{
		return ERROR_1;
	}

	//---判断是硬件I2C还是软件I2C
	if (isHWI2C)
	{
		//_return= I2CTask_MHW_Init(&(WM8510x->msgI2C), pFuncDelay);
		SI5351Ax->msgI2C.msgModelIsHW = 1;
	}
	else
	{
		_return = I2CTask_MSW_Init(&(SI5351Ax->msgI2C), pFuncDelayus);
		SI5351Ax->msgI2C.msgModelIsHW = 0;
	}
	_return = SI5351A_I2C_START(SI5351Ax);
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_DeInit(SI5351A_HandlerType* SI5351Ax)
{
	//---注销I2C设备
	if (SI5351Ax->msgI2C.msgModelIsHW == 1)
	{
		return ERROR_1;
	}
	else
	{
		return I2CTask_MSW_DeInit(&(SI5351Ax->msgI2C));
	}
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_I2C_START(SI5351A_HandlerType* SI5351Ax)
{
	//---读取ID信息
	UINT8_T _return = SI5351A_ReadID(SI5351Ax);
	if (_return==OK_0)
	{
		UINT8_T temp[8]={0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00};
		//---复位PLL
		SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_PLL_RST_ADDR, SI5351A_PLL_RST_B | SI5351A_PLL_RST_A);
		//---各通道进入PWR模式
		SI5351A_I2C_WriteBulk(SI5351Ax, SI5351A_REG_CLK0_ADDR,temp,3);
		//---设置驱动能力
		SI5351A_SetClockChannelIDRV(SI5351Ax,0, SI5351A_CLK_IDRV_2mA);
		//---变量归零处理
		memset(temp, 0x00, 8);
		SI5351A_I2C_WriteBulk(SI5351Ax, SI5351A_REG_SSC_EN_ADDR,temp,8);
		SI5351A_I2C_WriteBulk(SI5351Ax, 157, temp, 8);
		//---配置寄存器
		SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_FANOUT_ENABLE_ADDR, 0xC0);
	}
	return _return;
}

///
//函		数:
//功		能:复位PLL
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_PLLRST(SI5351A_HandlerType* SI5351Ax, UINT8_T pllIndex)
{
	if (pllIndex == SI5351A_PLL_RST_B)
	{
		return SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_PLL_RST_ADDR, SI5351A_PLL_RST_B);
	}
	else
	{
		return SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_PLL_RST_ADDR, SI5351A_PLL_RST_A);
	}
}

///
//函		数:
//功		能:读取ID信息,使用时钟内部负载电容的配置作为ID表示,默认上电之后有个初值0B11XXXXXX
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_ReadID(SI5351A_HandlerType* SI5351Ax)
{
	UINT8_T temp=0;
	UINT8_T  _return= SI5351A_I2C_ReadSingle(SI5351Ax, SI5351A_REG_CRYSTAL_LOAD_ADDR, &temp);
	if (_return==OK_0)
	{
		temp>>=6;
		if ((temp&0x03)==0x03)
		{
			_return=OK_0;
		}
		else
		{
			_return=ERROR_2;
		}
	}
	return _return;
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_SetFreqHz(SI5351A_HandlerType* SI5351Ax,UINT8_T clkChannel, UINT64_T freq)
{
	return SI5351A_CalcConfig(SI5351Ax, clkChannel,freq);
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_SetFreqKHz(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, float freqKHz)
{
	UINT64_T freq= freqKHz*1000;
	return SI5351A_CalcConfig(SI5351Ax, clkChannel, freq);
}

///
//函		数:
//功		能:
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_SetFreqMHz(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, float freqMHz)
{
	UINT64_T freq = freqMHz * 1000000;
	return SI5351A_CalcConfig(SI5351Ax, clkChannel, freq);
}

///
//函		数:
//功		能:设置时钟输出通道的驱动能力
//输入参数:
//输出参数:
//说		明:
//
UINT8_T SI5351A_SetClockChannelIDRV(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, UINT8_T idrv)
{
	clkChannel=((clkChannel>(SI5351A_CLKOUT_CHANNEL_SIZE-1))?(SI5351A_CLKOUT_CHANNEL_SIZE-1):clkChannel);
	SI5351Ax->msgClockCTRL[clkChannel]&=0xFC;
	SI5351Ax->msgClockCTRL[clkChannel]|=idrv;
	return SI5351A_I2C_WriteSingle(SI5351Ax, SI5351A_REG_CLK0_ADDR+clkChannel, SI5351Ax->msgClockCTRL[clkChannel]);
}

#ifndef SI5351A_CFG_H_
#define SI5351A_CFG_H_
//
#ifdef __cplusplus
extern "C" {
#endif
	//
	//===包含的头文件
	#include"complier_lib.h"
	#include "i2c_task.h"
	//
	//===输入时钟频率
	#define SI5351A_CLK_HZ							25000000ULL		
	//===锁相环的最大或者最小时钟
	#define SI5351A_PLL_MAX_HZ						900000000ULL
	#define SI5351A_PLL_MIN_HZ						600000000ULL
	//===输出的最大频率
	#define SI5351A_CLKOUT_MAX_HZ					150000000ULL
	#define SI5351A_CLKOUT_MIN_HZ					8000ULL
	//===最大输出通道数据
	#define SI5351A_CLKOUT_CHANNEL_SIZE				3
	
	//===寄存器地址
	#define SI5351A_REG_STATUS_ADDR					0
	#define SI5351A_REG_CLKEN_ADDR					3
	#define SI5351A_REG_CLKIN_ADDR					15
	#define SI5351A_REG_CLK0_ADDR					16			// Register definitions
	#define SI5351A_REG_CLK1_ADDR					17
	#define SI5351A_REG_CLK2_ADDR					18
	#define SI5351A_REG_CLK3_0_DISABLE_STATE_ADDR	24
	#define SI5351A_REG_MSNA_ADDR					26
	#define SI5351A_REG_MSNB_ADDR					34
	#define SI5351A_REG_MS0_ADDR					42
	#define SI5351A_REG_MS1_ADDR					50
	#define SI5351A_REG_MS2_ADDR					58
	#define SI5351A_REG_SSC_EN_ADDR					149
	#define SI5351A_REG_SSDN_P1_ADDR				153
	#define SI5351A_REG_VCXO_PARAME_ADDR			162
	#define SI5351A_REG_PLL_RST_ADDR				177
	#define SI5351A_REG_CRYSTAL_LOAD_ADDR			183
	#define SI5351A_REG_FANOUT_ENABLE_ADDR			187

	//===输入时钟配置	   CRYSTAL_LOAD
	#define SI5351A_CLKIN_DIV_1						(0<<6)
	#define SI5351A_CLKIN_DIV_2						(1<<6)
	#define SI5351A_CLKIN_DIV_4						(2<<6)
	#define SI5351A_CLKIN_DIV_8						(3<<6)
	#define SI5351A_PLLB_SRC						(1<<3)
	#define SI5351A_PLLA_SRC						(1<<2)

	//===输出时钟控制配置
	#define SI5351A_CLK_PWR							(1<<7)
	#define SI5351A_CLK_MS_INT						(1<<6)
	#define SI5351A_CLK_MS_SRC						(1<<5)
	#define SI5351A_CLK_INV							(1<<4)
	#define SI5351A_CLK_SRC_MS						(3<<2)
	#define SI5351A_CLK_SRC_XTAL					(0<<2)
	#define SI5351A_CLK_SRC_CLKIN					(1<<2)
	#define SI5351A_CLK_IDRV_2mA					(0)
	#define SI5351A_CLK_IDRV_4mA					(1)
	#define SI5351A_CLK_IDRV_6mA					(2)
	#define SI5351A_CLK_IDRV_8mA					(3)

	//===输出时钟的分频数
	#define SI5351A_CLKOUT_DIV_1					(0<<4)	
	#define SI5351A_CLKOUT_DIV_2					(1<<4)
	#define SI5351A_CLKOUT_DIV_4					(2<<4)
	#define SI5351A_CLKOUT_DIV_8					(3<<4)
	#define SI5351A_CLKOUT_DIV_16					(4<<4)
	#define SI5351A_CLKOUT_DIV_32					(5<<4)
	#define SI5351A_CLKOUT_DIV_64					(6<<4)
	#define SI5351A_CLKOUT_DIV_128					(7<<4)

	//===时钟输出驱动负载电容
	#define SI5351A_CRYSTAL_LOAD_6pF				(1<<6)|0x12
	#define SI5351A_CRYSTAL_LOAD_8pF				(2<<6)|0x12
	#define SI5351A_CRYSTAL_LOAD_10pF				(3<<6)|0x12

	//===复位PLL设置
	#define SI5351A_PLL_RST_B						(1<<7)
	#define SI5351A_PLL_RST_A						(1<<5)

	//---配置CLK的不使能状态
	

	//===上下限参数
	#define SI5351A_PLL_A_MIN						15
	#define SI5351A_PLL_A_MAX						90
	#define SI5351A_PLL_B_MAX						(SI5351A_PLL_C_MAX-1)
	#define SI5351A_PLL_C_MAX						1048575
	#define SI5351A_MS_A_MIN						6
	#define SI5351A_MS_A_MAX						1800

	//===写命令
	#define SI5351A_WADDR							0xC0	
	//===读命令
	#define SI5351A_RADDR							0xC1	

	//===结构体定义
	typedef struct _SI5351A_HandlerType				SI5351A_HandlerType;
	//===指针结构体定义
	typedef struct _SI5351A_HandlerType				*pSI5351A_HandlerType;

	//===定义结构
	struct _SI5351A_HandlerType
	{
		UINT8_T msgClockCTRL[SI5351A_CLKOUT_CHANNEL_SIZE];		//---CLK输出通道的配置寄存器
		UINT8_T msgIsResetPll;									//---是否配置完成之后复位PLL,1---复位,0---不复位
		I2C_HandlerType msgI2C;									//---使用的I2C设备
	};

	//===定义的任务函数
	#define SI5351A_TASK_ONE						pSI5351ADevice0
	#define SI5351A_TASK_TWO						0
	#define SI5351A_TASK_THREE						0
	
	//===外部调用接口
	extern SI5351A_HandlerType						g_SI5351ADevice0;
	extern pSI5351A_HandlerType						pSI5351ADevice0;
	
	//===函数定义
	UINT8_T SI5351A_I2C_WriteSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T val);
	UINT8_T SI5351A_I2C_ReadSingle(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal);
	UINT8_T SI5351A_I2C_WriteBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length);
	UINT8_T SI5351A_I2C_ReadBulk(SI5351A_HandlerType* SI5351Ax, UINT8_T addr, UINT8_T* pVal, UINT8_T length);
	UINT8_T SI5351A_I2C_Init(SI5351A_HandlerType* SI5351Ax, void(*pFuncDelayus)(UINT32_T delay), UINT8_T isHWI2C);
	UINT8_T SI5351A_I2C_DeInit(SI5351A_HandlerType* SI5351Ax);
	UINT8_T SI5351A_I2C_START(SI5351A_HandlerType* SI5351Ax);
	UINT8_T SI5351A_PLLRST(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel);
	UINT8_T SI5351A_ReadID(SI5351A_HandlerType* SI5351Ax);
	UINT8_T SI5351A_SetFreqHz(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, UINT64_T freq);
	UINT8_T SI5351A_SetFreqKHz(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, float freqKHz);
	UINT8_T SI5351A_SetFreqMHz(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, float freqMHz);
	UINT8_T SI5351A_SetClockChannelIDRV(SI5351A_HandlerType* SI5351Ax, UINT8_T clkChannel, UINT8_T idrv);
	//
#ifdef __cplusplus
}
#endif
//
#endif /*SI5351A_CFG_H_ */

/******************************************** 主控芯片:STM32F405RGT6主频168Mhz 晶体频率:HSE=8Mhz SYSCLK=168Mhz 模块型号:SI5351A 通讯方式: 函数功能:Si5351时钟芯片 作者:苏夏雨 授权:未经作者允许,禁止转载 ********************************************/ #ifndef _si5351a_h #define _si5351a_h #include "system.h" //Si5351寄存器声明 #define SI_CLK0_CONTROL 16 // Register definitions #define SI_CLK1_CONTROL 17 #define SI_CLK2_CONTROL 18 #define SI_SYNTH_PLL_A 26 #define SI_SYNTH_PLL_B 34 #define SI_SYNTH_MS_0 42 #define SI_SYNTH_MS_1 50 #define SI_SYNTH_MS_2 58 #define SI_PLL_RESET 177 #define SI_R_DIV_1 0x00 // R-division ratio definitions #define SI_R_DIV_2 0b00010000 #define SI_R_DIV_4 0b00100000 #define SI_R_DIV_8 0b00110000 #define SI_R_DIV_16 0b01000000 #define SI_R_DIV_32 0b01010000 #define SI_R_DIV_64 0b01100000 #define SI_R_DIV_128 0b01110000 #define SI_CLK_SRC_PLL_A 0x00 #define SI_CLK_SRC_PLL_B 0b00100000 #define XTAL_FREQ 25000000 // Crystal frequency //IIC总线引脚配置 #define SDA(n) {n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);} #define CLK(n) {n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET);} //相关函数声明 void Si5351Init(void);//初始化Si5351的GPIO void SetPLLClk(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom);//设置PPL时钟 void SetFrequency(uint32_t frequency);//时钟Si5351时钟频率 void SetMultisynth(uint8_t synth,uint32_t divider,uint8_t rDiv);//设置多synth #endif
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值