在我之前发布的《ZYNQ IIC EEPROM读写例程》基础上,借用其IIC读写函数,其余代码参照DK7IH的AVR例子,即可实现SI5351控制。
硬件平台为PYNQ-Z2+ELEKTOR SDR,刚开始读写不成功,用示波器看IIC波形,没有拉低,因为PYNQ-Z2上已经有上拉电阻,把ELEKTOR SDR上的上拉电阻去掉,可正常读写,但是用示波器测频率,偏了9M,检查代码发现,DK7IH的代码中定义了INTERFREQUENCY 9000000,将其改成0,即可。
输出10MHz波形如下:

完整代码如下:

/***************************** Include Files *********************************/#include "xparameters.h"
#include "sleep.h"
#include "xiicps.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"/************************** Constant Definitions *****************************//** The following constants map to the XPAR parameters created in the* xparameters.h file. They are defined here such that a user can easily* change all the needed parameters in one place.*/
#define IIC_DEVICE_ID   XPAR_XIICPS_0_DEVICE_ID
#define INTC_DEVICE_ID  XPAR_SCUGIC_SINGLE_DEVICE_ID
#define IIC_INTR_ID XPAR_XIICPS_0_INTR#define INTERFREQUENCY 0000000/
//Defines for Si5351
/
#define PLLRATIO 36
#define CFACTOR 1048575//Set of Si5351A register addresses
#define CLK_ENABLE_CONTROL       3
#define PLLX_SRC                15
#define CLK0_CONTROL            16
#define CLK1_CONTROL            17
#define CLK2_CONTROL            18
#define SYNTH_PLL_A             26
#define SYNTH_PLL_B             34
#define SYNTH_MS_0              42
#define SYNTH_MS_1              50
#define SYNTH_MS_2              58
#define PLL_RESET              177
#define XTAL_LOAD_CAP          183//Tuning
int calc_tuningfactor(void);int tuningcount = 0;
int tuning = 0;
int laststate = 0; //Last state of rotary encoder//SI5351 Declarations & frequency
void si5351_write(int, int);
void si5351_start(void);
void si5351_set_freq(int, unsigned long);/** The following constant defines the address of the IIC Slave device on the* IIC bus. Note that since the address is only 7 bits, this constant is the* address divided by 2.*/
#define IIC_SLAVE_ADDR      0x60
#define IIC_SCLK_RATE       100000/** The page size determines how much data should be written at a time.* The write function should be called with this as a maximum byte count.*/
#define PAGE_SIZE       16/** The Starting address in the IIC EEPROM on which this test is performed.*/
#define EEPROM_START_ADDRESS    0/**************************** Type Definitions *******************************//** The AddressType should be u8 as the address pointer in the on-board* EEPROM is 1 byte.*/
typedef u8 AddressType;/***************** Macros (Inline Functions) Definitions *********************//************************** Function Prototypes ******************************/int IicPsEepromIntrExample(void);
int EepromWriteData(u16 ByteCount);
int MuxInit(void);
int EepromReadData(u8 *BufferPtr, u16 ByteCount);static int SetupInterruptSystem(XIicPs * IicInstPtr);static void Handler(void *CallBackRef, u32 Event);/************************** Variable Definitions *****************************/XIicPs IicInstance;      /* The instance of the IIC device. */
XScuGic InterruptController;    /* The instance of the Interrupt Controller. *//** Write buffer for writing a page.*/
u8 WriteBuffer[sizeof(AddressType) + PAGE_SIZE];u8 ReadBuffer[PAGE_SIZE];  /* Read buffer for reading a page. */volatile u8 TransmitComplete;  /* Flag to check completion of Transmission */
volatile u8 ReceiveComplete;    /* Flag to check completion of Reception */
volatile u32 TotalErrorCount;/************************** Function Definitions *****************************//*****************************************************************************/
/**
* Main function to call the Iic EEPROM interrupt example.
*
* @param   None.
*
* @return  XST_SUCCESS if successful else XST_FAILURE.
*
* @note        None.
*
******************************************************************************/
int main(void)
{int Status;xil_printf("\n\r********************************************************");xil_printf("\n\r********************************************************");xil_printf("\n\r**     PYNQ  - SI5351 Test                        **");xil_printf("\n\r********************************************************");xil_printf("\n\r********************************************************\r\n");/** Run the Iic EEPROM interrupt mode example.*/Status = IicPsEepromIntrExample();if (Status != XST_SUCCESS) {xil_printf("IIC EEPROM Interrupt Example Test Failed\r\n");return XST_FAILURE;}xil_printf("Successfully ran IIC EEPROM Interrupt Example Test\r\n");//return XST_SUCCESS;unsigned long f_vfo = 14212789;si5351_start();si5351_set_freq(SYNTH_MS_0, f_vfo);si5351_set_freq(SYNTH_MS_1, 10000000);si5351_set_freq(SYNTH_MS_2, 3552000);
}/*****************************************************************************/
/**
* This function writes, reads, and verifies the data to the IIC EEPROM. It
* does the write as a single page write, performs a buffered read.
*
* @param   None.
*
* @return  XST_SUCCESS if successful else XST_FAILURE.
*
* @note        None.
*
******************************************************************************/
int IicPsEepromIntrExample(void)
{int Status;XIicPs_Config *ConfigPtr;   /* Pointer to configuration data *//** Initialize the IIC driver so that it is ready to use.*/ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);if (ConfigPtr == NULL) {return XST_FAILURE;}Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr,ConfigPtr->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}/** Setup the Interrupt System.*/Status = SetupInterruptSystem(&IicInstance);if (Status != XST_SUCCESS) {return XST_FAILURE;}/** Setup the handlers for the IIC that will be called from the* interrupt context when data has been sent and received, specify a* pointer to the IIC driver instance as the callback reference so* the handlers are able to access the instance data.*/XIicPs_SetStatusHandler(&IicInstance, (void *) &IicInstance, Handler);/** Set the IIC serial clock rate.*/XIicPs_SetSClk(&IicInstance, IIC_SCLK_RATE);return XST_SUCCESS;
}/*****************************************************************************/
/**
* This function writes a buffer of data to the IIC serial EEPROM.
*
* @param   ByteCount contains the number of bytes in the buffer to be
*       written.
*
* @return  XST_SUCCESS if successful else XST_FAILURE.
*
* @note        The Byte count should not exceed the page size of the EEPROM as
*       noted by the constant PAGE_SIZE.
*
******************************************************************************/
int EepromWriteData(u16 ByteCount)
{TransmitComplete = FALSE;/** Send the Data.*/XIicPs_MasterSend(&IicInstance, WriteBuffer,ByteCount, IIC_SLAVE_ADDR);/** Wait for the entire buffer to be sent, letting the interrupt* processing work in the background, this function may get* locked up in this loop if the interrupts are not working* correctly.*/while (TransmitComplete == FALSE) {if (0 != TotalErrorCount) {return XST_FAILURE;}}/** Wait until bus is idle to start another transfer.*/while (XIicPs_BusIsBusy(&IicInstance));/** Wait for a bit of time to allow the programming to complete*/usleep(200000);return XST_SUCCESS;
}/*****************************************************************************/
/**
* This function reads data from the IIC serial EEPROM into a specified buffer.
*
* @param   BufferPtr contains the address of the data buffer to be filled.
* @param   ByteCount contains the number of bytes in the buffer to be read.
*
* @return  XST_SUCCESS if successful else XST_FAILURE.
*
* @note        None.
*
******************************************************************************/
int EepromReadData(u8 *BufferPtr, u16 ByteCount)
{int Status;AddressType Address = EEPROM_START_ADDRESS;if (sizeof(Address) == 1) {WriteBuffer[0] = (u8) (Address);}else {WriteBuffer[0] = (u8) (Address >> 8);WriteBuffer[1] = (u8) (Address);}Status = EepromWriteData(sizeof(Address));if (Status != XST_SUCCESS) {return XST_FAILURE;}ReceiveComplete = FALSE;/** Receive the Data.*/XIicPs_MasterRecv(&IicInstance, BufferPtr,ByteCount, IIC_SLAVE_ADDR);while (ReceiveComplete == FALSE) {if (0 != TotalErrorCount) {return XST_FAILURE;}}/** Wait until bus is idle to start another transfer.*/while (XIicPs_BusIsBusy(&IicInstance));return XST_SUCCESS;
}/******************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the IIC.
*
* @param   IicPsPtr contains a pointer to the instance of the Iic
*       which is going to be connected to the interrupt controller.
*
* @return  XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note        None.
*
*******************************************************************************/
static int SetupInterruptSystem(XIicPs *IicPsPtr)
{int Status;XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */Xil_ExceptionInit();/** Initialize the interrupt controller driver so that it is ready to* use.*/IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);if (NULL == IntcConfig) {return XST_FAILURE;}Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig,IntcConfig->CpuBaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}/** Connect the interrupt controller interrupt handler to the hardware* interrupt handling logic in the processor.*/Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&InterruptController);/** Connect the device driver handler that will be called when an* interrupt for the device occurs, the handler defined above performs* the specific interrupt processing for the device.*/Status = XScuGic_Connect(&InterruptController, IIC_INTR_ID,(Xil_InterruptHandler)XIicPs_MasterInterruptHandler,(void *)IicPsPtr);if (Status != XST_SUCCESS) {return Status;}/** Enable the interrupt for the Iic device.*/XScuGic_Enable(&InterruptController, IIC_INTR_ID);/** Enable interrupts in the Processor.*/Xil_ExceptionEnable();return XST_SUCCESS;
}/*****************************************************************************/
/**
*
* This function is the handler which performs processing to handle data events
* from the IIC.  It is called from an interrupt context such that the amount
* of processing performed should be minimized.
*
* This handler provides an example of how to handle data for the IIC and
* is application specific.
*
* @param   CallBackRef contains a callback reference from the driver, in
*       this case it is the instance pointer for the IIC driver.
* @param   Event contains the specific kind of event that has occurred.
* @param   EventData contains the number of bytes sent or received for sent
*       and receive events.
*
* @return  None.
*
* @note        None.
*
*******************************************************************************/
void Handler(void *CallBackRef, u32 Event)
{/** All of the data transfer has been finished.*/if (0 != (Event & XIICPS_EVENT_COMPLETE_RECV)){ReceiveComplete = TRUE;} else if (0 != (Event & XIICPS_EVENT_COMPLETE_SEND)) {TransmitComplete = TRUE;} else if (0 == (Event & XIICPS_EVENT_SLAVE_RDY)){/** If it is other interrupt but not slave ready interrupt, it is* an error.* Data was received with an error.*/TotalErrorCount++;}
}
//
// Si5351A commands
//
///
void si5351_write(int reg_addr, int reg_value)
{int Status;WriteBuffer[0] = reg_addr;WriteBuffer[1] = reg_value;Status = EepromWriteData(2);
}// Set PLLs (VCOs) to internal clock rate of 900 MHz
// Equation fVCO = fXTAL * (a+b/c) (=> AN619 p. 3
void si5351_start(void)
{unsigned long a, b, c;unsigned long p1, p2;//, p3;// Init clock chip//si5351_write(XTAL_LOAD_CAP, 0xD2);      // Set crystal load capacitor to 10pF (default),// for bits 5:0 see also AN619 p. 60si5351_write(CLK_ENABLE_CONTROL, 0x00); // Enable all outputssi5351_write(CLK0_CONTROL, 0x0F);       // Set PLLA to CLK0, 8 mA outputsi5351_write(CLK1_CONTROL, 0x2F);       // Set PLLB to CLK1, 8 mA outputsi5351_write(CLK2_CONTROL, 0x2F);       // Set PLLB to CLK2, 8 mA outputsi5351_write(PLL_RESET, 0xA0);          // Reset PLLA and PLLB// Set VCOs of PLLA and PLLB to 650 MHza = PLLRATIO;     // Division factor 650/25 MHz !!!!b = 0;            // Numerator, sets b/c=0c = CFACTOR;      //Max. resolution, but irrelevant in this case (b=0)//Formula for splitting up the numbers to register data, see AN619p1 = 128 * a + (unsigned long) (128 * b / c) - 512;p2 = 128 * b - c * (unsigned long) (128 * b / c);//p3  = c;//Write data to registers PLLA and PLLB so that both VCOs are set to 900MHz intermal freqsi5351_write(SYNTH_PLL_A, 0xFF);si5351_write(SYNTH_PLL_A + 1, 0xFF);si5351_write(SYNTH_PLL_A + 2, (p1 & 0x00030000) >> 16);si5351_write(SYNTH_PLL_A + 3, (p1 & 0x0000FF00) >> 8);si5351_write(SYNTH_PLL_A + 4, (p1 & 0x000000FF));si5351_write(SYNTH_PLL_A + 5, 0xF0 | ((p2 & 0x000F0000) >> 16));si5351_write(SYNTH_PLL_A + 6, (p2 & 0x0000FF00) >> 8);si5351_write(SYNTH_PLL_A + 7, (p2 & 0x000000FF));si5351_write(SYNTH_PLL_B, 0xFF);si5351_write(SYNTH_PLL_B + 1, 0xFF);si5351_write(SYNTH_PLL_B + 2, (p1 & 0x00030000) >> 16);si5351_write(SYNTH_PLL_B + 3, (p1 & 0x0000FF00) >> 8);si5351_write(SYNTH_PLL_B + 4, (p1 & 0x000000FF));si5351_write(SYNTH_PLL_B + 5, 0xF0 | ((p2 & 0x000F0000) >> 16));si5351_write(SYNTH_PLL_B + 6, (p2 & 0x0000FF00) >> 8);si5351_write(SYNTH_PLL_B + 7, (p2 & 0x000000FF));}void si5351_set_freq(int synth, unsigned long f)
{unsigned long freq = f + INTERFREQUENCY; unsigned long  a, b, c = CFACTOR; unsigned long f_xtal = 25000000;double fdiv = (double) (f_xtal * PLLRATIO) / freq; //division factor fvco/freq (will be integer part of a+b/c)double rm; //remainderunsigned long p1, p2;a = (unsigned long) fdiv;rm = fdiv - a;  //(equiv. to fractional part b/c)b = rm * c;p1  = 128 * a + (unsigned long) (128 * b / c) - 512;p2 = 128 * b - c * (unsigned long) (128 * b / c);//Write data to multisynth registers of synth nsi5351_write(synth, 0xFF);      //1048575 MSBsi5351_write(synth + 1, 0xFF);  //1048575 LSBsi5351_write(synth + 2, (p1 & 0x00030000) >> 16);si5351_write(synth + 3, (p1 & 0x0000FF00) >> 8);si5351_write(synth + 4, (p1 & 0x000000FF));si5351_write(synth + 5, 0xF0 | ((p2 & 0x000F0000) >> 16));si5351_write(synth + 6, (p2 & 0x0000FF00) >> 8);si5351_write(synth + 7, (p2 & 0x000000FF));
}

ZYNQ控制SI5351例程相关推荐

  1. 基于MPC的移动机器人轨迹跟踪控制qpOASES例程

    参考了 一个模型预测控制(MPC)的简单实现 https://www.cnblogs.com/zhjblogs/p/13880682.html 与 基于MPC的移动机器人轨迹跟踪控制matlab例程 ...

  2. LabVIEW编程LabVIEW控制TC-XSM例程与相关资料

    LabVIEW编程LabVIEW控制TC-XSM例程与相关资料  TC-XSM是北京通磁伟业传感技术有限公司的产品.TC-XSM仪表:显示转速.线速.频率测控仪表.可配tcsensor转速传感器.振动 ...

  3. LabVIEW编程LabVIEW开发 控制NI9472例程与相关资料

    LabVIEW编程LabVIEW开发 控制NI9472例程与相关资料 NI 9472 是一款数字输出模块,用于 CompactDAQ 和 CompactRIO 系统.每个通道都可接受 6 V - 30 ...

  4. Dsp28335 - ePWM - 50Hz小舵机的控制 - 代码例程

    最近要做一点小东西,使用dsp28335控制舵机,使用pwm信号.在这里写点东西给需要使用pwm这个模块的新人吧. 工程模板代码我传在我的csdn的资源里了,有需要的可以下载. 28xx设置的sysc ...

  5. ZYNQ PL采集AD7606数据PS LWIP发送

    一,传输设计: 1,PS 通过 AXI GPIO IP核启动 PL 不间断循环构造64bit 位宽的 0-1023 的数据,通过 AXI DMA IP 核,PS的 Slave AXI GP 接口传输至 ...

  6. 使用webots的MPC的移动机器人轨迹跟踪控制

    上一篇文章中使用MPC对机器人的一个方向自由度进行了控制, 基于MPC的移动机器人轨迹跟踪控制qpOASES例程 现在使用速度与角速度对机器人进行平面运动控制. 所以机器人的控制量为U=[v ;w], ...

  7. 使用ESP8266通过Blinker平台接入天猫精灵控制电视/空调

    目录 `演示视频` 1.准备工作 1.1 `原理` 1.2 `使用的硬件以及硬件连接图` 1.3 `开发环境准备` 2.解码空调红外键值 2.1 `把ESP8266红外接收的实例,上传到NodeMCU ...

  8. 基于visual c++之windows核心编程代码分析(24)IO控制、内核通信

    我们在进行Windows编程的时候,经常需要进行IO控制与内核通信,我们来实现IO控制与内核通信.请见代码实现与注释讲解 驱动代码实现与分析 /* 头文件 */ #include <ntddk. ...

  9. DSP28035控制舵机

    1.舵机教程和参考例程 硬石舵机教程和参考例程(密码:o5zh) 2.使用到的舵机MG90S 使用的舵机MG90S 信号线(黄线)红线(电源线)棕色(地线) 舵机的控制一般需要一个20ms(50HZ) ...

最新文章

  1. nvGraph-NVIDIA图形库
  2. 虚拟机系统的磁盘扩容妙招及案例
  3. 收货地址 - 设置默认收货地址
  4. 通过通用数据访问扩展AWS生态系统
  5. python 三维曲线拟合_基于三维数据和参数的Scipy曲线拟合
  6. Hashtable Dictionary[必看]
  7. 中国土壤厚度空间分布数据
  8. 简单的idea非maven项目引入jar包
  9. 北航计算机专业报录比,北京航空航天大学考研报录比数据查询
  10. fprom预测结果内容_启动子分析预测数据库
  11. java 文件存在 覆盖_java – 如果文件存在于目录中,我该如何覆盖它
  12. windows安装php
  13. 智能快递柜的密码模块
  14. 用ccs创建一个工程文件
  15. 阻滞增长函数matlab拟合,matlab指数增长和阻滞增长拟合代码讲课稿
  16. 运放-环路控制系统-零点、极点、频宽、波特图、二阶、RC概念
  17. 计算机的u盘显示桌面,插入U盘后如何让U盘图标显示在Win7系统桌面上
  18. keras非线性回归代码专题
  19. (二)海思3519av100开发:开发板环境搭建
  20. maven的使用-很全

热门文章

  1. PROTEUS元件库元件称呼
  2. 国际化域名 idn linux,CLUB中文国际化域名(IDN)9月开放注册
  3. [心情]分手以后我要记得这10句话
  4. 编写测试用例-qq注册(账号)
  5. 【FMCW雷达人体行为识别——多普勒谱提取】
  6. python爬虫之通过xpath获取豆瓣最新上映电影的海报
  7. WordPress 如何阻止垃圾评论?
  8. 暑期总结——变是永远不变的
  9. 金属氧化物半导体场效应晶体管的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  10. MySQL的视图定义、规则与视图作用、创建视图和修改视图,以及视图的保存