找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 51849|回復(fù): 66
打印 上一主題 下一主題
收起左側(cè)

proteus仿真的51單片機(jī)信號發(fā)生器 課程設(shè)計(jì)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
51單片機(jī)簡易信號發(fā)生器的proteus仿真圖:




程序,仿真文件,課程設(shè)計(jì)論文下載: signal-generator.zip (1.44 MB, 下載次數(shù): 1055)

程序:
  1. #include
  2. #include
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. //--LCD控制引腳
  6. sbit RS=P3^0;
  7. sbit RW=P3^1;
  8. sbit EN=P3^3;
  9. //--按鍵
  10. sbit K1=P2^0;
  11. sbit K2=P2^1;
  12. sbit K3=P2^2;
  13. sbit K4=P2^3;
  14. sbit K5=P2^4;

  15. uchar WaveChoice=1;
  16. uchar ys=30;
  17. uchar i,a=0;
  18. uchar sqar_num=128;
  19. uint freq;

  20. uchar code Sin[]={"Sine      "};
  21. //uchar code exp[]={"Exp      "};
  22. uchar code Squ[]={"Square    "} ;
  23. uchar code Tri[]={"Triangle  "};
  24. uchar code Saw[]={"Sawtooth  "} ;
  25. uchar code No[]={"No Signal out "};
  26. uchar code Wave[]={"Wave :"};
  27. uchar code Fre[]={"Freq :"};

  28. uchar code tosin[256]=
  29. {0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,
  30. 0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,
  31. 0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,
  32. 0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
  33. 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,
  34. 0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,
  35. 0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,
  36. 0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,
  37. 0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,
  38. 0x51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,
  39. 0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,0x15,0x13,0x11,0x10,0x0e,
  40. 0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,
  41. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,
  42. 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,0x18,
  43. 0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,
  44. 0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e ,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,
  45. 0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80 }; //正弦波碼

  46. //--延時(shí)MS
  47. void DelayMS(uchar ms)
  48. {
  49.         uchar i;
  50.         while(ms--) for(i=0;i<120;i++);
  51. }
  52. //--延時(shí)y*9us
  53. void Delay1(uint y)
  54. {
  55.          uint i;
  56.         for(i=y;i>0;i--);
  57. }
  58. //-------------
  59. //忙檢查
  60. //-----------------------------
  61. uchar Busy_Check()
  62. {
  63.         uchar LCD_Status;
  64.         RS=0;  //        寄存器選擇
  65.         RW=1; //讀狀態(tài)寄存器
  66.         EN=1;  // 開始讀
  67.         DelayMS(1);
  68.         LCD_Status=P1;
  69.         EN=0;
  70.         return  LCD_Status;

  71. }
  72. //----------------------------
  73. //寫LCD命令
  74. //---------------------------------
  75. void Write_LCD_Command(uchar cmd)
  76. {
  77.            while((Busy_Check()&0x80)==0x80);   //忙等待
  78.            RS=0;  //選擇命令寄存器
  79.            RW=0;  //寫
  80.            EN=0;
  81.            P1=cmd;EN=1;DelayMS(1);EN=0;
  82. }
  83. //--------------------------------------
  84. //發(fā)送數(shù)據(jù)
  85. //---------------------------------------
  86. void Write_LCD_Data(uchar dat)
  87. {
  88.          while((Busy_Check()&0x80)==0x80);   //忙等待        
  89.           RS=1;  RW=0; EN=0; P1=dat;EN=1;DelayMS(1);EN=0;        
  90. }
  91. //------------------------------------
  92. //LCD初始化
  93. //-----------------------------------------
  94. void Init_LCD()
  95. {               
  96.         Write_LCD_Command(0x38);
  97.         DelayMS(1);
  98.         Write_LCD_Command(0x01); //清屏
  99.         DelayMS(1);
  100.         Write_LCD_Command(0x06); //字符進(jìn)入模式:屏幕不動(dòng),字符后移
  101.         DelayMS(1);
  102.         Write_LCD_Command(0x0C); //顯示開、關(guān)光標(biāo)
  103.         DelayMS(1);
  104. }

  105. //--向LCD寫頻率值
  106. void Write_freq(uint k)
  107. {
  108.         uchar qian,bai,shi,ge;
  109.         qian=k/1000;
  110.         bai=k/100%10;
  111.         shi=k/10%10;
  112.         ge=k%10;
  113.         Write_LCD_Command(0x86+0x40);
  114.         Write_LCD_Data(0x30+qian);
  115.         Write_LCD_Data(0x30+bai);
  116.         Write_LCD_Data(0x30+shi);
  117.         Write_LCD_Data(0x30+ge);
  118.         Write_LCD_Data(0x48);
  119.         Write_LCD_Data(0x5a);
  120. }

  121. //--LCD上顯示不同波形頻率
  122.   void Xianshi_f()                  
  123. {
  124.   if(WaveChoice==1)
  125.   {
  126.      freq=(10000000/(50000+2860*ys));
  127.          Write_freq(freq);
  128.   }
  129.   if(WaveChoice==2)
  130.   {
  131.      freq=(10000000/(50000+2300*ys));
  132.          Write_freq(freq);
  133.   }
  134.    if(WaveChoice==3)
  135.   {
  136.      freq=(10000000/(14000+2300*ys));
  137.          Write_freq(freq);
  138.   }
  139.     if(WaveChoice==4)
  140.   {
  141.      freq=(10000000/(15000+2300*ys));
  142.          Write_freq(freq);
  143.   }
  144. }
  145. //--LCD上寫波形類型
  146. void Write_wave(uchar  t )
  147. {
  148.         switch(t)
  149.         {
  150.                 case 0:
  151.                                 //-- 無輸出
  152.                                  Write_LCD_Command(0x86);
  153.                                    DelayMS(5);
  154.                                     for (i=0;i<sizeof(no)-1;i++)
  155.                                         {
  156.                                                 Write_LCD_Data(No[i]);
  157.                                                 DelayMS(5);
  158.                                         }
  159.                                         break;
  160.                 case 1:
  161.                                 //--正弦波
  162.                                 ys=25;
  163.                                 Write_LCD_Command(0x86);
  164.                                    DelayMS(5);
  165.                                     for (i=0;i<sizeof(sin)-1;i++)
  166.                                         {
  167.                                                 Write_LCD_Data(Sin[i]);
  168.                                                 DelayMS(5);
  169.                                         }
  170.                                 break;
  171.                 case 2:
  172.                                 //---矩形波
  173.                                 ys=30;
  174.                                 Write_LCD_Command(0x86);
  175.                                    DelayMS(5);
  176.                                     for (i=0;i<sizeof(squ)-1;i++)
  177.                                         {
  178.                                                 Write_LCD_Data(Squ[i]);
  179.                                                 DelayMS(5);
  180.                                          }
  181.                         
  182.                                 break;
  183.                 case 3:
  184.                                 //---三角波
  185.                                 ys=30;
  186.                                 Write_LCD_Command(0x86);
  187.                                    DelayMS(5);
  188.                                     for (i=0;i<sizeof(tri)-1;i++)
  189.                                         {
  190.                                                 Write_LCD_Data(Tri[i]);
  191.                                                 DelayMS(5);
  192.                                         }
  193.                                 break;
  194.                 case 4:
  195.                                 //----鋸齒波
  196.                                 ys=30;
  197.                                    Write_LCD_Command(0x86);//液晶顯示位置
  198.                                    DelayMS(5);
  199.                                     for (i=0;i<sizeof(saw)-1;i++)
  200.                                         {
  201.                                                 Write_LCD_Data(Saw[i]);
  202.                                                 DelayMS(5);
  203.                                          }
  204.                                 break;
  205.         }
  206. }
  207. //---輸出波形
  208. void Out_Wave(uchar i)
  209. {         uchar j;        
  210.         switch(i)
  211.         {
  212.                 case 0:        P0=0x00;break;
  213.                 case 1:
  214.                                 //---正弦波
  215.                                 for (j=0;j<255;j++)
  216.                                 {
  217.                                         P0=tosin[j];
  218.                                         Delay1(ys);
  219.                                 }
  220.                                  break;
  221.                 case 2:
  222.                                 //----矩形波
  223.                                 {
  224.                                         if(a<sqar_num)
  225.                                                 {
  226.                                                         P0=0xff;
  227.                                                         Delay1(ys);
  228.                                                 }
  229.                                         else  
  230.                                                 {
  231.                                                         P0=0x00;
  232.                                                         Delay1(ys);
  233.                                                 }
  234.                                                 a++;
  235.                                 }  break;
  236.                 case 3:
  237.                                 //----三角波
  238.                                 {
  239.                                         if(a<128)
  240.                                                 {
  241.                                                         P0=a;
  242.                                                         Delay1(ys);
  243.                                                 }
  244.                                         else  
  245.                                                 {
  246.                                                         P0=255-a;
  247.                                                         Delay1(ys);
  248.                                                 }
  249.                                                 a++;
  250.                                 }   break;
  251.                 case 4:
  252.                            //----鋸齒波
  253.                                 {
  254.                                          if(a<255)
  255.                                         {
  256.                                                 P0=a;
  257.                                                 Delay1(ys);
  258.                                         }
  259.                                 
  260.                                 a++;
  261.                         if(a==255)
  262.                                 {
  263.                                         a=0;
  264.                                 }   break;
  265.                 }
  266.         }
  267. }
  268. //----按鍵掃描
  269. void keyscanf()
  270. {        
  271.         if(K2==0)
  272.         {
  273.                 DelayMS(5);
  274.                 if(K2==0)
  275.                 {
  276.                         while(!K2);
  277.                         ys--;
  278.                         if(ys==0)
  279.                         ys=20;
  280.                 }
  281.         }
  282.         if(K3==0)
  283.         {
  284.                 DelayMS(5);
  285.                 if(K3==0)
  286.                 {
  287.                         while(!K3);
  288.                         ys++;
  289.                         if(ys>22)
  290.                         ys=20;
  291.                 }
  292.         }
  293.         if(K4==0)
  294.         {
  295.                 DelayMS(5);
  296.                 if(K4==0)
  297.                 {
  298.                         while(!K4);
  299.                         if(WaveChoice==2)
  300.                         sqar_num=sqar_num+2;
  301.                         if(sqar_num==238)
  302.                                 sqar_num=128;
  303.                 }
  304.         }
  305.         if(K5==0)
  306.         {
  307.                 DelayMS(5);
  308.                 if(K5==0)
  309.                 {
  310.                         while(!K5);
  311.                         if(WaveChoice==2)
  312.                         sqar_num=sqar_num-2;
  313.                         if(sqar_num==18)
  314.                                 sqar_num=128;                        
  315.                 }
  316.         }
  317. }

  318. //----主程序---
  319. void main()
  320. {
  321.         Init_LCD();
  322.         IE=0X81;
  323.         IT0=1;
  324.         Write_LCD_Command(0x80);//--顯示wave:
  325.            DelayMS(5);                 
  326.    for (i=0;i<sizeof(wave)-1;i++)
  327.                 {
  328.                         Write_LCD_Data(Wave[i]);
  329.                         DelayMS(5);
  330.                 }
  331.             Write_LCD_Command(0x80+0X40);//----顯示freq:
  332.      DelayMS(5);
  333.     for (i=0;i<sizeof(fre)-1;i++)
  334.                 {
  335.                         Write_LCD_Data(Fre[i]);
  336.                         DelayMS(5);
  337.                 }
  338.            Write_wave(WaveChoice);
  339.         while (1)
  340.         {
  341.                          keyscanf();
  342.                 Out_Wave(WaveChoice);
  343.                 if(!(K1&K2&K3))
  344.                                 Xianshi_f();
  345.         }         
  346. }

  347. //---INT0中斷
  348. void EX_INT0() interrupt 0
  349. {

  350.                 WaveChoice++;
  351.                 if(WaveChoice==5) WaveChoice=1;
  352.                 Write_wave(WaveChoice);

  353. }
復(fù)制代碼

以下是論文預(yù)覽:

課程設(shè)計(jì)



題    目 基于proteus仿真的簡易信號發(fā)生器的設(shè)計(jì)

學(xué)    院管理科學(xué)與工程學(xué)院

專    業(yè) 電子信息工程

班    級     08信工(3)班

學(xué)    號201883062

姓    名高 攀


信號發(fā)生器是一種常用的信號源,廣泛地應(yīng)用于電子電路、自動(dòng)控制系統(tǒng)和教學(xué)實(shí)驗(yàn)等領(lǐng)域。 本設(shè)計(jì)采用AT89C51單片機(jī)作為控制核心,外圍采用數(shù)字/模擬轉(zhuǎn)換電路(DAC0832)、運(yùn)放電路(LM324)、按鍵和LCD液晶顯示電路。電路采用單片機(jī)和一片DAC0832數(shù)模轉(zhuǎn)換器組成數(shù)字式低頻信號發(fā)生器,可產(chǎn)生正弦波、矩形波、鋸齒波和三角波四種波形。系統(tǒng)通過單片機(jī)產(chǎn)生數(shù)字信號,通過DAC0832轉(zhuǎn)換為模擬信號,再通過放大器LM324就可以得到雙極性的各種波形,最終由示波器顯示出來。通過鍵盤來控制四種波形的類型選擇、頻率變化,并通過液晶1602顯示其各自的波形類型以及頻率數(shù)值。

本設(shè)計(jì)硬件電路簡單,軟件功能完善,控制系統(tǒng)可靠,性價(jià)比較高,具有一定的實(shí)用價(jià)值和參考價(jià)值。

關(guān)鍵詞AT89C51 單片機(jī); 函數(shù)信號發(fā)生器;DAC0832;LCD液晶顯示

Abstract

Signal generator is a common signal source, widely used in electronic circuits, automatic control systems and experiments in areas such as teaching. The design using AT89C51 microcontroller as the control, external digital/analog conversion circuit (DAC0832), op-amp circuit (LM324), buttons and liquid crystal display of 1602. Circuit adopts single-chip microcomputer and a digital-to-analog converters DAC0832 consisting a low frequency signal generator, can produce four waveform such as the sine wave, the rectangle wave, the sawtooth wave and the triangle wave. System through the microcontroller create a digital signal, through DAC0832 into analog signals, again through the amplifier LM324 can get dual polarity by various waveform, finally shown by An oscilloscope. In this system, through the keyboard to control four waveform type selection, frequency variation, and displays those through liquid crystal display of 1602.

In this design, the hardware circuits are simple, software functions are consummate, and the control system is reliable, so it has some practical value and reference value.

KeywordsAT89C51;function generator;DAC0832;LCD display

1 系統(tǒng)總體設(shè)計(jì)              1

1.1 系統(tǒng)基本模塊設(shè)計(jì)與論證              1

1.1.1 信號發(fā)生模塊              1

1.1.2 輸出顯示模塊              1

1.1.3 鍵盤模塊              1

1.1.4 電路設(shè)計(jì)最終方案              2

1.2 系統(tǒng)原理及總體結(jié)構(gòu)圖              2

1.2.1 系統(tǒng)總體結(jié)構(gòu)圖              2

1.2.2 系統(tǒng)工作原理              2

2 系統(tǒng)硬件設(shè)計(jì)              3

2.1 系統(tǒng)硬件仿真原理圖              3

2.2 系統(tǒng)主要單元電路設(shè)計(jì)              4

2.2.1 主控制器AT89C51              4

2.2.2 數(shù)/模轉(zhuǎn)換電路              7

2.2.3 電流/電壓轉(zhuǎn)換放大電路

2.2.4 液晶顯示電路            

2.2.5 鍵盤電路

3 系統(tǒng)軟件設(shè)計(jì)

3.1 系統(tǒng)主程序流程框圖

3.2 信號產(chǎn)生子程序

3.2.1 正弦波發(fā)生子程序

3.2.2 矩形波發(fā)生子程序              18

3.2.3 三角波發(fā)生子程序              18

3.2.4 鋸齒波發(fā)生子程序              20

3.3按鍵處理子程序              20

3.4液晶顯示子程序

3.5 INT0中斷子程序              1

4 系統(tǒng)調(diào)試

4.1 系統(tǒng)調(diào)試過程

4.2 調(diào)試中的問題及解決方法

4.3 系統(tǒng)仿真結(jié)果

5 結(jié)論              28

5.1 結(jié)論              28

參考文獻(xiàn)8




1 系統(tǒng)總體設(shè)計(jì)1.1 系統(tǒng)基本模塊設(shè)計(jì)與論證 1.1.1 信號發(fā)生模塊

方案一:利用MAX038芯片組成的電路輸出波形。MAX038是精密高頻波形產(chǎn)生芯片,能夠產(chǎn)生準(zhǔn)確的三角波、方波和正弦波三種周期性波形。但此方案成本高,程序復(fù)雜度高。

方案二:采用分立元件實(shí)現(xiàn)非穩(wěn)態(tài)的多諧振振蕩器,然后根據(jù)需要加入積分電路等構(gòu)成正弦、矩形、三角等波形發(fā)生器。這種信號發(fā)生器輸出頻率范圍窄,而且電路參數(shù)設(shè)定較繁瑣,其頻率大小的測量往往需要通過硬件電路的切換來實(shí)現(xiàn),操作不方便。               

方案三:采用單片機(jī)和DAC0832數(shù)模轉(zhuǎn)換器生成波形。通過編程的方法來控制輸入到數(shù)模轉(zhuǎn)換電路的數(shù)字量,從而控制輸出信號的波形和頻率。它的特點(diǎn)是價(jià)格低、設(shè)計(jì)簡單,在低頻范圍內(nèi)穩(wěn)定性好、操作方便、體積小、耗電少。

經(jīng)比較,方案三既可滿足畢業(yè)設(shè)計(jì)的基本要求又能充分發(fā)揮其優(yōu)勢,電路簡單,易控制,性價(jià)比較高,所以采用該方案。

1.1.2 輸出顯示模塊

方案一:用數(shù)碼管進(jìn)行顯示。數(shù)碼管由于顯示速度快,使用簡單,顯示效果簡潔明了而得到了廣泛應(yīng)用。但是由于我們計(jì)劃顯示輸出信號波形類型和頻率,內(nèi)容很多。用數(shù)碼管無法顯示如此豐富的內(nèi)容,因此我們放棄了此方案。

方案二:用LCD液晶進(jìn)行顯示。LCD由于其顯示清晰,顯示內(nèi)容豐富,顯示信息量大,使用方便,顯示快速而得到了廣泛的應(yīng)用。

對于此系統(tǒng)我們選用的LCD LM016L液晶能夠顯示英語字母和數(shù)字,能夠很好的滿足顯示要求,因此我們選擇了此方案。

1.1.3鍵盤模塊

方案一:采用獨(dú)立式按鍵電路,每個(gè)按鍵單獨(dú)占有一根I/O接口線,每個(gè)I/O口的工作狀態(tài)互不影響,此類鍵盤采用端口直接掃描方式。缺點(diǎn)為當(dāng)按鍵較多時(shí)占用單片機(jī)的I/O口數(shù)目較多,優(yōu)點(diǎn)為電路設(shè)計(jì)簡單,且編程相對比較容易。

方案二:采用矩陣式鍵盤,鍵盤為4*4矩陣式行列掃描,優(yōu)點(diǎn)是當(dāng)按鍵較多時(shí)可降低占用單片機(jī)的I/O口數(shù)目。

對于此系統(tǒng),由于按鍵數(shù)目不多,故采用方案一。

1.1.4 電路設(shè)計(jì)最終方案

本系統(tǒng)包括主控模塊,顯示模塊,信號發(fā)生模塊,鍵盤模塊,運(yùn)放模塊,綜上各方案所述,確定最終設(shè)計(jì)方案為:采用AT89C51作為主控制系統(tǒng),LCD液晶顯示作為顯示部分,獨(dú)立式按鍵作為鍵盤模塊,數(shù)模轉(zhuǎn)換芯片DAC0832作為信號發(fā)生模塊,LM324作為電流/電壓轉(zhuǎn)換放大模塊。

1.2 系統(tǒng)原理及總體結(jié)構(gòu)圖1.2.1 系統(tǒng)總體結(jié)構(gòu)圖

根據(jù)上述電路設(shè)計(jì)的最終方案,系統(tǒng)總體設(shè)計(jì)結(jié)構(gòu)如圖1所示。

圖1  系統(tǒng)總體結(jié)構(gòu)圖
1.2.2系統(tǒng)工作原理

數(shù)字信號可以通過數(shù)/模轉(zhuǎn)換器轉(zhuǎn)換成模擬信號,因此可通過產(chǎn)生數(shù)字信號再轉(zhuǎn)換成模擬信號的方法來獲得所需要的波形。在本設(shè)計(jì)中,AT89C51是整個(gè)波形發(fā)生器的核心部分,外圍電路包括數(shù)字/模擬轉(zhuǎn)換電路、電流/電壓轉(zhuǎn)換放大電路、按鍵電路、LCD液晶顯示電路和晶振電路。外接12MHz晶振電路為單片機(jī)提供工作脈沖。單片機(jī)的P1口接LCD液晶顯示電路,用來顯示波形類型和頻率大;P0口接數(shù)模轉(zhuǎn)換芯片DAC0832的DI0~DI7,為數(shù)模轉(zhuǎn)換芯片提供數(shù)字信號;P2.0~P2.4外接獨(dú)立鍵盤,以控制信號的類型、頻率等;P3部分口作為LCD的控制信號。

通過對單片機(jī)編寫程序,控制從P0口輸出的數(shù)字信號類型,P0口的數(shù)字信號再輸入到數(shù)模轉(zhuǎn)換芯片DAC0832中,從而轉(zhuǎn)換為模擬信號輸出。DAC0832輸出的模擬信號為電流信號,所以用電流/電壓運(yùn)算放大器LM324將電流信號再轉(zhuǎn)換成電壓信號輸出。用兩片LM324可以得到輸出波形的雙極性輸出,將輸出的波形與示波器相連即可觀察輸出波形的特征。獨(dú)立式鍵盤可以控制從P0口輸出的數(shù)字信號,按下不同的鍵可以使此輸出信號改變,從而使輸出的波形實(shí)現(xiàn)正弦波、矩形波、鋸齒波和三角波之間的轉(zhuǎn)變,并能夠改變波形輸出頻率的大小。在此過程中,單片機(jī)將信號的類型和頻率經(jīng)過處理后,由P1口送到LCD液晶顯示器上進(jìn)行顯示,LCD1602第一行顯示信號的類型,第二行顯示波形的頻率。

2 系統(tǒng)硬件設(shè)計(jì)2.1系統(tǒng)硬件仿真原理圖

硬件設(shè)計(jì)是系統(tǒng)設(shè)計(jì)的重點(diǎn)之一,選擇合適的元器件尤為重要。在本設(shè)計(jì)中,根據(jù)設(shè)計(jì)的總體方案,選擇AT89C51作為主控制器、DAC0832為數(shù)模轉(zhuǎn)換芯片、LM324為電流/電壓轉(zhuǎn)換元件、LM016L為LCD液晶顯示元件、5個(gè)獨(dú)立式按鍵為按鍵模塊元件。本設(shè)計(jì)在Proteus軟件中繪制的硬件電路圖如圖2所示。

圖2  硬件仿真原理圖
2.2 系統(tǒng)主要單元電路設(shè)計(jì)2.2.1 主控制器AT89C51

AT89C51是美國ATMEL公司生產(chǎn)的低電壓、高性能CMOS 8位單片機(jī),片內(nèi)含4KB的可反復(fù)擦除的只讀程序存儲(chǔ)器(PEROM)和128B隨機(jī)存取數(shù)據(jù)存儲(chǔ)器(RAM),器件采用ATMEL公司的高密度、非易失性存儲(chǔ)技術(shù)生產(chǎn)兼容標(biāo)準(zhǔn)MCS-51指令系統(tǒng),片內(nèi)置通用8位中央處理器(CPU)和FLASH存儲(chǔ)單元,功能強(qiáng)大AT89C51單片機(jī)可為您提供許多高性價(jià)比的應(yīng)用場合。

主要性能參數(shù):

①與MCS-51產(chǎn)品指令系統(tǒng)完全兼容

②4K字節(jié)可重擦寫FLASH閃速存儲(chǔ)器

③1000次擦寫周期

④全靜態(tài)操作:0HZ-24MHZ

⑤三級加密程序存儲(chǔ)器

⑥128

8字節(jié)內(nèi)部RAM

⑦32個(gè)可編程I/O口線

⑧2個(gè)16位定時(shí)/計(jì)數(shù)器

⑨6個(gè)中斷源

⑩可編程串行UART通道

                     

                       圖3   AT89C51 引腳封裝圖

AT89C51引腳封裝如圖3所示,其芯片引腳介紹如下:

(1)主電源引腳

VCC:+5 V電源   VSS:地線。

(2)時(shí)鐘電路引腳

XTAL1和XTAL2:外接晶體引線端。當(dāng)使用芯片內(nèi)部時(shí)鐘時(shí),此二引線端用于外接石英晶體和微調(diào)電容;當(dāng)使用外部時(shí)鐘時(shí),用于接外部時(shí)鐘脈沖信號。

(3)控制信號引腳

RST/VPD:復(fù)位信號。當(dāng)輸入的復(fù)位信號延續(xù)兩個(gè)機(jī)器周期以上的高電平時(shí)即為有效,用以完成單片機(jī)的復(fù)位初始化操作;當(dāng)單片機(jī)掉電時(shí),此引腳上可接備用電源,由VPD向片內(nèi)RAM提供備用電源,以保持片內(nèi)RAM中的數(shù)據(jù)不丟失。

ALE/PROG:地址鎖存控制信號。在系統(tǒng)擴(kuò)展時(shí),ALE用于控制把P0口輸出的低8位地址鎖存起來,以實(shí)現(xiàn)低位地址和數(shù)據(jù)的隔離。此外,由于ALE是以晶振1/6的固定頻率輸出的正脈沖,因此,可作為外部時(shí)鐘或外部定時(shí)脈沖使用。

PSEN:片外程序存儲(chǔ)器讀選通信號輸出端。

EA/VPP:訪問程序存儲(chǔ)控制信號。當(dāng)EA信號為低電平時(shí),對ROM的讀操作限定在外部程序存儲(chǔ)器;當(dāng)EA信號為高電平時(shí),對ROM的讀操作是從內(nèi)部程序存儲(chǔ)器開始,并可延至外部程序存儲(chǔ)器。

              (4)I/O引腳

P0.0 ~ P0.7 :P0口8位雙向口線;P1.0 ~ P1.7 :P1口8位雙向口線;

P2.0 ~ P2.7 :P2口8位雙向口線;P3.0 ~ P3.7 :P3口8位雙向口線。

P3口線的第二功能。P3的8條口線都定義有第二功能,詳見表1。

表1  P3口各引腳與第二功能表

引腳

第二功能

信號名稱

P3.0

RXD

串行數(shù)據(jù)接收

P3.1

TXD

串行數(shù)據(jù)發(fā)送

P3.2

INT0

外部中斷0申請

P3.3

INT1

外部中斷1申請

P3.4

T0

定時(shí)/計(jì)數(shù)器0的外部輸入

P3.5

T1

定時(shí)/計(jì)數(shù)器1的外部輸入

P3.6

WR

外部RAM寫選通

P3.7

RD

外部RAM讀選通

以上把8051單片機(jī)的全部信號引腳分別以第一功能和第二功能的形式列出。對于各種型號的芯片,其引腳的第一功能信號是相同的,所不同的只在引腳的第二功能信號。對于9、30和31三個(gè)引腳,由于第一功能信號與第二功能信號是單片機(jī)在不同工作方式下的信號,因此不會(huì)發(fā)生使用上的矛盾。但是P3口的情況卻有所不同,它的第二功能信號都是單片機(jī)的重要控制信號。因此,在實(shí)際使用時(shí),都是先按需要選用第二功能信號,剩下的才以第一功能的身份作數(shù)據(jù)位的輸入/輸出使用。

如圖4所示,本設(shè)計(jì)中單片機(jī)資源的分配情況如下:

(1)單片機(jī)使用外部電路來提供時(shí)鐘脈沖。引腳XTAL1和XTAL2之間接12MHz的石英晶體,使單片機(jī)的一個(gè)機(jī)器周期為1us。

(2)P0口與DAC0832的DI0-DI7數(shù)據(jù)輸入口相連;P1口與LCD液晶顯示數(shù)據(jù)輸入口相連;P2口的P2^0-P2^4分別與5個(gè)獨(dú)立按鍵相連;P3部分口與LCD液晶顯示控制信號接口相連。

圖4  單片機(jī)控制模塊

2.2.2 數(shù)模轉(zhuǎn)換電路

數(shù)模轉(zhuǎn)換電路是本設(shè)計(jì)的關(guān)鍵電路,它決定著將數(shù)字信號轉(zhuǎn)變?yōu)槟M信號,從而得到各種所需要的波形。

1. 數(shù)模轉(zhuǎn)換器的工作原理

數(shù)模轉(zhuǎn)換器可將數(shù)字量信號轉(zhuǎn)換成與此數(shù)值成正比的模擬量信號。需要轉(zhuǎn)換的數(shù)字量由一個(gè)二進(jìn)制數(shù)字表示,每位二進(jìn)制數(shù)字都有一定的權(quán),在轉(zhuǎn)換中,應(yīng)將二進(jìn)制數(shù)的每一位按照權(quán)的大小轉(zhuǎn)換成相應(yīng)的模擬量輸出分量,然后將各個(gè)輸出分量疊加,總和就是與數(shù)字量成正比的模擬量數(shù)值。

上述的D/A轉(zhuǎn)換,常用如圖5所示的倒T形解碼網(wǎng)絡(luò)加以實(shí)現(xiàn)。

                                                                                   圖5  倒T形電阻網(wǎng)絡(luò)D/A轉(zhuǎn)換器

電路設(shè)計(jì)如圖5所示,包括由R-2R組成的電阻網(wǎng)絡(luò)、模擬電子開關(guān)和集成運(yùn)算放大器。

對于電阻網(wǎng)絡(luò),無論從哪個(gè)R-2R節(jié)點(diǎn)看,等效電阻都是R,因此,從參考電壓端輸入的電流為:  IR=VREF/R

根據(jù)分流公式,各支路電流為:

I7=I/21I6 =I/22I5 =I/23I4 =I/24I3 =I/25I2 =I/26I1 =I/27I0 =I/28

于是,經(jīng)過運(yùn)算放大器輸出的模擬電壓VO為:

VO = - RF∑Ii= -Rfb VREF/R×28(D7×27 +D6×26 +D5×25+

D4×24+D3×23+D2×22+D1×21+D0×20)

其中VREF是進(jìn)行D/A轉(zhuǎn)換的系統(tǒng)提供的參考電壓,Rfb為集成運(yùn)算放大器的反饋電阻,D7 ~ D0取值為0或1,0表示切換開關(guān)與地相連,1表示與參考電壓相連。通過上述電路,即完成了二進(jìn)制數(shù)字信號到模擬電壓信號的轉(zhuǎn)換。

2.?dāng)?shù)模轉(zhuǎn)換器的主要技術(shù)指標(biāo)

  • 分辨率

分辨率指輸入給D/A轉(zhuǎn)換器的單位數(shù)字量引起的模擬量輸出的變化,通常定義為輸出滿刻度值與2n之比(n為D/A轉(zhuǎn)換器的二進(jìn)制位數(shù))。顯然,二進(jìn)制位數(shù)越多,分辨率越高,即D/A轉(zhuǎn)換器對輸入量變化的敏感程度越高。例如,8位的D/A轉(zhuǎn)換器,若滿量程輸出為10V,根據(jù)分辨率定義,則分辨率為10V/2n,分辨率為10V/256=39.1mV,即輸入的二進(jìn)制最低位的變化可引起輸出的模擬電壓變化39.1mV,該值占滿量程的0.391%,常用1LSB表示。使用時(shí),應(yīng)根據(jù)對D/A轉(zhuǎn)換器分辨率的需要來選定D/A轉(zhuǎn)換器的位數(shù)。

  • 相對精度

相對精度是指在滿刻度已經(jīng)校準(zhǔn)的前提下,在整個(gè)刻度范圍內(nèi),對應(yīng)于任一數(shù)碼的模擬量輸出與它的理論值之差。通常用偏差幾個(gè)LSB來表示。

  • 建立時(shí)間

建立時(shí)間是描述D/A轉(zhuǎn)換器轉(zhuǎn)換快慢的一個(gè)參數(shù),用于表明轉(zhuǎn)換時(shí)間或轉(zhuǎn)換速度。其值為從輸入數(shù)字量到輸出達(dá)到總值誤差±(1/2)LSB(最低有效位)時(shí)所需的時(shí)間。電流輸出的轉(zhuǎn)換時(shí)間較短,而電壓輸出的轉(zhuǎn)換器,由于要加上完成I-V轉(zhuǎn)換的運(yùn)算放大器的延遲時(shí)間,因此轉(zhuǎn)換時(shí)間要長一些?焖貲/A轉(zhuǎn)換器的轉(zhuǎn)換時(shí)間可控制在1us以下。

  • 線性度

通常用非線性誤差的大小表示D/A轉(zhuǎn)換器的線性度,輸入輸出特性的偏差與滿刻度輸出之比的百分?jǐn)?shù)表示非線性誤差。一定溫度下的最大非線性誤差一般為0.01%~0.03%。

3. DAC0832數(shù)模轉(zhuǎn)換芯片主要特性與結(jié)構(gòu)

DAC0832系列為美國國家半導(dǎo)體公司生產(chǎn)的具有2個(gè)數(shù)據(jù)寄存器的8位分辨率的D/A轉(zhuǎn)換芯片。此芯片與微處理器完全兼容,并且價(jià)格低廉,接口簡單,轉(zhuǎn)換控制容易,在單片機(jī)應(yīng)用系統(tǒng)中得到了廣泛的應(yīng)用。

1.DAC0832的主要特性

  • 分辨率為8位;
  • 轉(zhuǎn)換時(shí)間為1us;
  • 可單緩沖、雙緩沖或者直接數(shù)字轉(zhuǎn)換;
  • 只需在滿量程下調(diào)整其線性度;
  • 邏輯電平輸入與TTL兼容;
  • 單一電源供電(+5V+15V);
  • 基準(zhǔn)電壓的范圍為±10V。

2.DAC0832的內(nèi)部結(jié)構(gòu)

DAC0832的內(nèi)部結(jié)構(gòu)框圖如圖6所示。它由8位輸入鎖存器、8位DAC寄存器、8位D/A轉(zhuǎn)換器及轉(zhuǎn)換控制電路構(gòu)成,通過兩個(gè)輸入寄存器構(gòu)成兩級數(shù)據(jù)輸入鎖存。

                                                                                                  圖 6   DAC0832內(nèi)部邏輯框圖

              使用時(shí),數(shù)據(jù)輸入可以采用兩級鎖存(雙鎖存)、單級鎖存(一級鎖存,一級直通方式)或直接輸入(兩級直通)形式。上圖中,2個(gè)與門電路組成寄存器輸出控制邏輯電路,該邏輯電路的功能是進(jìn)行數(shù)據(jù)鎖存控制。

3.DAC0832的引腳功能

              DI0~DI7:8位數(shù)據(jù)輸入線。

              :片選信號輸入,低電平有效。

              ILE:數(shù)據(jù)鎖存允許控制信號,高電平有效。

1:輸入寄存器寫選通輸入信號,低

平有效。                                                                                                                                                                        圖 7  DAC0832的引腳                                            

              2:DAC寄存器寫選通輸入信號,低電平有效。

              :數(shù)據(jù)傳送控制信號,低電平有效。上述兩個(gè)信號控制DAC寄存器是否為數(shù)據(jù)直通方式。當(dāng)2=0和=0時(shí),為DAC寄存器直通方式;當(dāng)2=1或=1時(shí),為DAC寄存器鎖存方式。

              IOUT1、IOUT2:電流輸出,IOUT1+IOUT2=常數(shù)。

Rfb:反饋電阻輸入端。內(nèi)部接反饋電阻,外部通過該引腳接運(yùn)放輸出端。為了取得電壓輸出,需要在輸出端接運(yùn)算放大器,Rfb即為運(yùn)算放大器的反饋電阻端。

              Vref:基準(zhǔn)電壓,其值為-10V~+10V。

              AGND:模擬信號地。

              DGND:數(shù)字信號地,為工作電源地和數(shù)字邏輯地,可在基準(zhǔn)電源處進(jìn)行單點(diǎn)共地。

              VCC:電源輸入端,其值為+5V~+15V。

4.DAC0832芯片與單片機(jī)的接口

DAC0832根據(jù)控制信號的接法可分為三種工作方式:直通方式、單緩沖方式、雙緩沖方式。

  • 單緩沖方式

此時(shí)輸入鎖存器和DAC寄存器相應(yīng)的控制信號引腳分別連在一起,使數(shù)據(jù)直接寫入DAC寄存器,立即進(jìn)行D/A轉(zhuǎn)換(這種情況下,輸入鎖存器不起鎖存作用)。此方式適用于只有一路模擬量輸出,或有幾路模擬量輸出但是并不要求同步的系統(tǒng)。            

2. 雙緩沖方式

對于多路D/A轉(zhuǎn)換輸出,如果要求同步進(jìn)行,可以采用雙緩沖同步方式。DAC0832工作于雙緩沖工作方式時(shí),數(shù)字量的輸入鎖存和D/A轉(zhuǎn)換是分兩步完成的。首先CPU的數(shù)據(jù)總線分時(shí)向各路D/A轉(zhuǎn)換器輸入要轉(zhuǎn)換的數(shù)字量,并將其鎖存在各自的輸入鎖存器中,然后CPU對所有的DAC發(fā)出控制信號,使各個(gè)DAC輸入鎖存器中的數(shù)據(jù)打入DAC寄存器,實(shí)現(xiàn)同步轉(zhuǎn)換輸出。

              3. 直通工作方式

當(dāng)DAC0832芯片的片選信號、寫信號1、2及傳送控制信號的引腳全部接地,允許輸入鎖存信號ILE引腳+5V時(shí),DAC0832芯片就處于直通工作方式,數(shù)字量一旦輸入,就直接進(jìn)入DAC寄存器,進(jìn)行D/A轉(zhuǎn)換,從輸出端得到轉(zhuǎn)換的模擬量。

本設(shè)計(jì)中,為了降低數(shù)模轉(zhuǎn)換建立的時(shí)間,數(shù)模轉(zhuǎn)換芯片DAC0832采用直通的工作方式。

2.2.3 電流/電壓轉(zhuǎn)換放大電路

由于從DAC0832轉(zhuǎn)換出來的模擬信號為電流信號,為了方便觀測輸出信號的特征,特將DAC0832輸出的信號經(jīng)過電流/電壓轉(zhuǎn)換放大電路轉(zhuǎn)變?yōu)殡妷盒盘枴1驹O(shè)計(jì)中使用的運(yùn)放為LM324。LM324運(yùn)算放大器是價(jià)格便宜的帶差動(dòng)輸入功能的四運(yùn)算放大器。其引腳圖如圖8所示。

   LM324的特點(diǎn):

1.短路保護(hù)輸出

2.真差動(dòng)輸入級            

3.可單電源工作:3V-32V

4.低偏置電流:最大100nA(LM324A)

5.每封裝含四個(gè)運(yùn)算放大器。

6.具有內(nèi)部補(bǔ)償?shù)墓δ堋?/font>

7.共模范圍擴(kuò)展到負(fù)電源

8.行業(yè)標(biāo)準(zhǔn)的引腳排列

9.輸入端具有靜電保護(hù)功能                   圖8  LM324引腳


DAC0832輸出信號經(jīng)運(yùn)放電路轉(zhuǎn)變?yōu)殡妷汉笥袃煞N輸出方式。一種為單極性輸出方式。此方式中,DAC0832通過使用一片LM324運(yùn)算放大器將從單片機(jī)輸入的數(shù)字量Din轉(zhuǎn)換為電壓輸出,其輸出電壓為Uout=Din/28 *(-VREF)。當(dāng)VREF=5V時(shí),Uout的輸出范圍為-5V~0V。另一種為雙極性輸出方式。本設(shè)計(jì)中采用雙極性輸出方式,如圖9所示。其雙極性輸出原理為:因?yàn)閁1為-5V~0V,根據(jù)電流環(huán)路定理有

即:Uout=-VREF-2U1

所以當(dāng)VREF=5V,而U1為-5V~ 0V輸出時(shí),Uout的輸出為-5~+5V,即實(shí)現(xiàn)了雙極性輸出。

圖9  DAC0832和兩片LM324實(shí)現(xiàn)雙極性輸出
3.2.4 液晶顯示電路

顯示模塊主要是用來顯示輸出信號的波形類型和頻率大小,本設(shè)計(jì)中以LM016L作為顯示器件。LM016L智能型顯示模塊是一種低功耗、低價(jià)值、低損耗的顯示器件,它不但可以顯示各式各樣的字符、漢字和圖形,同時(shí)具有可編程能力,且與單片機(jī)接口方便。

1引腳功能說明

LCD LM016L采用標(biāo)準(zhǔn)的14腳接口,各引腳接口說明如下:

第1腳:VSS為地電源。

第2腳:VDD接5V正電源。

第3腳:VEE為液晶顯示器對比度調(diào)整端,接正電源時(shí)對比度最弱,接地時(shí)對比度最高,對比度過高時(shí)會(huì)產(chǎn)生“鬼影”,使用時(shí)可以通過一個(gè)10K的電位器調(diào)整對比度。

第4腳:RS為寄存器選擇,高電平時(shí)選擇數(shù)據(jù)寄存器、低電平時(shí)選擇指令寄存器。

第5腳:R/W為讀寫信號線,高電平時(shí)進(jìn)行讀操作,低電平時(shí)進(jìn)行寫操作。當(dāng)RS和R/W共同為低電平時(shí)可以寫入指令或者顯示地址,當(dāng)RS為低電平R/W為高電平時(shí)可以讀忙信號,當(dāng)RS為高電平R/W為低電平時(shí)可以寫入數(shù)據(jù)。

第6腳:E端為使能端,當(dāng)E端由高電平跳變成低電平時(shí),液晶模塊執(zhí)行命令。

第7~14腳:D0~D7為8位雙向數(shù)據(jù)線。

2.基本操作時(shí)序表

讀寫操作時(shí)序如圖10和圖11所示。

圖10 讀操作時(shí)序

圖11  寫操作時(shí)序

3LCD LM016LRAM地址映射及標(biāo)準(zhǔn)字庫表

液晶顯示模塊是一個(gè)慢顯示器件,所以在執(zhí)行每條指令之前一定要確認(rèn)模塊的忙標(biāo)志為低電平,表示不忙,否則此指令失效。要顯示字符時(shí)要先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符,圖12是016的內(nèi)部顯示地址。

圖12  1602LCD內(nèi)部顯示地址

例如第二行第一個(gè)字符的地址是40H,那么是否直接寫入40H就可以將光標(biāo)定位在第二行第一個(gè)字符的位置呢?這樣不行,因?yàn)閷懭腼@示地址時(shí)要求最高位D7恒定為高電平1,所以實(shí)際寫入的數(shù)據(jù)應(yīng)該是01000000B(40H)+10000000B(80H)=11000000B(C0H)。

在對液晶模塊的初始化中要先設(shè)置其顯示模式,在液晶模塊顯示字符時(shí)光標(biāo)是自動(dòng)右移的,無需人工干預(yù)。每次輸入指令前都要判斷液晶模塊是否處于忙的狀態(tài)。

016液晶模塊內(nèi)部的字符發(fā)生存儲(chǔ)器(CGROM)已經(jīng)存儲(chǔ)了160個(gè)不同的點(diǎn)陣字符圖形,如圖13所示,這些字符有:阿拉伯?dāng)?shù)字、英文字母的大小寫、常用的符號、和日文假名等。每一個(gè)字符都有一個(gè)固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時(shí)模塊把地址41H中的點(diǎn)陣字符圖形顯示出來,我們就能看到字母“A”。

圖13 字符代碼與圖形對應(yīng)圖

4.液晶LM016L顯示電路圖

本設(shè)計(jì)中,液晶顯示電路與單片機(jī)的連接如圖14所示。

圖14 液晶顯示電路

2.2.5鍵盤電路

該子系統(tǒng)是5個(gè)獨(dú)立鍵盤和一個(gè)2輸入與門組成,其中與門輸出端連接單片機(jī)的P3.2口以便形成外部中斷。5個(gè)按鍵分別連接單片機(jī)的P2.0~P2.4口。2輸入與門一引腳與K1按鍵相連,另一引腳接高電平。當(dāng)K1按下時(shí),INT0為低電平,可知外部中斷到了,系統(tǒng)執(zhí)行中斷程序。當(dāng)K2~K5按鍵某一個(gè)按下時(shí),對應(yīng)的P2.1~P2.4口中某個(gè)為低電平,系統(tǒng)可以感知此按鍵按下,從而執(zhí)行相應(yīng)的程序。每個(gè)按鍵的功能如表2所示。

表2 按鍵功能表

按鍵

功能

屬性

K1

波形選擇

自動(dòng)復(fù)位

K2

頻率升高

自動(dòng)復(fù)位

K3

頻率降低

自動(dòng)復(fù)位

K4

占空比升高

自動(dòng)復(fù)位

K5

占空比降低

自動(dòng)復(fù)位

按鍵電路的電路圖如圖15所示。

圖15 按鍵電路圖
3 系統(tǒng)軟件設(shè)計(jì)

系統(tǒng)軟件主要是用來控制信號發(fā)生器系統(tǒng)按照設(shè)計(jì)的邏輯進(jìn)行運(yùn)行。在軟件設(shè)計(jì)上,根據(jù)功能分成了多個(gè)模塊編程,主要包括:主程序模塊、四種不同的波形產(chǎn)生模塊、按鍵處理模塊、外部中斷模塊、液晶顯示模塊等。

3.1 系統(tǒng)主程序流程框圖

系統(tǒng)主程序流程圖如圖16所示,源程序見附件。

圖16  系統(tǒng)主程序流程圖

3.2 信號產(chǎn)生子程序

本系統(tǒng)采用編程的方法,來輸出四種不同的波形即正弦波、矩形波、三角波、鋸齒波。各種波形的產(chǎn)生方法如下。

3.2.1 正弦波發(fā)生子程序

正弦波的產(chǎn)生比較特殊,它不能由單片機(jī)直接產(chǎn)生,只能由如圖17所示的階梯波來向正弦波逼近。很顯然,在一個(gè)周期內(nèi)階梯波的階梯數(shù)目越多,單片機(jī)輸出的波形也就越接近正弦波。

圖17 正弦波信號的產(chǎn)生

先假定正弦波的振幅是2.56 V,則波谷對應(yīng)的數(shù)字量為最小值00H,波峰對應(yīng)的數(shù)字量為最大值FFH。將正弦波的第一個(gè)周期的波形按角度均分為若干等份,并計(jì)算出各點(diǎn)對應(yīng)的電壓值,電壓值計(jì)算方法:Vx=2.5·(1+sinθ),因?yàn)?0H~FFH對應(yīng)的數(shù)字量為0~255,所以根據(jù)算出的電壓就可直接寫出各點(diǎn)所對應(yīng)的數(shù)字量。單片機(jī)將一個(gè)周期的數(shù)字量存入一定的存儲(chǔ)區(qū)域中,然后依次循環(huán)取出這些數(shù)字量,并送D/A電路轉(zhuǎn)換成階梯波,即近似的正弦波輸出。圖18為正弦波產(chǎn)生的流程圖。

圖18 正弦波產(chǎn)生的流程圖
3.2.2 矩形波發(fā)生子程序

如圖19所示,矩形波的實(shí)現(xiàn)比較簡單。首先定義一個(gè)無符號字符型變量i=0,使自變量i不斷的自動(dòng)加1,若i的值小于squa_num,將P0口賦值為0xFF;若i的值大于squa_num,則將P0口賦值為0x00。當(dāng)i自加到256后又自動(dòng)變?yōu)?,以此循環(huán),即可得到矩形波。當(dāng)squa_num=128時(shí),此時(shí)輸出的為方波。調(diào)節(jié)squa_num的大小,即可實(shí)現(xiàn)矩形波占空比的調(diào)節(jié);調(diào)節(jié)延時(shí)時(shí)間的大小,即可實(shí)現(xiàn)矩形波頻率的改變。

圖19 矩形波產(chǎn)生流程圖
3.2.3 三角波發(fā)生子程序

三角波中的斜線用一個(gè)個(gè)小臺(tái)階來逼近,當(dāng)臺(tái)階間隔很小時(shí),波形基本上近似一直線。首先定義一個(gè)無符號字符型變量i=0,使自變量i不斷的自動(dòng)加1,若i的值小于128,將P0口賦值為i;若i的值大于128,則將P0口賦值為256-i。當(dāng)i自加到256后又自動(dòng)變?yōu)?,以此循環(huán),從而P0口實(shí)現(xiàn)了周期性的數(shù)字量變換,在經(jīng)過數(shù)模轉(zhuǎn)換后轉(zhuǎn)變成模擬信號,經(jīng)運(yùn)算放大電路后就得到了周期性的三角波。三角波產(chǎn)生流程圖如圖20所示。

圖20 三角波發(fā)生流程圖
3.2.4 鋸齒波發(fā)生子程序

鋸齒波的實(shí)現(xiàn)過程與三角波類似,也是定義一個(gè)變量i=0,并使P0=i,自變量i不斷的自動(dòng)加1,直到加到255,然后i又可以自動(dòng)歸為0,再不斷的重復(fù)上過程。在此過程中,P0口的值也隨著i一樣變化,經(jīng)數(shù)模轉(zhuǎn)換DAC0832后,周期性逐一變化的數(shù)字量就轉(zhuǎn)換為鋸齒波輸出了。通過調(diào)節(jié)P0口每相鄰兩個(gè)值之間的延遲時(shí)間,就可以改變鋸齒波的頻率。圖21為鋸齒波發(fā)生流程圖。

圖21 鋸齒波發(fā)生流程圖
3.3按鍵處理子程序

在本設(shè)計(jì)中,主要是通過按鍵來調(diào)節(jié)輸出波形的類型、頻率的大小及矩形波的占空比,采用程序控制掃描方式,時(shí)刻監(jiān)視著有無按鍵按下。為了能夠更準(zhǔn)確的判斷按鍵的情況,一旦有按鍵按下時(shí),先延時(shí)去除按鍵的抖動(dòng),再判斷是哪個(gè)按鍵按下,從而單片機(jī)對應(yīng)的執(zhí)行相應(yīng)的程序。圖22為按鍵處理流程圖。

圖22 按鍵處理流程圖
3.4液晶顯示子程序

LCD LM016L的顯示函數(shù)很簡單,只要嚴(yán)格按照其時(shí)序圖操作,并結(jié)合其相關(guān)指令集,寫好LCD的初始化程序,清屏程序,寫指令程序,寫數(shù)據(jù)程序,讀數(shù)據(jù)程序等一系列驅(qū)動(dòng)程序,即可完成LCD的所有顯示需要。在本設(shè)計(jì)中,由于需要顯示的內(nèi)容比較多,且有些需要重復(fù)顯示,有些只要顯示一次,故只畫出液晶顯示的基本流程,如圖23所示。

圖23 液晶顯示流程圖
3.5 INT0中斷子程序

中斷子程序是用來控制輸出波形的選擇及將輸出波形的類型在LCD液晶顯示屏上顯示出來。當(dāng)波形選擇按鍵K1按下時(shí),進(jìn)入中斷程序中,此時(shí)波形選擇標(biāo)識(shí)WaveChoice加1,LCD液晶顯示屏上顯示出相應(yīng)的波形類型。中斷結(jié)束后,主程序中根據(jù)WaveChoice的值輸出相應(yīng)的波形。圖24為INT0中斷流程圖。

圖24 INT0中斷流程圖

4 系統(tǒng)調(diào)試4.1 系統(tǒng)調(diào)試過程

1.編譯、連接項(xiàng)目,形成目標(biāo)文件

打開Keil新建工程文件,然后添加源程序文件,保存時(shí)把文件后綴名改成“.c”,再直接導(dǎo)入新建的工程中。

把源程序全部錄入后,先粗略的檢查一遍,主要改正明顯的各種錯(cuò)誤,這樣可以減少之后的修改工作量。接著Options for Target “Target 1”,點(diǎn)擊Output ,勾選Create Hex 那個(gè)選項(xiàng),生成可執(zhí)行的文件。然后點(diǎn)擊Project菜單下的Built Target命令然后再進(jìn)行編譯、連接,形成目標(biāo)文件。編譯、連接用Project菜單下的Built Target命令(或快捷鍵F7),也可以直接點(diǎn)擊工具欄中相對應(yīng)的圖標(biāo)。

編譯、連接時(shí),如果程序存在語法有錯(cuò),則不會(huì)通過編譯,并在下面的信息窗口給出相應(yīng)的出錯(cuò)提示信息,其中錯(cuò)誤是一定得改正的,警告可以忽略。雙擊下面顯示錯(cuò)誤信息的那一行,可以直接定位錯(cuò)誤所在的行,用戶可以方便的對程序進(jìn)行修改。修改后再編譯、連接,繼續(xù)進(jìn)行調(diào)試,這個(gè)過程可能會(huì)重復(fù)多次。如果沒有任何語法上的錯(cuò)誤,則編譯、連接成功,并且信息窗口給出提示信息。

2.運(yùn)行調(diào)試

在Proteus軟件中先從元件庫中加載要使用的那些元件,然后把元件放在圖紙上一個(gè)一個(gè)的接線,盡量不讓線交錯(cuò),便于查看、分析,有必要時(shí),使用接線標(biāo)號法。完成所有元器件的接線后,在單片機(jī)上右擊選Edit Properties,在Program file 那一行右側(cè)點(diǎn)擊,然后選擇前面生成的以“.hex”為后綴名的文件,為單片機(jī)AT89C51添加可執(zhí)行文件。然后點(diǎn)擊左下角的相關(guān)按鍵,開始進(jìn)行仿真。

4.2 調(diào)試中的問題及解決方法

在設(shè)計(jì)方案確定后,為了更好的調(diào)試,可以先分別對不同模塊進(jìn)行調(diào)試,最后在進(jìn)行整體調(diào)試。在整個(gè)調(diào)試的過程中,遇到了不少的問題,經(jīng)自己查閱資料,并向老師、同學(xué)請教后,這些問題基本已解決。調(diào)試中遇到的問題及解決方法如下:

(1) 在調(diào)試LCD顯示過程中,當(dāng)波形選擇按鍵變化時(shí),對應(yīng)的LCD上顯示的波形類型也跟著變化,達(dá)到設(shè)計(jì)的目的。但由于不同波形類型的顯示字符長度不一樣,由字符長的向字符短的跳轉(zhuǎn)時(shí),字符長的多余的幾位還在顯示,使顯示結(jié)果出現(xiàn)錯(cuò)誤。

解決方法:將四種需要顯示的波形類型的字符串長度設(shè)定為一樣,字母不足的用空格來補(bǔ)充,這樣就達(dá)到了顯示所需效果。

(2) 在調(diào)試波形產(chǎn)生過程中,波形選擇按鍵按下時(shí),沒有波形輸出或只輸出一種波形。

解決方法:若無波形輸出,則要先檢查硬件原理圖是否連接好,再檢查程序是否出現(xiàn)問題。若僅有一種波形輸出,則要檢查程序中是否出現(xiàn)了死循環(huán),還應(yīng)檢查按鍵控制程序是否符合邏輯要求。

(3) 當(dāng)個(gè)個(gè)模塊的功能都可以實(shí)現(xiàn)時(shí),就可以進(jìn)行總體的調(diào)試。在總體的調(diào)試中,發(fā)現(xiàn)波形選擇按鍵按下時(shí),液晶顯示波形類型變化和輸出波形的變化并不能同時(shí)實(shí)現(xiàn)。

解決方法:當(dāng)波形選擇按鍵按下時(shí),液晶上的顯示只要做一次就可以,而信號波形的輸出則是連續(xù)著的。所以使用外部中斷INT0,當(dāng)有按鍵按下時(shí),先響應(yīng)中斷程序,顯示輸出波形的類型,然后再回到主程序中,輸出對應(yīng)的波形。

(4) 系統(tǒng)使用的是控制延時(shí)的方法來改變輸出信號的頻率,故頻率值的大小不好計(jì)算。

解決方法:設(shè)定不同的延時(shí)時(shí)間,從示波器顯示的輸出波形來計(jì)算其對應(yīng)的頻率,并記錄下來。再根據(jù)每條指令大約的執(zhí)行時(shí)間,來粗略的估計(jì)出輸出信號的頻率與延時(shí)時(shí)間的函數(shù)關(guān)系。當(dāng)然,這種方法所測得的頻率與實(shí)際頻率的誤差還是很大的,此問題并沒得到完美的解決。

4.3 系統(tǒng)仿真結(jié)果

經(jīng)以上調(diào)試,確認(rèn)程序沒有問題時(shí),加載到Proteus軟件中進(jìn)行仿真,所得仿真結(jié)果如下。

(1)剛開始運(yùn)行程序,沒有按鍵操作時(shí),仿真結(jié)果如圖25所示。

圖25 仿真初始化結(jié)果
(2)當(dāng)K1鍵按下進(jìn)行波形四種波形選擇時(shí),每種波形的仿真結(jié)果如下。
圖26 正弦波

圖27 方波

圖28 三角波

圖29 鋸齒波

(3)波形為正弦波,K2鍵按下時(shí),輸出波形的頻率增大仿真如圖30 所示。

圖30 正弦波頻率增加仿真


(4)當(dāng)波形為矩形波且K4鍵按下后,矩形波的占空比增加。其仿真結(jié)果如圖31所示。

圖31 矩形波占空比增加仿真
5 結(jié)論

經(jīng)過兩個(gè)月的努力,終于完成了信號發(fā)生器的設(shè)計(jì),總結(jié)兩個(gè)月以來的工作,主要有以下幾個(gè)方面:

(1)通過查閱大量資料使自己對信號發(fā)生器的研究現(xiàn)狀、原理、工作方式等的基本概念及技術(shù)發(fā)展有了更好的理解。

(2)針對設(shè)計(jì)的任務(wù)和要求,確定信號發(fā)生器的設(shè)計(jì)方案,并逐步來實(shí)現(xiàn)。

(3)本系統(tǒng)使用了單片機(jī)作為主控制器,直接由軟件產(chǎn)生不同波形信號的輸出,因此在如何編寫程序方面下了很大的功夫,也收獲了很多知識(shí)。

(4)在Keil中編寫仿真程序,在Proteus中繪制硬件仿真圖,并實(shí)現(xiàn)聯(lián)調(diào)仿真。從仿真的結(jié)果來看,基本完成了設(shè)計(jì)的要求。

在這兩個(gè)月的工作中,我也學(xué)習(xí)到了很多東西。首先,經(jīng)過此次設(shè)計(jì)學(xué)會(huì)了很多關(guān)于電子方面的軟件:如Proteus、Keil51等。了解到了一個(gè)模型從項(xiàng)目選擇、方案選擇和論證電路設(shè)計(jì)、元器件選擇等到軟硬件的設(shè)計(jì)及實(shí)現(xiàn),再到最終的整機(jī)測試和調(diào)試整個(gè)工作過程,為以后工作打下了堅(jiān)實(shí)的基礎(chǔ)。其次,經(jīng)過這次畢業(yè)設(shè)計(jì),使我深刻地認(rèn)識(shí)到學(xué)好專業(yè)知識(shí)的重要性,也理解了理論聯(lián)系實(shí)際的含義,提升了我對電子設(shè)計(jì)和制作的興趣。

參考文獻(xiàn)

[1] 彭偉.單片機(jī)C語言程序設(shè)計(jì)實(shí)訓(xùn)100例——基于8051+Proteus仿真[M].電子工業(yè)出版社,2009

[2] 王為青,程國剛.單片機(jī)Keil Cx51應(yīng)用開發(fā)技術(shù)[M].北京:人民郵電出版社,2007

[3] 龔云新.單片機(jī)C語言開發(fā)技術(shù)[M].北京:清華大學(xué)出版社,2006

[4] 于永,戴佳.51單片機(jī)C語言常用模塊與綜合系統(tǒng)設(shè)計(jì)實(shí)例講解[M].北京:電子工業(yè)出版社,2007

[5] 蔡美琴等.MCS-51系列單片機(jī)系統(tǒng)極其應(yīng)用[M].北京:高等教育出版社,2004

[6] 林伸茂.8051單片機(jī)徹底研究實(shí)習(xí)篇[M].北京:人民郵電出版社,2004

[7] 胡學(xué)海.單片機(jī)原理極其應(yīng)用系統(tǒng)設(shè)計(jì)[M].北京:電子工業(yè)出版社,2005  

[8] 韓志軍.單片機(jī)應(yīng)用系統(tǒng)設(shè)計(jì)[M].北京:機(jī)械工業(yè)出版社,2005

[9] 舒懷林.單片機(jī)原理與接口技術(shù)[M].武漢:華中科技大學(xué)出版社,2001

[10] 徐愛軍,彭秀華.8051單片機(jī)實(shí)踐教程[M].北京:電子工業(yè)出版社,2005


評分

參與人數(shù) 6黑幣 +25 收起 理由
chrccc + 5
yy921311266 + 5 很給力!
吳明山 + 5 很給力!
削刻陶杯 + 3 很給力!
2256611327 + 4 贊一個(gè)!
匆匆歲月 + 3 回帖助人的獎(jiǎng)勵(lì)!

查看全部評分

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:115446 發(fā)表于 2016-4-22 15:00 來自手機(jī) | 只看該作者
這是函數(shù)發(fā)生器
回復(fù)

使用道具 舉報(bào)

板凳
ID:117153 發(fā)表于 2016-4-27 22:01 | 只看該作者
不錯(cuò)不錯(cuò)
回復(fù)

使用道具 舉報(bào)

地板
ID:117509 發(fā)表于 2016-4-29 13:06 | 只看該作者
正在研究這方面的制作,下載下來參考一下。
回復(fù)

使用道具 舉報(bào)

5#
ID:124550 發(fā)表于 2016-6-1 21:34 | 只看該作者
很詳細(xì)的帖子,棒!
回復(fù)

使用道具 舉報(bào)

6#
ID:125404 發(fā)表于 2016-6-6 11:34 | 只看該作者
謝謝樓主,非常感謝
回復(fù)

使用道具 舉報(bào)

7#
ID:126108 發(fā)表于 2016-6-10 16:12 | 只看該作者
謝謝樓主謝謝樓主謝謝樓主謝謝樓主
回復(fù)

使用道具 舉報(bào)

8#
ID:127613 發(fā)表于 2016-6-21 23:39 | 只看該作者
請問誰下載了這個(gè)文件的,我怎么下不下來呀,求賜教
回復(fù)

使用道具 舉報(bào)

9#
ID:129186 發(fā)表于 2016-7-4 16:45 | 只看該作者
非常感謝
回復(fù)

使用道具 舉報(bào)

10#
ID:109819 發(fā)表于 2016-9-29 19:44 | 只看該作者
有沒有聯(lián)系方式啊,為什么我運(yùn)行顯示邏輯錯(cuò)誤啊  LOGIC connection detected
回復(fù)

使用道具 舉報(bào)

11#
ID:145318 發(fā)表于 2016-10-31 13:22 | 只看該作者
很好,學(xué)習(xí)到了很多
回復(fù)

使用道具 舉報(bào)

12#
ID:121114 發(fā)表于 2016-11-2 18:31 | 只看該作者
函數(shù)發(fā)生器??有什么用??
不管  下載看看!好高檔的樣子!善哉一個(gè)哈哈
回復(fù)

使用道具 舉報(bào)

13#
ID:121114 發(fā)表于 2016-11-2 18:35 | 只看該作者
程序 50多個(gè)錯(cuò)誤????
我還是找個(gè)簡單的吧!
回復(fù)

使用道具 舉報(bào)

14#
ID:150230 發(fā)表于 2016-11-25 22:06 | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

15#
ID:156158 發(fā)表于 2016-12-20 10:35 | 只看該作者
正在研究這方面的制作,下載下來參考一下。
回復(fù)

使用道具 舉報(bào)

16#
ID:156343 發(fā)表于 2016-12-20 20:29 | 只看該作者
啊啊啊  需要這個(gè)呀
回復(fù)

使用道具 舉報(bào)

17#
ID:156343 發(fā)表于 2016-12-20 20:34 | 只看該作者
需要需要
回復(fù)

使用道具 舉報(bào)

18#
ID:156480 發(fā)表于 2016-12-21 11:15 | 只看該作者
好難啊,一臉蒙比
回復(fù)

使用道具 舉報(bào)

19#
ID:156853 發(fā)表于 2016-12-22 14:54 | 只看該作者
好難啊 下載下來看看
回復(fù)

使用道具 舉報(bào)

20#
ID:144557 發(fā)表于 2016-12-30 13:40 | 只看該作者
這個(gè)也沒有下載的地方喲
回復(fù)

使用道具 舉報(bào)

21#
ID:167165 發(fā)表于 2017-2-28 16:20 | 只看該作者
很厲害,頂一頂樓主
回復(fù)

使用道具 舉報(bào)

22#
ID:186199 發(fā)表于 2017-4-6 10:30 | 只看該作者
謝謝樓主分享 很詳細(xì)
回復(fù)

使用道具 舉報(bào)

23#
ID:177119 發(fā)表于 2017-4-18 16:25 | 只看該作者
樓主  我是新手  想提高正弦波頻率   不知道從這個(gè)程序中可以從哪些方面改進(jìn)   
回復(fù)

使用道具 舉報(bào)

24#
ID:195456 發(fā)表于 2017-5-3 17:27 | 只看該作者
好人一個(gè)
回復(fù)

使用道具 舉報(bào)

25#
ID:200339 發(fā)表于 2017-5-13 16:34 | 只看該作者
proteus仿真的51單片機(jī)信號發(fā)生器 課程設(shè)計(jì)   這個(gè)設(shè)計(jì)感覺不錯(cuò)呦。
回復(fù)

使用道具 舉報(bào)

26#
ID:201904 發(fā)表于 2017-5-17 18:41 | 只看該作者
感謝樓主分享~
回復(fù)

使用道具 舉報(bào)

27#
ID:202514 發(fā)表于 2017-5-19 13:22 | 只看該作者
樓主不錯(cuò),很喜歡
回復(fù)

使用道具 舉報(bào)

28#
ID:209683 發(fā)表于 2017-6-11 21:32 | 只看該作者
如果把占空比改成幅度可調(diào),那該怎么改線路呢?
回復(fù)

使用道具 舉報(bào)

29#
ID:210067 發(fā)表于 2017-6-13 09:53 | 只看該作者
請問怎么在這個(gè)基礎(chǔ)上改頻率步長
回復(fù)

使用道具 舉報(bào)

30#
ID:58215 發(fā)表于 2017-6-13 10:46 | 只看該作者
樓主寫的不錯(cuò),支持。
回復(fù)

使用道具 舉報(bào)

31#
ID:216554 發(fā)表于 2017-7-3 16:01 | 只看該作者
樓主寫的很不錯(cuò),對我很有幫助
回復(fù)

使用道具 舉報(bào)

32#
ID:217944 發(fā)表于 2017-7-7 16:52 | 只看該作者
謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

33#
ID:210959 發(fā)表于 2017-9-5 08:58 | 只看該作者
樓主寫得太好了,學(xué)習(xí)了。
回復(fù)

使用道具 舉報(bào)

34#
ID:238027 發(fā)表于 2017-10-9 15:39 | 只看該作者
很感謝,有用
回復(fù)

使用道具 舉報(bào)

35#
ID:241982 發(fā)表于 2017-10-23 03:29 來自手機(jī) | 只看該作者
直得學(xué)習(xí),
回復(fù)

使用道具 舉報(bào)

36#
ID:246786 發(fā)表于 2017-11-7 23:35 | 只看該作者
帖子很好,正在研究
回復(fù)

使用道具 舉報(bào)

37#
ID:247166 發(fā)表于 2017-11-8 00:23 | 只看該作者
直得學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

38#
ID:247636 發(fā)表于 2017-11-10 09:17 來自手機(jī) | 只看該作者
下載下來看看,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

39#
ID:263271 發(fā)表于 2017-12-18 20:22 | 只看該作者
為什么我運(yùn)行程序出現(xiàn)了錯(cuò)誤啊
回復(fù)

使用道具 舉報(bào)

40#
ID:273662 發(fā)表于 2018-1-9 11:30 | 只看該作者
值得學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表