找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 818|回复: 2
打印 上一主题 下一主题
收起左侧

ATMEGA8单片机+SI5351双通道高频信号发生器

  [复制链接]
跳转到指定楼层
楼主
ID:1136941 发表于 2025-1-13 15:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我是个无线电爱好者,平时喜欢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)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1136941 发表于 2025-1-13 16:14 | 只看该作者

回复

使用道具 举报

板凳
ID:1095428 发表于 2025-3-10 22:51 | 只看该作者
老师你好, DE BA7LNN, 谢谢,73!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表