找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8733|回復: 4
打印 上一主題 下一主題
收起左側(cè)

51單片機波形發(fā)生器程序設(shè)計及Proteus仿真

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:429738 發(fā)表于 2019-9-12 16:06 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
如題,內(nèi)容包括protuce仿真及源程序兩部分
一、 作品簡介:可以通過按鍵控制STC89C52單片機輸出[url=]不同波形[/url][z1] 信號。通過usb給pcb板通5v的電壓可以發(fā)出方波,三角波,鋸齒波,正弦波并在LCD顯示屏上顯示波形類別,頻率和幅值。通過按鍵可調(diào)波形類別,可調(diào)節(jié)頻率步進值有1Hz,10Hz和50Hz。最低頻率為10Hz最高頻率為800Hz。
  
  
二、設(shè)計原理:將各種波形的每個周期平均分成255份,把每份的值依次發(fā)給P0口,每份的時間間隔通過開啟定時器0來控制,當定時時間到時單片機就產(chǎn)生中斷,在中斷服務程序里面通過P0口將每份的值發(fā)出去,這個值通過向D/A換器的輸入端按一定的規(guī)律發(fā)生數(shù)據(jù),從而在轉(zhuǎn)換電路的輸出端得到相應的電壓波形。
  
  
三、    功能說明:能夠產(chǎn)生方波、鋸齒波、三角波、正弦波信號的波形發(fā)生器
  
(1)  按鍵選擇波形。按鍵控制單片機輸出方波、鋸齒波、三角波或者正弦波信號。按鍵K1,K2,K3,K4改變波形類型,K5,K6控制頻率的加減。
  
(2)  波形參數(shù)顯示。通過液晶屏顯示單片機當前輸出波形的頻率、幅度。
  
(3)  頻率調(diào)節(jié)。通過外部按鍵,調(diào)節(jié)單片機輸出波形信號的頻率。



單片機源程序如下:

  1. /****************************************************************************************************************/
  2. /*                                           簡易波形發(fā)生器 程序                                                */
  3. /*                                            編寫者 :FHX                                                      */
  4. /*                                  可輸出 正弦波 三角波 方波  按鍵控制波形、頻率、步進值                       */
  5. /*                            由于是單片機定時器控制頻率   經(jīng)測試頻率只能在10HZ ~ 700HZ 之間                    */
  6. /*                            有掉電儲存功能 再次上電時 顯示掉電前設(shè)置好的波形 頻率 步進值                      */               
  7. /****************************************************************************************************************/

  8. #include "lcd12864.h"
  9. #include "key.h"
  10. #include "24c02.h"
  11. #include "function.h"

  12. uchar T1RH = 0;                                //定時器1重載值高位
  13. uchar T1RL = 0;                                //定時器1重載值低位

  14. uchar T0RH = 0;                                //定時器0重載值高位
  15. uchar T0RL = 0;                                //定時器0重載值低位
  16. uchar mode = 0;
  17. sbit led=P2^4;
  18. sbit led1=P2^7;
  19. extern uchar Wave_Index;                       //聲明 波形變量

  20. uchar code sin[32]={                                             //此數(shù)組內(nèi)的數(shù)據(jù)為,DA輸出對應電壓值對應的數(shù)字量,0是0V,255是5V
  21.         127, 152, 176, 198, 217, 233, 245, 252,
  22.   255, 252, 245, 233, 217, 198, 176, 152,
  23.   127, 102, 78, 56, 37, 21, 9, 2,
  24.   0, 2, 9, 21, 37, 56, 78, 102

  25. };                                          //正弦波取碼
  26. uchar code juxing[32]={                                                 //一個周期是采樣32個點, 所以數(shù)組內(nèi)是32個數(shù)據(jù)
  27.         255,255,255,255,255,255,255,255,255,255,
  28.   255,255,255,255,255,255,0,0,0,0,0,0,0,0,
  29.         0,0,0,0,0,0,0,0
  30. };                                          //矩形波取碼

  31. uchar code sanjiao[32]={
  32.         0, 16, 32, 48, 64, 80, 96, 112,
  33.   128, 144, 160, 176, 192, 208, 224, 240,
  34.   255, 240, 224, 208, 192, 176, 160, 144,
  35.   128, 112, 96, 80, 64, 48, 32, 16

  36. };                                                //三角波取碼
  37. uchar code jvchi[32]={
  38.         0, 16, 32, 48, 64, 80, 96, 112,
  39.   128, 144, 160, 176, 192, 208, 224, 240,
  40.   255, 0, 16, 32, 48, 64, 80, 96, 112,
  41.   128, 144, 160, 176, 192, 208, 224

  42. };                                                //鋸齒波取碼


  43. /*****************子函數(shù)聲明*****************/
  44. void Timer1Init(uint ms);
  45. void SetWaveRate(uint num_2);
  46. void Control_Key();
  47. void Refresh_Out();
  48. /*****************************************************************************/
  49. /*                                 主函數(shù)                                    */
  50. /*****************************************************************************/
  51. void main()
  52. {        led=1;
  53.     led1=1;
  54.         Timer1Init(1);                          //初始化定時器1 定時1ms
  55.         LcdInit();                              //初始化12864
  56.         Init_Display();                         //顯示固定內(nèi)容
  57.         Init_OutPut();                          //初始化輸出數(shù)據(jù)和顯示

  58.         while(1)
  59.         {
  60.                 Refresh_Out();                        //更新輸出 mode=0:輸出波形 獨立按鍵關(guān)閉 mode!=0 :關(guān)閉波形輸出 可用獨立按鍵調(diào)整
  61.                 Control_Key();                        //控制獨立按鍵 調(diào)整模式mode
  62.                 KeyDrive();                                                                      //調(diào)整波形、頻率及步進值
  63.         }
  64. }

  65. /*****************************************************************************/
  66. /*                             按鍵控制函數(shù)                                  */
  67. /*               按鍵KEY_1 :用延時函數(shù)判斷按下 控制模式變換                  */
  68. /*****************************************************************************/
  69. void Control_Key()
  70. {
  71.         if(KEY_1==0)                            //按下按鍵1  mode+1
  72.         {
  73.                 DelayMs(2);
  74.                 if(KEY_1==0)
  75.                 {
  76.                         while(!KEY_1);
  77.                         mode++;                              
  78.                         if(mode > 3)mode = 1;
  79.                 }
  80.         }
  81. }

  82. /*****************************************************************************/
  83. /*                            更新輸出函數(shù)                                   */
  84. /*                      根據(jù)不同的模式變量 打開或關(guān)閉波形輸出                */
  85. /*****************************************************************************/
  86. void Refresh_Out()
  87. {
  88.                         if(mode == 0)                                    //不顯示箭頭   輸出波形 獨立按鍵關(guān)閉
  89.                   {
  90.                                 ET1=0;
  91.                           TR1=0;
  92.                           ET0=1;       
  93.               TR0=1;
  94.                     EA=1;
  95.                           Display_Arr(0);
  96.                   }
  97.                
  98.                   else if(mode == 1)                               //箭頭指向 "波形"   說明是在切換波形
  99.                   {
  100.                                 ET1=1;
  101.               TR1=1;
  102.                           ET0=0;       
  103.               TR0=0;
  104.                           EA=1;
  105.                           Display_Arr(1);
  106.                   }
  107.                
  108.                   else if(mode == 2)                               //箭頭指向 "頻率"   說明是在加減頻率
  109.                   {
  110.                                 ET1=1;
  111.                           TR1=1;
  112.                           ET0=0;       
  113.               TR0=0;
  114.                     EA=1;
  115.                           Display_Arr(2);
  116.                   }
  117.                
  118.                   else if(mode == 3)                               //箭頭指向 "步進值" 說明在加減步進值
  119.                   {
  120.                                 ET1=1;
  121.                           TR1=1;
  122.                           ET0=0;       
  123.               TR0=0;
  124.                     EA=1;
  125.                           Display_Arr(3);
  126.                   }
  127. }


  128. /*****************************************************************************/
  129. /*                             按鍵動作函數(shù)                                  */
  130. /*          按鍵  KEY_2 ~ KEY_4 三個按鍵由定時器1中斷掃描 有長按功能         */
  131. /*****************************************************************************/
  132. void KeyDown(uchar keycode)
  133. {
  134.         /*********************************/
  135.         /*            "+"鍵              */
  136.         /*********************************/       
  137.         if(keycode == 0x26)                          
  138.         {
  139.                 if(mode == 1)                                    //模式1 向右切換波形
  140.                 {
  141.                         Convert_Wave(1);
  142.                 }
  143.                
  144.                 else if(mode == 2)                               //模式2 增加頻率
  145.                 {
  146.                         Change_Rate(1);
  147.                 }
  148.                
  149.                 else if(mode == 3)                               //模式3 增加步進值
  150.                 {
  151.                         Change_Step(1);
  152.                 }
  153.   }
  154.         /*********************************/
  155.         /*            "-"鍵              */
  156.         /*********************************/
  157.         else if(keycode == 0x28)                           
  158.         {
  159.                 if(mode == 1)                                    //模式1 向左切換波形
  160.                 {
  161.                         Convert_Wave(0);
  162.                 }
  163.                
  164.                 else if(mode == 2)                               //模式2 減小頻率
  165.                 {
  166.                         Change_Rate(0);
  167.                 }
  168.                
  169.                 else if(mode == 3)                               //模式3 減小步進值
  170.                 {
  171.                         Change_Step(0);     
  172.                 }
  173.         }
  174.         /*********************************/
  175.         /*          模式清零鍵           */
  176.         /*********************************/       
  177.         else if(keycode == 0x0D)
  178.         {
  179.                 mode = 0;
  180.         }
  181. }



  182. /**********頻率設(shè)置函數(shù)****************/
  183. /************定時器0控制***************/
  184. void SetWaveRate(uint num_2)
  185. {
  186.         ulong tmp;                                             
  187.         tmp=(12000000/12)/(num_2*32);                            //定時器計數(shù)頻率 是波形頻率的32倍                                                                        
  188.         tmp=65536-tmp;                                           //計算定時器重載值                        
  189.   tmp=tmp+18;                                              //補償
  190.         T0RH=(uchar)(tmp>>8);                                    
  191.         T0RL=(uchar)tmp;
  192.         TMOD&=0xF0;                                          
  193.         TMOD|=0x01;                                          
  194.         TH0=T0RH;                                             
  195.         TL0=T0RL;
  196. }

  197. /**********定時器1初始化函數(shù)***********/
  198. /**********用于三個獨立按鍵掃描********/
  199. void Timer1Init(uint ms)
  200. {
  201.         ulong tmp;                                               //16位長整型變量tmp
  202.         tmp=12000000/12;                                         //用晶振頻率除以12得到定時器計數(shù)頻率
  203.         tmp=(tmp*ms)/1000;                                       //計算出需要多少個機器周期
  204.         tmp=65536-tmp;                                           //定時器的重載值
  205.         tmp=tmp+28;                                              //補償中斷延時響應造成的誤差
  206.         T1RH=(uchar)(tmp>>8);                                    //將tmp高8位右移8位 賦值給T1RH
  207.         T1RL=(uchar)tmp;                                         //將tmp低8位賦值給T0RL
  208.         TMOD&=0x0F;                                              //清零T1控制位
  209.         TMOD|=0x10;                                              //選擇模式1

  210. }

  211. /**********定時器0中斷函數(shù)**********/
  212. /*******輸出相應頻率的波形數(shù)據(jù)******/
  213. void InterruptTimer0() interrupt 1
  214. {
  215.         static uchar cnt;                                               //變量 用于輸出波形采樣點
  216.         TH0=T0RH;
  217.         TL0=T0RL;
  218.         switch(Wave_Index)
  219.         {
  220.                 case 0:DAC_OUT=sin[cnt];break;
  221.                 case 1:DAC_OUT=sanjiao[cnt];break;
  222.                 case 2:DAC_OUT=juxing[cnt];break;
  223.         }
  224.         cnt++;
  225.         if(cnt>=32)cnt=0;
  226. }

  227. void InterruptTimer1() interrupt 3
  228. {
  229.         TH1=T1RH;                                                //重載初值
  230.         TL1=T1RL;
  231.   KeyScan();                                               //按鍵掃描
  232. }
復制代碼

所有資料51hei提供下載:
仿真及程序.rar (98.29 KB, 下載次數(shù): 214)
程序代碼.rar (100.73 KB, 下載次數(shù): 128)


評分

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

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:682755 發(fā)表于 2020-1-7 11:43 | 只看該作者
lcd12哪個顯示屏的代碼是什么呀?頭文件那些程序代碼可不可以發(fā)一下呀,謝謝了
回復

使用道具 舉報

板凳
ID:551189 發(fā)表于 2020-3-18 13:31 | 只看該作者
不能運行,protues會報錯
回復

使用道具 舉報

地板
ID:727952 發(fā)表于 2020-8-13 17:21 | 只看該作者
540431075 發(fā)表于 2020-3-18 13:31
不能運行,protues會報錯

真的嗎?
我剛下載完看到你的評論
回復

使用道具 舉報

5#
ID:505058 發(fā)表于 2021-4-21 20:37 | 只看該作者
這圖和他展示的程序不是一套的,是拼出來的,大家注意。!
回復

使用道具 舉報

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

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表