久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1543|回復: 2
打印 上一主題 下一主題
收起左側

單片機+AD9833+LCD1602+獨立按鍵程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:109865 發表于 2024-3-16 22:23 來自手機 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
輸出正弦波,三角波,方波,LCD顯示,獨立按鍵可調。分享給大家,應該是硬件問題吧,噪聲比較大,不知如何處理。

制作出來的實物圖如下:


波形圖:


單片機源程序如下:
  1. #include <reg52.h>
  2. #include <math.h>
  3. #define uchar8 unsigned char
  4. #define uint16 unsigned int
  5. #define ulong32 unsigned long
  6. //給正弦、三角、方波編碼
  7. #define SIN 0
  8. #define TRI 1
  9. #define SQU 2
  10. //顯示字庫
  11. uchar8 code table_desk[]="WAV FRE M  K  1";
  12. uchar8 code table_wave[]="sintrisqu";
  13. uchar8 code table_num[]="0123456789";
  14. uint16 Config_Data[8]={0};
  15. //AD9833控制端
  16. sbit  FSYNC=P3^4;
  17. sbit  SCLK=P3^3;
  18. sbit  SDATA=P3^2;
  19. //1602液晶控制端
  20. sbit lcden = P0^7;
  21. sbit lcdrs = P0^6;
  22. //
  23. sbit KEY0 = P0^0;
  24. sbit KEY1 = P0^1;
  25. sbit KEY2 = P0^2;
  26. sbit KEY3 = P0^3;
  27. sbit KEY4 = P0^4;
  28. sbit KEY5 = P0^5;
  29. //
  30. sbit LED0 = P1^0;
  31. sbit LED1 = P1^1;
  32. sbit LED2 = P1^2;
  33. sbit LED3 = P1^3;
  34. sbit LED4 = P1^4;
  35. sbit LED5 = P1^5;

  36. bit fre_r = 0;//AD9833的兩個頻率字寄存器建議交替使用
  37. uchar8 wav = 0;//波形,默認正弦波
  38. ulong32 fre = 1000;//頻率,默認1KHz
  39. uchar8 meg = 0 ,hunk= 0, tenk = 0,tho = 1,hun=0 ,ten = 0, uni = 0;//頻率字的各個位
  40. uchar8 bit_select = 0;//頻率位調節的選擇標志
  41. uchar8 num; //公用循環增量


  42. //AD9833的驅動函數
  43. void  Wave_Generate(ulong32,uchar8);
  44. //1ms延時函數
  45. void delay(uint16 z)
  46. {
  47.   uint16 x,y;
  48.   for(x = z;x>0;x--)
  49.     for(y =110;y>0;y--);
  50. }

  51. //向液晶寫命令,rs端置低
  52. void write_com(uchar8 com)
  53. {
  54.   delay(5);
  55.         delay(5);
  56.   P2 = com;
  57.         lcdrs = 0;
  58.   lcden = 1;
  59.   lcden = 0;
  60. }
  61. //向液晶寫數據,rs端置高即可
  62. void write_date(uchar8 date)
  63. {
  64. delay(5);
  65.         delay(5);
  66.         P2  =  date;
  67.         lcdrs  = 1;
  68.   lcden = 1;
  69.   lcden = 0;
  70. }
  71. //液晶初始化
  72. void init_lcd()
  73. {
  74.   lcden = 0;
  75.   write_com(0x38);//16×2顯示,5×7點陣,8位數據接口
  76.   delay(5);
  77.   write_com(0x0c);//開顯示,不顯示光標
  78.   delay(5);
  79.   write_com(0x06);//寫一個字符之后地址指針自動加1
  80.   delay(5);
  81.   write_com(0x01);//顯示清零,數據指針清零
  82. }
  83. //波形標示函數,在第二行前三個字符標明信號波形
  84. void wave(uchar8 w_wave)
  85. {
  86.   write_com(0xc0);//定位到第二行第一字符
  87.   switch(w_wave)
  88.   {
  89.     case 0:
  90.    for(num = 0;num < 3;++num)
  91.       {
  92.         write_date(table_wave[num]);
  93.         delay(5);
  94.       }
  95.    break;
  96. case 1:
  97.    for(num = 3;num < 6;++num)
  98.       {
  99.         write_date(table_wave[num]);
  100.         delay(5);
  101.       }
  102.    break;
  103. case 2:
  104.    for(num = 6;num < 9;++num)
  105.       {
  106.         write_date(table_wave[num]);
  107.         delay(5);
  108.       }
  109.    break;
  110. default:
  111.    for(num = 0;num < 3;++num)
  112.    {
  113.      write_date('?');
  114.   delay(5);
  115.    }
  116.    break;
  117.   }
  118. }
  119. //////////////////////////////////////////
  120. //向ad9833寫一命令字(2Bytes)
  121. void AD9833_Send_Word(uint16 Data_In)
  122. {
  123.    uchar8 i;
  124.    uchar8 j;

  125.    SCLK=1;
  126.    FSYNC=0;
  127.    for(i=0;i<16;i++)
  128.    {
  129.      SCLK=1;
  130.      SDATA=(bit)((Data_In & 0x8000)>>15);
  131.      j=0x01;
  132.      while(j--);
  133.      SCLK=0;
  134.      Data_In=Data_In<<1;
  135.      j=0x01;
  136.      while(j--);
  137.    }
  138.    FSYNC=1;
  139.    SCLK=0;
  140. }


  141. //波形發生函數
  142. //入口參數: 頻率:Freq (<=12000000)
  143. //          形狀:0(正弦波),1(三角波),2(方波)
  144. //默認: Fmclk=25MHz, 0相移,方波不分頻.
  145. void  Wave_Generate(ulong32 Freq,uchar8 Shape)
  146. {
  147.    ulong32 temp;
  148.    uchar8 k;
  149.    if(Freq>12000000) Freq=12000000;
  150.    switch(Shape)
  151.    {
  152.      case 0: Config_Data[0]=0x2108; // 0010 0001 0000 1000  reset(D8) =1
  153.              Config_Data[7]=0x2008; // 0010 0000 0000 1000
  154.              break;
  155.      case 1: Config_Data[0]=0x210A; //0010 0001 0000 1010
  156.              Config_Data[7]=0x200A; //0010 0000 0000 1010
  157.              break;
  158.      case 2: Config_Data[0]=0x2128; //0010 0001 0010 1000
  159.              Config_Data[7]=0x2028; //0010 0000 0010 1000
  160.              break;
  161.      default:Config_Data[0]=0x2108; //0010 0001 0000 1000
  162.              Config_Data[7]=0x2008; //0010 0000 0000 1000
  163.    }
  164.    temp=(long)(((double)Freq)*10.737418);   //temp=Freq*(0x10000000/20000000);
  165.    Config_Data[1]=temp&0x00003fff;  //0000 0000 0000 0000 0011 1111 1111 1111
  166.    Config_Data[3]=Config_Data[1];
  167.    Config_Data[2]=(temp&0x0fffc000)>>14;  //0000 1111 1111 1111 1100 0000 0000 0000
  168.    Config_Data[4]=Config_Data[2];

  169.    Config_Data[1]=Config_Data[1]|0x4000;  //0100 0000 0000 0000
  170.    Config_Data[2]=Config_Data[2]|0x4000;  //0100 0000 0000 0000
  171.    Config_Data[3]=Config_Data[3]|0x8000;  //1000 0000 0000 0000
  172.    Config_Data[4]=Config_Data[4]|0x8000;  //1000 0000 0000 0000
  173.    Config_Data[5]=0xC000;                 //1100 0000  0000 0000
  174.    Config_Data[6]=0xE000;                 //1110 0000  0000 0000

  175.    for(k=0;k<8;k++)
  176.    {
  177.      AD9833_Send_Word(Config_Data[k]);
  178.    }
  179. }


  180. void  Wave_Fre_ALT(bit fre_reg,ulong32 Freq)//寄存器
  181. {
  182.    ulong32 temp;
  183.    if(Freq>12000000) Freq=12000000;

  184.    temp=(long)(((double)Freq)*10.737418);   //temp=Freq*(0x10000000/20000000);268435456/25=10.737418,25是晶振頻率268435456/30=8.947848
  185.    Config_Data[0]=Config_Data[0] & 0x3eff; // 0011 1110 1111 1111
  186.    Config_Data[1]=temp&0x00003fff;  //0000 0000 0000 0000 0011 1111 1111 1111
  187.    Config_Data[2]=(temp&0x0fffc000)>>14;  //0000 1111 1111 1111 1100 0000 0000 0000
  188.    Config_Data[5]=0xC000;                 //1100 0000 0000 0000
  189.    Config_Data[6]=0xE000;                 //1110 0000 0000 0000

  190.      if(fre_reg)
  191.      {
  192.        Config_Data[1]=Config_Data[1]|0x8000;  //1000 0000 0000 0000連續的兩個頻率字的16 15位為10
  193.        Config_Data[2]=Config_Data[2]|0x8000;  //1000 0000 0000 0000表示寫到頻率寄存器1
  194.        Config_Data[7]=Config_Data[7]|0x0800; //0000 1000 0000 0000控制字的FSELECT為1/////////^^^^^^^^^^^^^^^^^
  195.      }
  196.      else
  197.      {
  198.        Config_Data[1]=Config_Data[1]|0x4000;  //0100 0000 0000 0000
  199.        Config_Data[2]=Config_Data[2]|0x4000;  //0100 0000 0000 0000  
  200.        Config_Data[7]=Config_Data[7]&0xf7ff; //1111 0111 1111 1111//……………………………………………………………………………………………………………難道是以前的寫錯了?
  201.      }
  202.   AD9833_Send_Word(Config_Data[0]);
  203.   AD9833_Send_Word(Config_Data[1]);
  204.   AD9833_Send_Word(Config_Data[2]);
  205.   AD9833_Send_Word(Config_Data[5]);
  206.   AD9833_Send_Word(Config_Data[6]);
  207.   AD9833_Send_Word(Config_Data[7]);
  208. }

  209. ////////////////////////////////////////////
  210. //在1602指定位顯示數據
  211. void write_lcd(uchar8 whe,uchar8 n)
  212. {
  213. if(whe < 16)//第一行
  214. {
  215.    write_com(0x80+whe-1);
  216.    write_date(n);
  217. }
  218. else       //第二行 21表示第二行第一個位置
  219. {
  220.       write_com(0x80+0x40 + whe-21);
  221.       write_date(n);
  222. }
  223. }

  224. //鍵盤掃描函數,根據不同的按鍵進行相應波形和頻率的設置
  225. void keyscan()
  226. {
  227.   if(!KEY0)//切換波形
  228.   {
  229.     delay(10);
  230.     if(!KEY0)
  231.     {
  232.       ++wav;
  233.    if(wav > 2)
  234.      wav = 0;
  235.    LED0 = 0;
  236.      wave(wav);
  237.    write_com(0x0c);
  238.       Wave_Generate(fre,wav);
  239.       while(!KEY0);
  240.       LED0 = 1;
  241.     }
  242.   }

  243.   if(!KEY1)//切換頻率的不同數位
  244.   {
  245.     delay(10);
  246.     if(!KEY1)
  247.     {
  248.       LED1 = 0;
  249.    write_com(0x0e);//顯示光標
  250.    ++bit_select;   //選擇的頻率字的位移動
  251.    if(bit_select > 7)
  252.    {
  253.      bit_select = 1;
  254.    }
  255.    write_com(0xcf - bit_select ); //光標移動到相應的位上
  256.       while(!KEY1);
  257.       LED1 = 1;
  258.     }
  259.   }

  260.   if(!KEY2)//頻率數字加按鈕
  261.   {
  262.     delay(10);
  263.     if(!KEY2)
  264.     {
  265.       LED2 = 0;
  266.    switch(bit_select)
  267.    {
  268.      case 1:
  269.     ++uni;
  270.     if(uni > 9)uni = 0;
  271.           write_lcd(35,table_num[uni]);
  272.     write_com(0xce);//寫完光標自動加1了,要把光標移回來
  273.     break;
  274.      case 2:
  275.     ++ten;
  276.     if(ten > 9)ten = 0;
  277.     write_lcd(34,table_num[ten]);
  278.     write_com(0xcd);
  279.     break;
  280.   case 3:
  281.     ++hun;
  282.     if(hun > 9)hun = 0;
  283.     write_lcd(33,table_num[hun]);
  284.     write_com(0xcc);
  285.     break;
  286.      case 4:
  287.     ++tho;
  288.     if(tho > 9)tho = 0;
  289.     write_lcd(32,table_num[tho]);
  290.     write_com(0xcb);
  291.     break;
  292.   case 5:
  293.     ++tenk;
  294.     if( tenk > 9)tenk = 0;
  295.     write_lcd(31,table_num[tenk]);
  296.     write_com(0xca);
  297.     break;
  298.   case 6:
  299.     ++hunk;
  300.     if( hunk > 9)hunk = 0;
  301.     write_lcd(30,table_num[hunk]);
  302.     write_com(0xc9);
  303.     break;
  304.   case 7:
  305.     ++meg;
  306.     if(meg > 2)meg = 0;
  307.     write_lcd(29,table_num[meg]);
  308.     write_com(0xc8);
  309.     break;
  310.    }
  311.       while(!KEY2);
  312.       LED2 = 1;
  313.     }
  314.   }
  315.   if(!KEY3)
  316.   {
  317.     delay(10);
  318.     if(!KEY3)
  319.     {
  320.       LED3 = 0;
  321.    fre = 1000000*((ulong32)meg) + 100000*((ulong32)hunk) + 10000*((ulong32)tenk) + 1000*((ulong32)tho) + 100*((ulong32)hun) + 10*((ulong32)ten) + (ulong32)uni;
  322.    write_com(0x0c);//關閉光標
  323.    fre_r = !fre_r;//這里要寫個LED燈的測試程序試試
  324.    Wave_Fre_ALT(fre_r,fre);
  325.       while(!KEY3);
  326.       LED3 = 1;
  327.     }
  328.   }
  329. }



  330. void init_scr()
  331. {
  332.   //在第一行顯示 WAV FRE M  K  1
  333.   write_com(0x80);
  334.   for(num = 0;num<15;num++)
  335.   {
  336.     write_date(table_desk[num]);
  337.     delay(5);
  338.   }
  339.   //在第二行顯示默認sin       00001000
  340.   //即正弦波,頻率1KHz
  341.   write_com(0xc0);
  342.   for(num = 0;num < 3;++num)
  343.   {
  344.     write_date(table_wave[num]);
  345.     delay(5);
  346.   }
  347.   write_com(0xc0 + 8);
  348.   for(num = 0;num < 7;++num)
  349.   {
  350.     if(3 == num)
  351. {
  352.    write_date('1');
  353.    delay(5);
  354. }
  355. else
  356. {
  357.       write_date('0');
  358.    delay(5);
  359. }
  360.   }
  361. }

  362. void main()
  363. {
  364.         
  365.   init_lcd();
  366. init_scr();
  367.   Wave_Generate(50000,0);
  368.   while(1)
  369.   {
  370.                   keyscan();
  371.   }
  372. }
復制代碼


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:109865 發表于 2024-3-17 14:34 | 只看該作者
Keil代碼在這里

ad9833_092613.rar

40.89 KB, 下載次數: 23, 下載積分: 黑幣 -5

回復

使用道具 舉報

板凳
ID:402383 發表于 2024-3-25 16:43 | 只看該作者
LZ請把原理圖發一下出來,讓大家分析一下硬件。
我以前用過51+AD9833,做出來的效果不錯。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 手机在线观看av | 欧美一级片免费看 | 免费人成激情视频在线观看冫 | 国产一区二区在线观看视频 | 国产欧美日韩二区 | 国产精品国产成人国产三级 | 狠狠干美女| 国产美女一区二区 | wwwxxx日本在线观看 | 福利在线观看 | 国产福利精品一区 | 久久久久国产 | 精品一区二区三区91 | 欧美a在线 | 夜操| 国产激情91久久精品导航 | 午夜精品久久久久久久久久久久久 | 我要看一级片 | 国产一区二区欧美 | 亚洲一区 中文字幕 | 中文在线一区二区 | 精品一级电影 | 亚洲一区视频在线 | 成人日韩 | 国产四区| 久草免费在线视频 | 精品日韩一区二区 | 亚洲成人网在线 | 美女国内精品自产拍在线播放 | 亚洲欧美激情四射 | 欧美中文在线 | 国产一区二区三区在线 | 天天操夜夜艹 | 精品国产18久久久久久二百 | 在线视频久久 | 成年人的视频免费观看 | 最新国产精品精品视频 | 久久免费精品 | 国产精品电影在线观看 | 精品欧美一区二区久久久伦 | 日本视频在线播放 |