標(biāo)題: 51單片機(jī)波形發(fā)生器程序設(shè)計及Proteus仿真 [打印本頁]

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



單片機(jī)源程序如下:

  1. /****************************************************************************************************************/
  2. /*                                           簡易波形發(fā)生器 程序                                                */
  3. /*                                            編寫者 :FHX                                                      */
  4. /*                                  可輸出 正弦波 三角波 方波  按鍵控制波形、頻率、步進(jìn)值                       */
  5. /*                            由于是單片機(jī)定時器控制頻率   經(jīng)測試頻率只能在10HZ ~ 700HZ 之間                    */
  6. /*                            有掉電儲存功能 再次上電時 顯示掉電前設(shè)置好的波形 頻率 步進(jìn)值                      */               
  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輸出對應(yīng)電壓值對應(yīng)的數(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)整波形、頻率及步進(jìn)值
  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)                               //箭頭指向 "步進(jìn)值" 說明在加減步進(jìn)值
  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 增加步進(jìn)值
  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 減小步進(jìn)值
  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;                                              //補(bǔ)償
  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;                                       //計算出需要多少個機(jī)器周期
  204.         tmp=65536-tmp;                                           //定時器的重載值
  205.         tmp=tmp+28;                                              //補(bǔ)償中斷延時響應(yīng)造成的誤差
  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. /*******輸出相應(yīng)頻率的波形數(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. }
復(fù)制代碼

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



作者: 12人    時間: 2020-1-7 11:43
lcd12哪個顯示屏的代碼是什么呀?頭文件那些程序代碼可不可以發(fā)一下呀,謝謝了
作者: 540431075    時間: 2020-3-18 13:31
不能運行,protues會報錯
作者: tim28    時間: 2020-8-13 17:21
540431075 發(fā)表于 2020-3-18 13:31
不能運行,protues會報錯

真的嗎?
我剛下載完看到你的評論
作者: 158751hei0141    時間: 2021-4-21 20:37
這圖和他展示的程序不是一套的,是拼出來的,大家注意。!





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1