打印

请问一个关于用单片机做DDS信号源的问题

[复制链接]
926|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
先写了第一个程序如下,很简单,输出频率能达到500HZ左右,如图。
#include<iom16v.h>  
#include<macros.h>   
#define uchar unsigned char       
#define uint unsigned int
unsigned char k=0,c=1;
unsigned char i;
#pragma data:code
flash unsigned char juchi[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
#pragma data:data
int f=0;//示波器上请改变此频率
//sbit      cs =     Pc^3;      
//sbit     clk =     Pc^4;      
//sbit     din =     Pc^5;   

void DA_Conver(unsigned char DAValue)
{   
       PORTC&=0B11110111;//cs=0
       PORTC&=0B11101111;//clk=0;

                                                                 
      for(i = 0; i < 8; i++)         
      {                                 
          if(DAValue&0B10000000) {PORTC |= 0B00100000;}
          else {PORTC&=0B11011111;}
          PORTC|=0B00010000;//clk = 1;                  
          DAValue <<= 1;                  
          PORTC&=0B11101111; //clk = 0;
      }
             //9位数据为0
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;
          //10位数据为0
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;   
          //第一个填充字节
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;
          //第二个填充字节
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;

      PORTC|=0B00001000;//cs = 1;
}

void delaynus(unsigned int n)
{
if (n == 0)
return ;  
  while (--n);
}


void main(void)            //主函数
{

  unsigned char i,j;
  DDRC=0xff;
  PORTC=0xff;
  f=0;       
               
               
                while(1)
                {
                DA_Conver(juchi[k]);
                delaynus(f);
                k++;
                if(k==147) k=0;
                }
}



后来加上了一些1602液晶显示和按键选择波形频率,然后最高频率就降到260了,这是为什么呀?DDS的程序几乎完全不变

#include<iom16v.h>     //包含单片机寄存器的头文件
#include<macros.h>   //包含_nop_()函数定义的头文件
#define uchar unsigned char       
#define uint unsigned int
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
#define RS_0 PORTC&=~(1<<PC0)
#define RS_1 PORTC|=(1<<PC0)


#define RW_0 PORTC&=~(1<<PC1)
#define RW_1 PORTC|=(1<<PC1)


#define E_0 PORTC&=~(1<<PC2)
#define E_1 PORTC|=(1<<PC2)
#pragma data:code //数据较多,存入flash
flash unsigned char juchi[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi2[147]={
219,254,158,0,54,144,221,254,167,1,41,123,201,249,235,72,2,52,124,190,239,254,207,60,0,25,72,121,166,204,233,250,254,244,218,173,117,67,34,17,9,5,4,6,10,20,39,75,128,182,224,247,254,248,228,197,158,112,62,17,1,91,224,254,231,178,110,40,0,115,246,243,187,106,27,10,202,254,208,126,38,5,197,253,206,120,32,11,210,252,200,115,30,9,200,254,213,139,58,1,82,237,250,209,145,77,19,4,120,232,254,237,203,161,115,74,38,11,0,10,51,112,165,199,219,230,236,238,238,235,228,215,192,154,96,37,5,1,17,47,84,127,172,213,244,254,215};
flash unsigned char juchi8[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi3[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi4[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi5[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi6[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};
flash unsigned char juchi7[147]={
9,38,76,116,154,188,223,247,254,234,164,50,1,9,38,76,116,154,187,217,239,252,254,240,205,145,68,19,1,1,10,22,35,49,61,73,83,90,97,101,104,104,103,99,94,87,78,68,56,43,29,16,5,0,6,36,102,175,224,248,254,247,230,204,172,136,97,58,23,1,13,101,204,247,253,237,208,170,126,83,41,8,2,60,175,237,254,248,227,197,162,125,89,54,25,4,1,26,91,166,215,240,252,254,252,246,240,232,224,216,209,204,200,198,197,198,200,204,209,216,223,231,239,246,252,254,252,241,217,170,97,29,1,4,23,52,87,123,160,195,224,246,254,239,181,66,3
};

#pragma data:data //跳出flash
unsigned char const string[ ]= {"Signal?    \0"};
unsigned char const string1[ ]={"Press K1 or K2\0"};
unsigned char const string2[ ]= {"Freq? press  \0"};
unsigned char const string3[ ]={"K3-K8: 1hz-1khz \0"};
unsigned char const string4[ ]={"Enjoy it ! "};
uchar a=0,b=0;
long int f=0,zhouqi=0,k=0,i=0;

//sbit      cs =     Pc^3;      
//sbit     clk =     Pc^4;      
//sbit     din =     Pc^5;      

void DA_Conver(unsigned char DAValue)
{   
       PORTC&=0B11110111;//cs=0
       PORTC&=0B11101111;//clk=0;

                                                                 
      for(i = 0; i < 8; i++)         
      {                                 
          if(DAValue&0B10000000) {PORTC |= 0B00100000;}
          else {PORTC&=0B11011111;}
          PORTC|=0B00010000;//clk = 1;                  
          DAValue <<= 1;                  
          PORTC&=0B11101111; //clk = 0;
      }
             //9位数据为0
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;
          //10位数据为0
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;   
          //第一个填充字节
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;
          //第二个填充字节
          PORTC|=0B00010000;//clk = 1;                                    
      PORTC&=0B11101111; //clk = 0;

      PORTC|=0B00001000;//cs = 1;
}

/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(unsigned int n)
{
if (n == 0)
return ;  
  while (--n);
}

/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(uint xms)
{
          int i,j;
  for(i=0;i<xms;i++)
        { for(j=0;j<1140;j++) ; }
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void Write_com (unsigned char dictate)
{   
   DDRA=0xff;

         RS_0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
         RW_0;   
         E_0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
                           // 就是让E从0到1发生正跳变,所以应先置"0"
         delaynus(50);              //空操作两个机器周期,给硬件反应时间
        PORTA=dictate;            //将数据送入P0口,即写入指令或地址
         delaynus(40);           //空操作四个机器周期,给硬件反应时间       
         E_1;                   //E置高电平
        delaynus(40);
             
          E_0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
     Write_com(x|0x80); //显示位置的确定方法规定为"80H+地址码x"       
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
   DDRA=0xff;
          RS_1;           //RS为高电平,RW为低电平时,可以写入数据
          RW_0;
          E_0;            //E置低电平(根据表8-6,写指令时,E为高脉冲,
                     // 就是让E从0到1发生正跳变,所以应先置"0"
          PORTA=y;           //将数据送入P0口,即将数据写入液晶模块
         delaynus(40); //空操作四个机器周期,给硬件反应时间
          E_1;           //E置高电平
        delaynus(40);    //空操作四个机器周期,给硬件反应时间
         E_0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInt(void)
{
           delay(15);             //延时15ms,首次写指令时应给LCD一段较长的反应时间
           Write_com(0x38);  //显示模式设置:16×2显示,5×7点阵,8位数据接口
        delay(5);   //延时5ms 
        Write_com(0x38);
        delay(5);
        Write_com(0x38); //3次写 设置模式
        delay(5);
        Write_com(0x0C);  //显示模式设置:显示开,有光标,光标闪烁
        delay(5);
        Write_com(0x06);  //显示模式设置:光标右移,字符不移
        delay(5);                                                                                          
        Write_com(0x01);  //清屏幕指令,将以前的显示内容清除
        delay(5);
}
void main(void)            //主函数
{
  unsigned char i,j;
  PORTA=0xff;//A口全部置为输出,用来控制LED1602
  DDRA=0xff;

  PORTC=0xff;//C口全部置为输出,1-3脚用来控制LED1602,4-6控制5615
  DDRC=0xff;

  PINB=0xff;//B口全部设为输入,用来按键选择波形和频率
  DDRB=0x00;

  PIND=0xff;//D口全部设为输入,用来按键选择波形和频率
  DDRD=0x00;

  LcdInt();         //调用LCD初始化函数  
  delay(10);
                 
                                Write_com(0x01);//清显示:清屏幕指令
                                         delay(5);
                                         WriteAddress(0x00);  // 设置显示位置为第一行的第1个字
                                        delay(5);
                                       i = 0;
                while(string != '\0')    //'\0'是数组结束标志
                        {                                               
                                        WriteData(string);
                                        i++;
                                        delay(100);
                        }

                         WriteAddress(0x40);  // 设置显示位置为第二行的第1个字
                       i = 0;
                while(string1 != '\0')   //'\0'是数组结束标志
                        {                               
                                        WriteData(string1);
                                        i++;
                                        delay(100);
                        }  
                        while(1){
                if (~PIND&0B00000100){a=1;break;}
                if (~PIND&0B00001000){b=1;break;}
               
                }
                                    Write_com(0x01);//清显示:清屏幕指令
                                         delay(5);
                                         WriteAddress(0x00);  // 设置显示位置为第一行的第1个字
                                        delay(5);
                                       i = 0;
                while(string2 != '\0')    //'\0'是数组结束标志
                        {                                               
                                        WriteData(string2);
                                        i++;
                                        delay(100);
                        }

                         WriteAddress(0x40);  // 设置显示位置为第二行的第1个字
                       i = 0;
                while(string3 != '\0')   //'\0'是数组结束标志
                        {                                               
                                        WriteData(string3);
                                        i++;
                                        delay(100);
                        }  
                while(1){
                if (~PIND&0B00010000){f=1000;break;}
                if (~PIND&0B00100000){f=500;break;}
                if (~PINB&0B00010000){f=200;break;}
                if (~PINB&0B00100000){f=50;break;}
                if (~PINB&0B01000000){f=20;break;}
                if (~PINB&0B10000000){f=0;break;}
                }
               
                                        Write_com(0x01);//清显示:清屏幕指令
                                         delay(5);
                                         WriteAddress(0x00);  // 设置显示位置为第一行的第1个字
                                        delay(5);
                                       i = 0;
                while(string4 != '\0')    //'\0'是数组结束标志
                        {                                               
                                        WriteData(string4);
                                        i++;
                                        delay(100);
                        }
               
               
               
                if (a){
                while(1)//如果选择波形1
                {
                DA_Conver(juchi[k]);
                k++;
                if(k==147) k=0;
                delaynus(f);
                }
                }
               
                else {
                while(1)//如果选择波形2
                {
                DA_Conver(juchi2[k]);
                k++;
                if(k==147) k=0;
                delaynus(f);
                }
                }
}



请问这是为什么啊??该怎么解决呢。。。谢谢大家!


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

59

帖子

0

粉丝