找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2143|回复: 0
收起左侧

单片机怎么调节AD9850产生10MHZ方波信号?(目前程序显示成矩形波)

[复制链接]
ID:531083 发表于 2019-5-10 16:54 | 显示全部楼层 |阅读模式
程序运行正确,电路可以显示正常的正弦波,方波的占空比设置不对,显示成了矩形波的样子,频率也只在50KHZ-3MHZ之间有波形,高了低了都会失真
希望哪位大神可以帮忙看着是哪里出了问题,虚心请教

单片机源程序如下:
  1. #include"reg51.h"
  2. #include <intrins.h>                                 //编译预处理命令
  3. #define LCD_GO_HOME               0x02         //AC=0,光标、画面回HOME位
  4. //输入方式设置
  5. #define LCD_AC_AUTO_INCREMENT     0x06         //数据读、写操作后,AC自动增一
  6. #define LCD_AC_AUTO_DECREASE      0x04         //数据读、写操作后,AC自动减一
  7. #define LCD_MOVE_ENABLE           0x05         //数据读、写操作,画面平移
  8. #define LCD_MOVE_DISENABLE        0x04         //数据读、写操作,画面不动
  9. //设置显示、光标及闪烁开、关
  10. #define LCD_DISPLAY_ON            0x0C         //显示开
  11. #define LCD_DISPLAY_OFF           0x08         //显示关
  12. #define LCD_CURSOR_ON             0x0A         //光标显示
  13. #define LCD_CURSOR_OFF            0x08         //光标不显示
  14. #define LCD_CURSOR_BLINK_ON       0x09         //光标闪烁
  15. #define LCD_CURSOR_BLINK_OFF      0x08         //光标不闪烁
  16. //光标、画面移动,不影响DDRAM
  17. #define LCD_LEFT_MOVE             0x18         //LCD显示左移一位
  18. #define LCD_RIGHT_MOVE            0x1C         //LCD显示右移一位
  19. #define LCD_CURSOR_LEFT_MOVE      0x10         //光标左移一位
  20. #define LCD_CURSOR_RIGHT_MOVE     0x14         //光标右移一位
  21. //工作方式设置
  22. #define LCD_DISPLAY_DOUBLE_LINE   0x38         //两行显示
  23. #define LCD_DISPLAY_SINGLE_LINE   0x30         //单行显示
  24. void LCD_cls(void);
  25. void LCD_write_data(unsigned char);
  26. void LCD_initial(void);
  27. void LCD_set_position(unsigned char);
  28. void LCD_prints(unsigned char *);
  29. void LCD_printc(unsigned char);
  30. #define LCD_DATA P0      //LCD的数据口
  31. sbit LCD_BUSY=LCD_DATA^7;  //LCD忙信号位
  32. sbit LCD_RS=P2^5;          //LCD寄存器选择
  33. sbit LCD_RW=P2^6;          //LCD读写控制
  34. sbit LCD_EN=P2^7;          //LCD使能信号*/
  35. extern void          _nop_     (void);
  36. unsigned char s;                  //无符号
  37. char code tab[4][4]={                {'1','2','3','A'},
  38.                                           {'4','5','6','B'},
  39.                                           {'7','8','9','C'},
  40.                                           {'*','0','#','D'}};       //0到F的16个键植
  41. ////////////////////////////////////////////////////////////////////
  42. //---------------------------------------------------//
  43. //                   程序                            //
  44. //---------------------------------------------------//




  45. sbit ad9850_w_clk    =P1^2;  //P2.2口接ad9850的w_clk脚/PIN7
  46. sbit ad9850_fq_up    =P1^1;  //P2.1口接ad9850的fq_up脚/PIN8
  47. sbit ad9850_rest     =P1^0;  //P2.0口接ad9850的rest脚/PIN12
  48. sbit ad9850_bit_data =P1^3;  //P1.7口接ad9850的D7脚/PIN25

  49. //***************************************************//
  50. //              ad9850复位(串行模式)                 //
  51. //---------------------------------------------------//
  52. void ad9850_reset_serial()
  53. {
  54. ad9850_w_clk=0;
  55. ad9850_fq_up=0;
  56. //rest信号
  57. ad9850_rest=0;
  58. ad9850_rest=1;
  59. ad9850_rest=0;
  60. //w_clk信号
  61. ad9850_w_clk=0;
  62. ad9850_w_clk=1;
  63. ad9850_w_clk=0;
  64. //fq_up信号
  65. ad9850_fq_up=0;
  66. ad9850_fq_up=1;
  67. ad9850_fq_up=0;
  68. }

  69. //***************************************************//
  70. //          向ad9850中写命令与数据(串行)             //
  71. //---------------------------------------------------//
  72. void ad9850_wr_serial(unsigned char w0,double frequence)
  73. {
  74. unsigned char i,w;
  75. long int y;
  76. double x;
  77. //计算频率的HEX值
  78. x=4294967295/125;//适合125M晶振
  79. //如果时钟频率不为180MHZ,修改该处的频率值,单位MHz  !!!
  80. frequence=frequence/1000000;
  81. frequence=frequence*x;
  82. y=frequence;
  83. //写w2数据
  84. w=(y>>8);
  85. for(i=0;i<8;i++)
  86. {
  87. ad9850_bit_data=(w>>i)&0x01;
  88. ad9850_w_clk=1;
  89. ad9850_w_clk=0;
  90. }
  91. //写w1数据
  92. w=(y>>24);
  93. for(i=0;i<8;i++)
  94. {
  95. ad9850_bit_data=(w>>i)&0x01;
  96. ad9850_w_clk=1;
  97. ad9850_w_clk=0;
  98. }
  99. //写w0数据
  100. w=w0;   
  101. for(i=0;i<8;i++)
  102. {
  103. ad9850_bit_data=(w>>i)&0x01;
  104. }
  105. }
  106. //////////////////////////////////////////////////////////////////////
  107. void LCD_check_busy(void)   //检测LCD状态,看它是不是还在忙呢
  108. {
  109. while(1)
  110.   {
  111.    LCD_EN=0;
  112.    LCD_RS=0;
  113.    LCD_RW=1;
  114.    LCD_DATA=0xff;
  115.    LCD_EN=1;
  116.    if(!LCD_BUSY)break;
  117.   }
  118. LCD_EN=0;
  119. }

  120. void LCD_cls(void)          //LCD清屏
  121. {

  122. LCD_check_busy();
  123. LCD_RS=0;
  124. LCD_RW=0;
  125. LCD_DATA=1;
  126. LCD_EN=1;
  127. LCD_EN=0;

  128. }

  129. void LCD_write_instruction(unsigned char LCD_instruction)   //写指令到LCD
  130. {
  131.   LCD_check_busy();
  132. LCD_RS=0;
  133. LCD_RW=0;

  134. LCD_DATA=LCD_instruction;
  135. LCD_EN=1;
  136. LCD_EN=0;
  137. }

  138. void LCD_write_data(unsigned char LCD_data)      //输出一个字节数据到LCD
  139. {
  140.   LCD_check_busy();
  141. LCD_RS=1;
  142. LCD_RW=0;

  143. LCD_DATA=LCD_data;
  144. LCD_EN=1;
  145. LCD_EN=0;
  146. }

  147. void LCD_set_position(unsigned char x)            //LCD光标定位到x处
  148. {
  149. LCD_write_instruction(0x80+x);
  150. }

  151. /*
  152. void LCD_go_home(void)                         //LCD光标归位
  153. {
  154. LCD_write_instruction(LCD_GO_HOME);
  155. }
  156. */

  157. void LCD_printc(unsigned char lcd_data)          //输出一个字符到LCD
  158. {
  159. LCD_write_data(lcd_data);
  160. }

  161. void LCD_prints(unsigned char *lcd_string)       //输出一个字符串到LCD
  162. {
  163. unsigned char i=0;
  164. while(lcd_string[i]!=0x00)
  165.   {
  166.    LCD_write_data(lcd_string[i]);
  167.    i++;
  168.   }
  169. }

  170. void LCD_initial(void)                        //初始化LCD
  171. {
  172. LCD_write_instruction(LCD_AC_AUTO_INCREMENT|LCD_MOVE_DISENABLE);
  173. LCD_write_instruction(LCD_DISPLAY_ON|LCD_CURSOR_OFF);
  174. LCD_write_instruction(LCD_DISPLAY_DOUBLE_LINE);
  175. LCD_cls();
  176. }
  177. void delay(unsigned char a)
  178.         {
  179.         unsigned char i;
  180.         while(a--)
  181.                 for(i=100;i>0;i--)
  182.                         ;
  183.         }

  184. char kbscan()          //键盘扫描
  185.         {
  186.          unsigned char hang,lie,key;
  187.         if(P3!=0x0f)
  188.         delay(5);
  189.         if(P3!=0x0f)
  190.                 {
  191.         
  192.                 switch(P3&0x0f)
  193.                                 {
  194.                                 case 0x0e:hang=3;break;
  195.                                 case 0x0d:hang=2;break;
  196.                                 case 0x0b:hang=1;break;
  197.                                 case 0x07:hang=0;break;
  198.                                 }
  199.                 P3=0xf0;
  200.                 P3=0xf0;
  201.                 switch(P3&0xf0)
  202.                                 {
  203.                                 case 0xe0:lie=0;break;
  204.                                 case 0xd0:lie=1;break;
  205.                                 case 0xb0:lie=2;break;
  206.                                 case 0x70:lie=3;break;
  207.                                 }
  208.                 P3=0x0f;
  209.                 while(P3!=0x0f);
  210.                 key=tab[hang][lie];
  211.                 }
  212.         else
  213.                 key=0;
  214.         return (key);
  215.         }

  216. void main()
  217.         {
  218.         unsigned char temp[10];
  219.         unsigned int shuzi[10];
  220.         long int f=10000;
  221.      s=0;
  222.         LCD_initial();
  223.         LCD_prints("SET Frequence:");
  224.         LCD_set_position(0x4E);
  225.         LCD_printc('H');
  226.         LCD_set_position(0x4f);
  227.         LCD_printc('z');
  228.          //LCD_cls();
  229.         P3=0x0f;
  230.         P0=0xff;
  231. //---------------------------------------------------//

  232. ad9850_reset_serial();
  233. //ad9850_wr_serial(0x00,2500);//串行写2500Hz程序
  234. //---------------------------------------------------//         
  235.         while(1)
  236.                 {
  237.                   
  238.                ad9850_wr_serial(0x00,f);
  239.                 temp[s]=kbscan();
  240.                 shuzi[s]=temp[s]-48;
  241.                           

  242. if(s==1)
  243. {
  244.   f=shuzi[0];
  245.   }
  246. if(s==2)
  247. {
  248.   f=shuzi[1]+10*shuzi[0];
  249.   }
  250. if(s==3)
  251. {
  252.   f=shuzi[2]+10*shuzi[1]+100*shuzi[0];
  253. //shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
  254.   }
  255. if(s==4)
  256. {
  257. f=shuzi[3]+10*shuzi[2]+100*shuzi[1]+1000*shuzi[0];
  258.   }
  259. if(s==5)
  260. {
  261. f=shuzi[4]+10*shuzi[3]+100*shuzi[2]+1000*shuzi[1]+10000*shuzi[0];
  262.   }
  263. if(s==6)
  264. {
  265. f=shuzi[5]+10*shuzi[4]+100*shuzi[3]+1000*shuzi[2]+10000*shuzi[1]+100000*shuzi[0];
  266.   }
  267. if(s==7)
  268. {
  269. f=shuzi[6]+10*shuzi[5]+100*shuzi[4]+1000*shuzi[3]+10000*shuzi[2]+100000*shuzi[1]+1000000*shuzi[0];
  270.   }
  271. if(s==8)
  272. {
  273. f=shuzi[7]+10*shuzi[6]+100*shuzi[5]+1000*shuzi[4]+10000*shuzi[3]+100000*shuzi[2]+1000000*shuzi[1]+10000000*shuzi[0];
  274.   }
  275. s=0;                           
  276. shuzi[0]=0;shuzi[1]=0;shuzi[2]=0;shuzi[3]=0;shuzi[4]=0;
  277.                                 shuzi[5]=0;shuzi[6]=0;shuzi[7]=0;shuzi[8]=0;shuzi[9]=0;        }
  278.                           else
  279.                           {
  280.                             P0=temp[s];
  281.                             LCD_set_position(0x40+s);
  282.                             LCD_printc(temp[s]);
  283.                             s=s+1;
  284.                           }
  285.                         }
  286.                 }
  287.         }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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