我是个无线电爱好者,平时喜欢DIY高频电路,由于高端的信号发生器价格太高,就制作了这个装置。SI5351是3通道输出的方波PLL信号发生器,驱动是移植后略加修改的,原驱动是一个通道输出,水平所限不能实现3个通道输出。两个通道频率可以分别调节,频率范围500KHZ-120MHZ.以下是源程序:
/*************************
ATMEGA-8L单片机
内部RC时钟8MHZ
***********************************/
#include "mega16.h"
#include "i2c.h"
#include "delay.h"
#asm
.equ __i2c_port=0x12 //D端口地址0x12
.equ __sda_bit=6 //6脚
.equ __scl_bit=7 //7脚
#endasm
#define uchar unsigned char
#define uint unsigned int
#define uint8_t unsigned char
#define uint16_t unsigned int
#define uint32_t signed long int
/////////////////////////////////////
#define SI_CLK0_CONTROL 16
#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
#define SI_R_DIV_2 0x16
#define SI_R_DIV_4 0x20
#define SI_R_DIV_8 0x30
#define SI_R_DIV_16 0x40
#define SI_R_DIV_32 0x50
#define SI_R_DIV_64 0x60
#define SI_R_DIV_128 0x70
#define SI_CLK_SRC_PLL_A 0x00
#define SI_CLK_SRC_PLL_B 0x20
#define XTAL_FREQ 25000000 // 晶体频率
#define I2C_START 0x08
#define I2C_START_RPT 0x10
#define I2C_SLA_W_ACK 0x18
#define I2C_SLA_R_ACK 0x40
#define I2C_DATA_ACK 0x28
#define I2C_WRITE 0xc0
#define I2C_READ 0xc1
unsigned char Table[]="0123456789";
unsigned char Data[9];
/**********1602**************/
#define RS_1 PORTC.2=1
#define RS_0 PORTC.2=0
#define EN_1 PORTC.0=1
#define EN_0 PORTC.0=0
#define LCD_D4_1 PORTB.4=1
#define LCD_D4_0 PORTB.4=0
#define LCD_D5_1 PORTB.3=1
#define LCD_D5_0 PORTB.3=0
#define LCD_D6_1 PORTB.2=1
#define LCD_D6_0 PORTB.2=0
#define LCD_D7_1 PORTB.1=1
#define LCD_D7_0 PORTB.1=0
//////////函数声明//////////////////////////////////
void i2cSendRegister(uint8_t reg,uint8_t data);
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);
//void si5351aOutputOff(uint8_t clk);
void si5351aSetFrequency(uint8_t td,uint32_t frequency);
void LCD_en_write(void);//液晶使能
void LCD_by(uchar abc);//写字节
void LCD_set_xy(uchar x, uchar y);//写地址
void LCD_write_str(uchar X,uchar Y,uchar *s);//写字符串
void LCD_init(void);//液晶初始化
void delay_nus(uint n);
void del_ms(uint n);
void delay_us(unsigned int n);
void process_8(unsigned long i,unsigned char *p);
void display_8(unsigned char x, unsigned char y, unsigned char *p);
/*8位数预处理函数*/
void process_8(unsigned long i,unsigned char *p)
{
p[0]=i/100000000%10;
p[1]=i/10000000%10;
p[2]=i/1000000%10;
p[3]=i/100000%10;
p[4]=i/10000%10;
p[5]=i/1000%10;
p[6]=i/100%10;
p[7]=i/10%10;
p[8]=i%10;
}
/*8位数显示函数*/
void display_8(unsigned char x, unsigned char y, unsigned char *p)
{
unsigned char i;
LCD_set_xy( x, y );
RS_1; //RS=1,写显示内容
for(i=0;i<9;i++)//8
{
if(i==3)
{
LCD_write_str(3,0,".");
}
if(i==6)
{
LCD_write_str(7,0,".");
}
LCD_by(Table[p[ i]]);
}
}
void LCD_en_write(void)
{
delay_us(5);
EN_1;
delay_us(5);
EN_0;
}
//---------------------------------------
void LCD_by(uchar abc)//写字节
{
delay_nus(500);//500
if(((abc<<0)&0x80)==0)
LCD_D7_0;
else LCD_D7_1;
if(((abc<<1)&0x80)==0)
LCD_D6_0;
else LCD_D6_1;
if(((abc<<2)&0x80)==0)
LCD_D5_0;
else LCD_D5_1;
if(((abc<<3)&0x80)==0)
LCD_D4_0;
else LCD_D4_1;
LCD_en_write();
if(((abc<<4)&0x80)==0)
LCD_D7_0;
else LCD_D7_1;
if(((abc<<5)&0x80)==0)
LCD_D6_0;
else LCD_D6_1;
if(((abc<<6)&0x80)==0)
LCD_D5_0;
else LCD_D5_1;
if(((abc<<7)&0x80)==0)
LCD_D4_0;
else LCD_D4_1;
LCD_en_write();
}
//----------------------------------------------
void LCD_set_xy( uchar x, uchar y )//写地址函数
{
uchar address;
if (y == 0) address = 0x80 + x;
else
address = 0xc0 + x;
RS_0; //RS=0,写命令
LCD_by(address);
}
//---------------------------------------------
void LCD_write_str(uchar X,uchar Y,uchar *s)//写字符串
{
LCD_set_xy(X,Y);
RS_1;
while(*s)
{
LCD_by(*s);
s++;
}
}
//------------------------------------
void LCD_init(void) //液晶初始化
{
RS_0; //写命令
del_ms(500);
LCD_by(0x30);
del_ms(60);
LCD_by(0x30);
del_ms(10);
LCD_by(0x30);
del_ms(10);
LCD_by(0x02);
del_ms(10);
LCD_by(0x28); //4bit test显示模式设置(不检测忙信号)
del_ms(10);
LCD_by(0x08); // 显示关闭
del_ms(10);
LCD_by(0x01); // 显示清屏
del_ms(10);
LCD_by(0x06); // 显示光标移动
del_ms(10);
LCD_by(0x0C); // 显示开及光标设置
del_ms(100);
}
//----------------------------------------------
void delay_nus(uint n) //N us延时函数
{
uint i=0;
for (i=0;i<n;i++){;}
}
//--------------------------------------
void del_ms(uint n)//ms延时函数
{ uchar j;
while(n--)
{for(j=0;j<125;j++);}
}
//-----------------------------
void delay_us(unsigned int n)
{
if(n==0)
return ;
while (--n);
}
//---------Si5351----------------
void i2cSendRegister(uint8_t reg,uint8_t data)
{
i2c_start();//启动
i2c_write(0xc0);//5351地址I2C_WRITE 0b11000000
i2c_write(reg);//存储地址
i2c_write(data);//一字节数据
i2c_stop();//停止
delay_ms(2);
}
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;
i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
i2cSendRegister(pll + 1, (P3 & 0x000000FF));
i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
i2cSendRegister(pll + 4, (P1 & 0x000000FF));
i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
i2cSendRegister(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;
P3 = 1;
i2cSendRegister(synth + 0, (P3 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 1, (P3 & 0x000000FF));
i2cSendRegister(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
i2cSendRegister(synth + 3, (P1 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 4, (P1 & 0x000000FF));
i2cSendRegister(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
i2cSendRegister(synth + 6, (P2 & 0x0000FF00) >> 8);
i2cSendRegister(synth + 7, (P2 & 0x000000FF));
}
/* void si5351aOutputOff(uint8_t clk)
{
i2cSendRegister(clk, 0x80);
} */
void si5351aSetFrequency(uint8_t td,uint32_t frequency)
{
uint32_t pllFreq;
uint32_t xtalFreq = XTAL_FREQ;
uint32_t l;
float f;
uint8_t mult;
uint32_t num;
uint32_t denom;
uint32_t divider;
uint8_t x;
uint8_t y;
uint8_t z;
if(td==1)//1通道
{
x=SI_SYNTH_MS_1;
y=SI_CLK1_CONTROL;
z=SI_CLK_SRC_PLL_B;
}
if(td==2)//2通道
{
x=SI_SYNTH_MS_2;
y=SI_CLK2_CONTROL;
z=SI_CLK_SRC_PLL_A;
}
divider = 900000000 / frequency;
if (divider % 2) divider--;
pllFreq = divider * frequency;
mult = pllFreq / xtalFreq;
l = pllFreq % xtalFreq;
f = l;
f *= 1048575;
f /= xtalFreq;
num = f;
denom = 1048575;
if(td==1)//1通道
{
setupPLL(SI_SYNTH_PLL_B, mult, num, denom);
}
if(td==2)//2通道
{
setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
}
setupMultisynth(x, divider, SI_R_DIV_1);
i2cSendRegister(SI_PLL_RESET, 0xA0);
i2cSendRegister(y, 0x4F | z);
}
void main(void)
{
signed long int bj_1=500000;
signed long int bj_2=500000;
uchar IC=1;
uchar ID=1;
bit ww=1;
bit ee=1;
DDRB=0XFF;
PORTB=0X00;
DDRC=0XFF;
PORTC=0X00;
DDRD=0XC0;
PORTD=0XFF;
del_ms(100);
i2c_init();
del_ms(100);
LCD_init();
del_ms(100);
LCD_write_str(13,0,"MHz");
LCD_write_str(0,1,"Bj=");
del_ms(100);
while(1)
{
if(ee==1)
{
si5351aSetFrequency(1,bj_1);
si5351aSetFrequency(2,bj_2);
ee=0;
}
if(PIND.2==0)//频率加
{
del_ms(2);
if(PIND.2==0)
{
while(!PIND.2);
if(ID==1)
{
if(IC==1){bj_1=bj_1+10;}
if(IC==2){bj_1=bj_1+100;}
if(IC==3){bj_1=bj_1+1000;}
if(IC==4){bj_1=bj_1+10000;}
if(IC==5){bj_1=bj_1+100000;}
if(IC==6){bj_1=bj_1+1000000;}
if(IC==7){bj_1=bj_1+10000000;}
if(bj_1>120000000)
{
bj_1=120000000;
}
process_8(bj_1,Data);
display_8(0,0,Data);
}
if(ID==2)
{
if(IC==1){bj_2=bj_2+10;}
if(IC==2){bj_2=bj_2+100;}
if(IC==3){bj_2=bj_2+1000;}
if(IC==4){bj_2=bj_2+10000;}
if(IC==5){bj_2=bj_2+100000;}
if(IC==6){bj_2=bj_2+1000000;}
if(IC==7){bj_2=bj_2+10000000;}
if(bj_2>120000000)
{
bj_2=120000000;
}
process_8(bj_2,Data);
display_8(0,0,Data);
}
ww=1;
}
}
if(PIND.3==0)//频率减
{
del_ms(2);
if(PIND.3==0)
{
while(!PIND.3);
if(ID==1)
{
if(IC==1){bj_1=bj_1-10;}
if(IC==2){bj_1=bj_1-100;}
if(IC==3){bj_1=bj_1-1000;}
if(IC==4){bj_1=bj_1-10000;}
if(IC==5){bj_1=bj_1-100000;}
if(IC==6){bj_1=bj_1-1000000;}
if(IC==7){bj_1=bj_1-10000000;}
if(bj_1<500000)
{
bj_1=500000;
}
process_8(bj_1,Data);
display_8(0,0,Data);
}
if(ID==2)
{
if(IC==1){bj_2=bj_2-10;}
if(IC==2){bj_2=bj_2-100;}
if(IC==3){bj_2=bj_2-1000;}
if(IC==4){bj_2=bj_2-10000;}
if(IC==5){bj_2=bj_2-100000;}
if(IC==6){bj_2=bj_2-1000000;}
if(IC==7){bj_2=bj_2-10000000;}
if(bj_2<500000)
{
bj_2=500000;
}
process_8(bj_2,Data);
display_8(0,0,Data);
}
ww=1;
}
}
if(PIND.4==0)//通道按下
{
del_ms(20);
if(Td==0)
{
while(!Td);
ID++;
if(ID>2)
{
ID=1;
}
ww=1;
}
}
switch(ID)
{
case 1:
if(ww==1)
{
si5351aSetFrequency(1,bj_1);
LCD_write_str(14,1,"1");
process_8(bj_1,Data);
display_8(0,0,Data);
ww=0;
}
break;
case 2:
if(ww==1)
{
si5351aSetFrequency(2,bj_2);
LCD_write_str(14,1,"2");
process_8(bj_2,Data);
display_8(0,0,Data);
ww=0;
}
break;
}
if(PIND.0==0)//步进按下
{
del_ms(20);
if(PIND.0==0)
{
while(!PIND.0);
IC++;
if(IC>7)
{
IC=1;
}
ww=1;
}
}
switch(IC)
{
case 1://10HZ
LCD_write_str(3,1,"10Hz ");//
break;
case 2://100HZ
LCD_write_str(3,1,"100Hz ");//
break;
case 3://1KHZ
LCD_write_str(3,1,"1KHz ");//
break;
case 4://10KHZ
LCD_write_str(3,1,"10KHz ");//
break;
case 5://100KHZ
LCD_write_str(3,1,"100KHz");//
break;
case 6://1MHZ
LCD_write_str(3,1,"1MHz ");//
break;
case 7://10MHZ
LCD_write_str(3,1,"10MHz ");//
break;
}
}
}
SI5351信号发生器.pdf
(211.42 KB, 下载次数: 0)
|