stm32 si5351使用(软件模拟i2c和硬件i2c)

参考资料来源
csdn: Si5351A方波信号发生器发送任意频率程序.
github: SI5351时钟模块测试代码.

使用的单片机为STM32F030
i2c引脚为PB8(SCL),PB9(SDA)

需要记住的地方有:

  1. si5351设备地址:写地址0xC0,读地址为0xC1(手册的第四章可以看到)
  2. si5351的寄存器和输出频率的计算要看另一本手册
    下载: AN619.

在这里插入图片描述简单说一下写操作:

  • i2c启动
  • 发送设备地址+写信号
  • 等待答应
  • 发送要写的寄存器地址
  • 等待答应
  • 发送要写的数据
  • 等待答应
  • i2c停止

软件模拟i2c

先说下软件模拟的i2c,这个好测试,因为万一别人画的板引脚反了改一下就可以测试了(惨痛教训)。
i2c.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include "i2c.h"

// 初始化IIC的IO口
void I2C2_Soft_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;   // 定义GPIO结构体
   
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  // 打开GPIOB口时钟
   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;  // 输出
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // 开漏
    GPIO_InitStructure.GPIO_Pin = Pin_SCL | Pin_SDA ; // IIC对应IO口
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; // 50MHZ
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIO
   
    I2C2_Stop();
}
 
// 发送IIC起始信号
bool I2C2_Start(void)
{
    Pin_SCL_H; // 拉高时钟线
    Pin_SDA_H; // 拉高信号线
    I2C2_Delay1us();
    if(!Read_SDA_Pin)       return false;
    Pin_SDA_L;
    I2C2_Delay1us();
    Pin_SDA_L;
    I2C2_Delay1us();
    return true;
}
 
// 发送IIC停止信号
bool I2C2_Stop(void)
{
    Pin_SCL_H;
    Pin_SDA_L;
    I2C2_Delay1us();
    if(Read_SDA_Pin)    return false;
    Pin_SDA_H;
    I2C2_Delay1us();
    if(!Read_SDA_Pin) return false;
    Pin_SDA_H;
    I2C2_Delay1us();   
    return true;
}
 
// IIC发送ACK信号
void I2C2_Ack(void)
{
    Pin_SCL_L;
    I2C2_Delay1us();
    Pin_SDA_L; 
    Pin_SCL_H;
    I2C2_Delay1us();
    Pin_SCL_L;
    Pin_SDA_H;
    I2C2_Delay1us();
}
 
// IIC不发送ACK信号
void I2C2_NAck(void)
{
    Pin_SCL_L;
    I2C2_Delay1us();   
    Pin_SDA_H;
    Pin_SCL_H;
    I2C2_Delay1us();
    Pin_SCL_L;
    I2C2_Delay1us();
}
 
// IIC等待ACK信号
uint8_t I2C2_Wait_Ack(void)
{
    Pin_SCL_L;
    I2C2_Delay1us();   
    Pin_SDA_H;
    Pin_SCL_H;
    I2C2_Delay1us();   
    if(Read_SDA_Pin)
    {
    Pin_SCL_L;
    I2C2_Delay1us();
    return false;
    }
    Pin_SCL_L;
    I2C2_Delay1us();
    return true;
}
 
// IIC发送一个字节
void I2C2_Send_Byte(uint8_t txd)
{
    for(uint8_t i=0; i<8; i++)
    {
    Pin_SCL_L;
    I2C2_Delay1us();
    if(txd & 0x80)
        Pin_SDA_H;
    else
        Pin_SDA_L;
        txd <<= 1;
        Pin_SCL_H;
        I2C2_Delay1us();
    }
}
 
// IIC读取一个字节
uint8_t I2C2_Read_Byte(void)
{
    uint8_t rxd = 0;
    for(uint8_t i=0; i<8; i++)
    {
    rxd <<= 1;
    Pin_SCL_L;
    I2C2_Delay1us();
    Pin_SCL_H; 
    I2C2_Delay1us();       
    if(Read_SDA_Pin)
    {
        rxd |= 0x01;
    }
    }
    return rxd;
}
 
// 向从机指定地址写数据
bool I2C_Write_REG(uint8_t SlaveAddress, uint8_t REG_Address,uint8_t REG_data)
{
    if(!I2C2_Start())       return false;
    I2C2_Send_Byte(SlaveAddress);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_Address);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_data);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    if(!I2C2_Stop()) return false;
    return true;
}
 
// 从设备中读取数据
uint8_t I2C2_Read_REG(uint8_t SlaveAddress,uint8_t REG_Address)
{
    uint8_t data;
    if(!I2C2_Start())   return false;
    I2C2_Send_Byte(SlaveAddress);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_Address);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    if(!I2C2_Start())   return false;
    I2C2_Send_Byte(SlaveAddress + 1);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    data = I2C2_Read_Byte();
    I2C2_NAck();
    if(!I2C2_Stop())    return false;  
    return data;
}
 
// 连续写N个字节
bool I2C2_Write_NByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t* buf, uint8_t len)
{
    if(!I2C2_Start())return false;
    I2C2_Send_Byte(SlaveAddress);  //发送设备地址+写信号
    if(!I2C2_Wait_Ack()){I2C2_Stop(); return false;}
    I2C2_Send_Byte(REG_Address);  
    if(!I2C2_Wait_Ack()){I2C2_Stop(); return false;}
    for(uint16_t i=0; i<len; i++)
    {
        I2C2_Send_Byte(buf[i]);
    if(i<len-1)
    {
            if(!I2C2_Wait_Ack()){I2C2_Stop(); return false;}
    }
    }
    I2C2_Stop();
    return true;
}

bool I2C2_CheckDevice(uint8_t SlaveAddress)
{
    if(!I2C2_Start())   return false;
    I2C2_Send_Byte(SlaveAddress);
    if(!I2C2_Wait_Ack())
    {
    I2C2_Stop();
    return false;      
    }
    if(!I2C2_Stop())    return false;  
    return true;   
}


bool my_I2C_sendREG(uint8_t REG_Address,uint8_t REG_data)
{
    if(!I2C2_Start())       return false;
    I2C2_Send_Byte(0xC0);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_Address);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_data);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    if(!I2C2_Stop()) return false;
    return true;
}

uint8_t my_I2C2_Read_REG(uint8_t REG_Address)
{
    uint8_t data;
    if(!I2C2_Start())   return false;
    I2C2_Send_Byte(0xC0);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    I2C2_Send_Byte(REG_Address);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    if(!I2C2_Start())   return false;
    I2C2_Send_Byte(0xC1);
    if(!I2C2_Wait_Ack()) { I2C2_Stop(); return false;   }
    data = I2C2_Read_Byte();
    I2C2_NAck();
    if(!I2C2_Stop())    return false;  
    return data;
}

i2c.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef __I2C_H
#define __I2C_H

#include "stm32f0xx.h"

typedef unsigned  short int   uint;
typedef enum {false = 0, true = !false} bool;

#define I2C2_GPIOx  GPIOB
#define Pin_SCL     GPIO_Pin_8//8
#define Pin_SDA     GPIO_Pin_9//9
 
#define Pin_SCL_L       I2C2_GPIOx->ODR &= ~Pin_SCL
#define Pin_SCL_H       I2C2_GPIOx->ODR |= Pin_SCL
 
#define Pin_SDA_L       I2C2_GPIOx->ODR &= ~Pin_SDA
#define Pin_SDA_H       I2C2_GPIOx->ODR |= Pin_SDA
 
#define Read_SDA_Pin    I2C2_GPIOx->IDR & Pin_SDA


#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




static inline void I2C2_Delay1us(void)
{
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();   
}  
 
 

 
void I2C2_Soft_Init(void);         
bool I2C2_Start(void);                     
bool I2C2_Stop(void);                  
void I2C2_Send_Byte(uint8_t txd);
uint8_t I2C2_Read_Byte(void);
uint8_t I2C2_Wait_Ack(void);       
void I2C2_Ack(void);                           
void I2C2_NAck(void);                      
 
bool I2C2_Write_REG(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data);
uint8_t I2C2_Read_REG(uint8_t SlaveAddress,uint8_t REG_Address);
bool I2C2_Write_NByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t* buf, uint8_t len);
bool I2C2_Read_NByte(uint8_t SlaveAddress, uint8_t REG_Address, uint8_t* buf, uint8_t len);
//建议使用这个函数来测试是否有通信
bool I2C2_CheckDevice(uint8_t SlaveAddress);

//这里的代码和硬件i2c重复了,下面会给出
void si5351aSetFrequency(uint32_t frequency , uint8_t Chanal );
void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom);
void setupMultisynth(uint8_t synth,uint32_t divider,uint8_t rDiv);

#endif

硬件i2c

(因为是直接改eproom的所以只给出关键部分,不然太长了)
i2c.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStruct;
   
    /* Enable  GPIOA clock */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  
//  /* Configure the I2C clock source. The clock is derived from the HSI */
//   RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);      
  /*!< sEE_I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
 
  /*!< GPIO configuration */  
  /*!< Configure sEE_I2C pins: SCL */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
  GPIO_Init(GPIOB , &GPIO_InitStruct);
 
  /*!< Configure sEE_I2C pins: SDA */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
  GPIO_Init(GPIOB , &GPIO_InitStruct);
   
 /* Connect PXx to I2C_SCL*/
  GPIO_PinAFConfig( GPIOB , GPIO_PinSource8, GPIO_AF_1);
  /* Connect PXx to I2C_SDA*/
  GPIO_PinAFConfig( GPIOB ,GPIO_PinSource9, GPIO_AF_1);
 
}

/*******************************************************************************
* Function Name  : I2C_Configuration
* Description    : I2C Configuration
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void I2C_Configuration(void)
{
  I2C_InitTypeDef  I2C_InitStruct;
 
  /* I2C configuration */
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStruct.I2C_DigitalFilter = 0x00;
  I2C_InitStruct.I2C_OwnAddress1 =0x00;
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   
  I2C_InitStruct.I2C_Timing = 0x00210507;
  /* I2C Peripheral Enable */
  I2C_Cmd(I2C1, ENABLE);
  /* Apply I2C configuration after enabling it */
  I2C_Init(I2C1, &I2C_InitStruct);
 
}

/*******************************************************************************
* Function Name  : I2C_EE_Init
* Description    : Initializes peripherals used by the I2C EEPROM driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void I2C_EE_Init(void)
{
  /* GPIO configuration */
  GPIO_Configuration();

  /* I2C configuration */
  I2C_Configuration();
   
    /*!< Select the EEPROM address */
  sEEAddress = sEE_HW_ADDRESS;  //设备地址
}
/**
  * @brief  从I2C1的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
  * @param  start_Addr:起始字节地址
  * @param  write_Buffer:存放读取数据的数组指针
  * @retval 是否读取成功
  */
uint8_t I2C1_Write_NBytes(uint8_t start_Addr, uint8_t write_Buffer)
{
  uint8_t write_Num;
    uint32_t I2C_Timeout =2000;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return 1;
    }
  }

  I2C_TransferHandling(I2C1, 0xC0, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);

  I2C_Timeout = 2000;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return 1;
    }
  }

  I2C_SendData(I2C1, start_Addr);

  I2C_Timeout = 2000;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return 1;
    }
  }

  I2C_TransferHandling(I2C1, 0xC0, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);

    I2C_Timeout = 2000;
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET)
    {
      if((I2C_Timeout--) == 0)
      {
        return 1;
      }
    }

    I2C_SendData(I2C1, write_Buffer);

  I2C_Timeout = 2000;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return 1;
    }
  }

  return 0;
}

i2c.h

1
2
3
4
5
#define sEE_HW_ADDRESS      0xC0
#define sEE_I2C_TIMING          0x00210507
#define sEE_OK                    0
#define sEE_FAIL                  1  
#define sEE_I2C                          I2C1

使用si5351代码

这部分发送使用的是软件模拟的i2c,想使用硬件i2c请将my_I2C_sendREG替换为I2C1_Write_NBytes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom)
{
  uint32_t P1;                  // PLL config register P1
  uint32_t P2;                  // PLL config register P2
  uint32_t P3;                  // PLL config register P3

  P1 = (uint32_t)(128 * ((float)num / (float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num - denom * P2);
  P3 = denom;

  my_I2C_sendREG(pll + 0, (P3 & 0x0000FF00) >> 8);
  my_I2C_sendREG(pll + 1, (P3 & 0x000000FF));
  my_I2C_sendREG(pll + 2, (P1 & 0x00030000) >> 16);
  my_I2C_sendREG(pll + 3, (P1 & 0x0000FF00) >> 8);
  my_I2C_sendREG(pll + 4, (P1 & 0x000000FF));
  my_I2C_sendREG(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  my_I2C_sendREG(pll + 6, (P2 & 0x0000FF00) >> 8);
  my_I2C_sendREG(pll + 7, (P2 & 0x000000FF));
}


void setupMultisynth(uint8_t synth,uint32_t divider,uint8_t rDiv)
{
  uint32_t P1;                  // Synth config register P1
  uint32_t P2;                  // Synth config register P2
  uint32_t P3;                  // Synth config register P3

  P1 = 128 * divider - 512;
  P2 = 0;                           // P2 = 0, P3 = 1 forces an integer value for the divider
  P3 = 1;

  my_I2C_sendREG(synth + 0,   (P3 & 0x0000FF00) >> 8);
  my_I2C_sendREG(synth + 1,   (P3 & 0x000000FF));
  my_I2C_sendREG(synth + 2,   ((P1 & 0x00030000) >> 16) | rDiv);
  my_I2C_sendREG(synth + 3,   (P1 & 0x0000FF00) >> 8);
  my_I2C_sendREG(synth + 4,   (P1 & 0x000000FF));
  my_I2C_sendREG(synth + 5,   ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  my_I2C_sendREG(synth + 6,   (P2 & 0x0000FF00) >> 8);
  my_I2C_sendREG(synth + 7,   (P2 & 0x000000FF));
}


void si5351aSetFrequency(uint32_t frequency , uint8_t Chanal )
{
  uint32_t pllFreq;
  uint32_t xtalFreq = XTAL_FREQ;// Crystal frequency
  uint32_t l;
  float f;
  uint8_t mult;
  uint32_t num;
  uint32_t denom;
  uint32_t divider;

  divider = 900000000 / frequency;// Calculate the division ratio. 900,000,000 is the maximum internal
                                                                  // PLL frequency: 900MHz
  if (divider % 2) divider--;       // Ensure an even integer division ratio

  pllFreq = divider * frequency;    // Calculate the pllFrequency: the divider * desired output frequency

  mult = pllFreq / xtalFreq;        // Determine the multiplier to get to the required pllFrequency
  l = pllFreq % xtalFreq;           // It has three parts:
  f = l;                            // mult is an integer that must be in the range 15..90
  f *= 1048575;                 // num and denom are the fractional parts, the numerator and denominator
  f /= xtalFreq;                    // each is 20 bits (range 0..1048575)
  num = f;                      // the actual multiplier is  mult + num / denom
  denom = 1048575;              // For simplicity we set the denominator to the maximum 1048575
  // Set up PLL A with the calculated multiplication ratio
  setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
                                                                  // Set up MultiSynth divider 0, with the calculated divider.
                                                                  // The final R division stage can divide by a power of two, from 1..128.
                                                                  // reprented by constants SI_R_DIV1 to SI_R_DIV128 (see si5351a.h header file)
                                                                  // If you want to output frequencies below 1MHz, you have to use the
                                                                  // final R division stage
  if( Chanal == 0 ){
        setupMultisynth(SI_SYNTH_MS_0,divider,SI_R_DIV_1);
                                                                  // Reset the PLL. This causes a glitch in the output. For small changes to
                                                                  // the parameters, you don't need to reset the PLL, and there is no glitch
        my_I2C_sendREG(SI_PLL_RESET,0xA0); 
                                                                  // Finally switch on the CLK0 output (0x4F)
                                                                  // and set the MultiSynth0 input to be PLL A
        my_I2C_sendREG(SI_CLK0_CONTROL, 0x4F|SI_CLK_SRC_PLL_A);
    }
    else if ( Chanal == 1 ){
        setupMultisynth(SI_SYNTH_MS_1,divider,SI_R_DIV_1);
        my_I2C_sendREG(SI_PLL_RESET,0xA0); 
        my_I2C_sendREG(SI_CLK1_CONTROL, 0x4F|SI_CLK_SRC_PLL_A);
    }
        else if ( Chanal == 2 ){
        setupMultisynth(SI_SYNTH_MS_2,divider,SI_R_DIV_1);
        my_I2C_sendREG(SI_PLL_RESET,0xA0); 
        my_I2C_sendREG(SI_CLK2_CONTROL, 0x4F|SI_CLK_SRC_PLL_A);
        }
}

至于怎么使用
main.c(软件模拟i2c)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(void)
{
    uint8_t testAddr = 0;
    int Fre_1M = 15000000;
    int fre = 50;
    SystemInit();
    I2C2_Soft_Init();
   
    si5351aSetFrequency(1*Fre_1M , 0);//CLK0
//  si5351aSetFrequency(2*Fre_1M , 1);
//  si5351aSetFrequency(3*Fre_1M , 2);
   
    while(1)
    {

    }
}