找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

51單片機(jī)的多波形發(fā)生器設(shè)計(jì)(PCF8591)源程序 正弦波、三角波、鋸齒波、方波、梯形波

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:641714 發(fā)表于 2019-12-23 15:55 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
多波形發(fā)生器基本功能:
1、可產(chǎn)生多種波形,如正弦波、三角波、鋸齒波、方波、梯形波等;
2、各種波形可通過(guò)按鍵選擇;
3、可調(diào)節(jié)信號(hào)的頻率參數(shù)。

1方案論證與對(duì)比
1.1     方案1

利用STC89C52RC為硬件核心,STC89C52RC具有8KB ROM存儲(chǔ)空間,512字節(jié)數(shù)據(jù)存儲(chǔ)空間,帶有MCS-51系列單片機(jī)完全兼容,STC89C52RC可以通過(guò)串口下載。本次實(shí)驗(yàn)設(shè)計(jì)采用單片機(jī)的PCF8591硬件接口實(shí)現(xiàn)D/A數(shù)模轉(zhuǎn)換設(shè)計(jì)。PCF8591時(shí)一個(gè)單電源低功耗的8位CMOS數(shù)據(jù)采集器件,具有4路模擬輸入,1路模擬輸出和一個(gè)串行I2C總線接口用來(lái)與單片機(jī)通信,符合電路簡(jiǎn)單,方便查找錯(cuò)誤的設(shè)計(jì)理念。


2硬件電路設(shè)計(jì)

仔細(xì)分析課題后,并查找了相應(yīng)資料,所學(xué)單片機(jī)中有關(guān)矩陣按鍵、A/D模數(shù)和D/A數(shù)模轉(zhuǎn)換的有關(guān)知識(shí),設(shè)計(jì)出整體硬件原理框圖如圖1所示, 其中晶振通過(guò)自身振蕩為單片機(jī)系統(tǒng)提供基準(zhǔn)時(shí)鐘信號(hào),復(fù)位電路用于單片機(jī)復(fù)位,矩陣按鍵控制波形、頻率切換。

      

圖1 整體原理框圖

2.1 最小系統(tǒng)的設(shè)計(jì)

單片機(jī)最小系統(tǒng)的三要素就是電源、晶振和復(fù)位電路。

本設(shè)計(jì)中選用的STC89C52RC需要5V的供電系統(tǒng),將供電電路接在STC89C52RC的40和20引腳的位置上,40引腳接+5V,即VCC。20引腳接GND,即電源負(fù)極。

晶振為單片機(jī)系統(tǒng)提供基準(zhǔn)時(shí)鐘信號(hào)。STC89C52RC的18引腳和19引腳接一個(gè)11.0592MHz的晶振,外加兩個(gè)20pF的電容,電容用于幫助晶振起振,并維持晶振信號(hào)的穩(wěn)定。

單片機(jī)復(fù)位分為三種情況:上電復(fù)位、手動(dòng)復(fù)位和程序自動(dòng)復(fù)位。

上電復(fù)位即單片機(jī)上電后,單片機(jī)進(jìn)行一個(gè)內(nèi)部的初始化過(guò)程,保證單片機(jī)每次都從一個(gè)固定的相同的狀態(tài)開(kāi)始工作。手動(dòng)復(fù)位即人主動(dòng)去按下復(fù)位按鍵,讓程序重新初始化重新運(yùn)行。程序自動(dòng)復(fù)位即單片機(jī)遇到某些情況自動(dòng)復(fù)位到初始化的狀態(tài)。

具體電路設(shè)計(jì)參見(jiàn)下圖2 :


圖2 單片機(jī)最小系統(tǒng)


2.2PCF8591電路設(shè)計(jì)


圖3 PCF8591電路

其中引腳1、2、3、4是4路模擬輸入,引腳5、6、7是I2C總線的硬件地址,8 腳是數(shù) 字地 GND,9 腳和 10 腳是I2C總線的 SDA 和SCL。12腳是時(shí)鐘選擇引腳,如果接高電平表 示用外部時(shí)鐘輸入,接低電平則用內(nèi)部時(shí)鐘,我們本次設(shè)計(jì)電路用的是內(nèi)部時(shí)鐘,因此12腳直接接 GND,同時(shí) 11腳懸空。13腳是模擬地 AGND。14腳是基準(zhǔn)源,15腳是 DAC 的模擬輸出,16腳是供電電源 VCC。

在軟件編程過(guò)程中單片機(jī)對(duì)PCF8591進(jìn)行初始化,一共發(fā)送三個(gè)字節(jié)即可。第一個(gè)字節(jié),和 EEPROM 類似,是器件地址字節(jié),其中7位代表地址,1位代表讀寫(xiě)方向。地址高4位固定是0b1001,低三位是A2,A1,A0, 這三位我們電路上都接了GND,因此也就是0b000。

圖 4 PCF8591 地址字節(jié)
發(fā)送到 PCF8591 的第二個(gè)字節(jié)將被存儲(chǔ)在控制寄存器,用于控制 PCF8591 的功能。
圖 5  PCF8591 控制字節(jié)
控制字節(jié)的第6位是DA使能位,這一位置1表示DA輸出引腳使能,會(huì)產(chǎn)生模擬電壓輸出功能。
2.3矩陣按鍵電路的設(shè)計(jì)

通過(guò)高四位全部輸出低電平,低四位輸出高電平。當(dāng)接收到的數(shù)據(jù),低四位不全為高電平時(shí),說(shuō)明有按鍵按下,然后通過(guò)接收的數(shù)據(jù)值,判斷是哪一列有按鍵按下,然后再反過(guò)來(lái),高四位輸出高電平,低四位輸出低電平,然后根據(jù)接收到的高四位的值判斷是那一行有按鍵按下,從而能夠確定是哪一個(gè)按鍵按下了。電路如圖6示:



圖6 矩陣鍵盤(pán)電路


3系統(tǒng)軟件設(shè)計(jì)流程圖
3.1主程序工作流程

首先開(kāi)啟總中斷,讓中斷程序能夠正常運(yùn)行,配置T0定時(shí)1ms,初始化波形和頻率,進(jìn)入循環(huán)不斷掃描按鍵動(dòng)態(tài)在中斷中完成按鍵掃描并消抖,主程序調(diào)用按鍵動(dòng)作函數(shù)。當(dāng)檢測(cè)到鍵4按下第一次,顯示三角波;當(dāng)檢測(cè)鍵4按下第二次,顯示鋸齒波;當(dāng)檢測(cè)到鍵4按下第三次,顯示方波;當(dāng)檢測(cè)到鍵4按下第四次,顯示梯形波若無(wú)檢測(cè)到鍵按下,則輸出默認(rèn)正弦波;當(dāng)檢測(cè)到按下鍵8,調(diào)整波形頻率。主程序流程圖如圖7所示:   


                             圖7 主程序流程圖
3.2中斷子程序設(shè)計(jì)
3.2.1 T0定時(shí)器

中斷子程序中,通過(guò)定時(shí)器T0執(zhí)行矩陣按鍵掃描函數(shù)檢測(cè)是否按下按鍵,定時(shí)器中斷流程圖如圖8所示:


                          


圖8 T0中斷子程序流程圖

3.2.2 T1定時(shí)器
通過(guò)定時(shí)器T1執(zhí)行波形輸出和頻率轉(zhuǎn)換,改變定時(shí)器T1的時(shí)鐘周期來(lái)改變輸出頻率。定時(shí)器中斷流程圖如圖9所示:


圖9 T1中斷子程序流程圖

附錄一:總電路設(shè)計(jì)圖

單片機(jī)源程序如下:
  1. #include <reg52.h>
  2. unsigned char  code SinWave[256] ={           //正弦波
  3. 127 ,        133 ,        139 ,        146 ,        152 ,        158 ,        164 ,        170,
  4. 176,         181 ,        187 ,        192 ,        198 ,        203 ,        208,         212 ,
  5. 217 ,        221 ,        225 ,        229 ,        233,         236,         239,         242 ,        
  6. 244 ,        247 ,        249 ,        250 ,        252 ,        253 ,        253 ,        254 ,

  7. 254 ,        254 ,        253 ,        253,         252 ,        250 ,        249 ,        247 ,
  8. 244,         242 ,        239,         236 ,        233 ,        229 ,        225 ,        221 ,
  9. 217 ,        212 ,        208 ,        203 ,        198 ,        192 ,        187 ,        181 ,
  10. 176 ,        170 ,        164 ,        158 ,        152 ,        146 ,        139 ,        133 ,
  11.         
  12. 127 ,        121 ,        115 ,        108 ,        102 ,        96         ,   90          ,  84         ,
  13. 78         ,        73         ,        67         ,        62         ,        56        ,         51         ,        46         ,        42        ,
  14. 37         ,        33,                 29         ,        25        ,         21        ,         18         ,        15         ,        12         ,        
  15. 10         ,        7 ,                5         ,        4         ,        2         ,        1         ,        1         ,        0          ,

  16. 0         ,        0 ,                1         ,        1         ,        2         ,        4         ,        5         ,        7          ,
  17. 10         ,        12 ,        15         ,        18         ,        21         ,        25         ,        29         ,        33  ,
  18. 37         ,        42 ,        46         ,        51         ,        56         ,        62         ,        67         ,        73         ,
  19. 78         ,        84         ,        90         ,        96         ,        102 ,        108 ,        115 ,        121         ,

  20. } ;
  21. unsigned char code SawWave[256] = {        //鋸齒波
  22. 0,        2,        4,        6,        8,        10,        12,        14,
  23. 16,        18,        20,        22,        24,        26,        28,        30,        
  24. 32,        34,        36,        38,        40,        42,        44,        46,        
  25. 48,        50,        52,        54,        56,        58,        60,        62,
  26.         
  27. 64,        66,        68,        70,        72,        74,        76,        78,        
  28. 80,        82,        84,        86,        88,        90,        92,        94,        
  29. 96,        98,        100,102,104,106,108,110,        
  30. 112,114,116,118,120,122,124,126,        

  31. 128        ,130,132,134,136,138,140,142,        
  32. 144        ,146,148,150,152,154,156,158,        
  33. 160        ,162,164,166,168,170,172,174,        
  34. 176        ,178,180,182,184,186,188,190,        

  35. 192,194        ,196,198,200,202,204,206,        
  36. 208,210        ,212,214,216,218,220,222,        
  37. 224,226        ,228,230,232,234,236,238,        
  38. 240,242        ,244,246,248,250,252,254,        
  39. };
  40. unsigned char code TriWave[256]= {         //三角波
  41. 0 ,    4    , 8,    12  ,  16   , 20  ,  24  ,  28 ,  
  42. 32 ,   36   , 40,    44 ,   48  ,  52 ,   56  ,  60        ,
  43. 64  ,  68   , 72 ,   76  ,  80   , 84  ,  88  ,  92  ,  
  44. 96   ,100  , 104 ,  108  , 112  , 116  , 120  , 124         ,
  45. 128  ,132  , 136,   140  , 144  , 148 ,  152  , 156 ,  
  46. 160  , 164  , 168,   172 ,  176 ,  180,   184 ,  188 ,
  47. 192  , 196 ,  200,   204,   208 ,  212 ,  216 ,  220 ,  
  48. 224  , 228 ,  232,   236 ,  240  , 244 ,  248 ,  252  ,
  49. 255  , 251 ,  247 ,  243,   239  , 235 ,  231 ,  227  ,
  50. 223  , 219 ,  215,   211 ,  207  , 203 ,  199 ,  195 ,
  51. 191  , 187 ,  183,   179,   175  , 171 ,  167 ,  163 ,
  52. 159  , 155 ,  151,   147,   143  , 139 ,  135  , 131  ,
  53. 127  , 123 ,  119,   115,   111  ,107  , 103  ,  99   ,
  54. 95   , 91  ,  87 ,   83 ,   79   , 75 ,   71  ,  67           ,
  55. 63   , 59 ,   55 ,   51 ,   47   ,43   , 39   , 35    ,
  56. 31   , 27,    23 ,   19 ,   15   , 11 ,    7   ,  3          ,
  57. };
  58. unsigned char code SquWave[256] = {        //方波
  59. 255,255,255,255,255,255,255,255,
  60. 255,255,255,255,255,255,255,255,
  61. 255,255,255,255,255,255,255,255,
  62. 255,255,255,255,255,255,255,255,

  63. 255,255,255,255,255,255,255,255,
  64. 255,255,255,255,255,255,255,255,
  65. 255,255,255,255,255,255,255,255,
  66. 255,255,255,255,255,255,255,255,
  67. };
  68. unsigned char code TraWave[256] = {//梯形波
  69. 0    , 6   ,  12 ,   18 ,   24 ,   30 ,   36  ,  42  ,  
  70. 48  ,  54   , 60 ,   66 ,   72 ,   78  ,  84  ,  90         ,
  71. 96  ,  102  , 108,   114 ,  120,   126 ,  132 ,  138 ,  
  72. 144 ,  150 ,  156,   162 ,  168 ,  174 ,  180 ,  186 ,
  73. 192 ,  198  , 204 ,  210  , 216 ,  222 ,  228 ,  234 ,  
  74. 240 ,  246 ,  252 ,  255,   255,   255,   255,   255,
  75. 255,   255,   255,   255,   255,   255,          255,   255,   
  76. 255,   255,   255,   255,   255,   255,   255,   255,
  77. 255,   255,   255,   255,   255,   255  , 249  , 243 ,  
  78. 237 ,  231  , 225  , 219  , 213,   207 ,  201  , 195  ,
  79. 189 ,  183  , 177 ,  171  , 165        ,  159  , 153  , 147 ,  
  80. 141,   135  , 129 ,  123 ,  117  , 111 ,  105  , 99 ,  
  81. 93 ,   87   , 81 ,   75  ,  69        ,  63  ,  57   , 51 ,   
  82. 45 ,   39    ,33   , 27 ,   21,    15  ,  9    , 3 ,
  83. };
  84. unsigned char code *pWave;  //波表指針
  85. unsigned char T0RH = 0;  //T0重載值的高字節(jié)
  86. unsigned char T0RL = 0;  //T0重載值的低字節(jié)
  87. unsigned char T1RH = 1;  //T1重載值的高字節(jié)
  88. unsigned char T1RL = 1;  //T1重載值的低字節(jié)
  89. unsigned char t;//函數(shù)周期
  90. unsigned char f;//頻率

  91. void ConfigTimer0(unsigned int ms);
  92. void SetWaveFreq(unsigned char freq);
  93. extern void KeyScan();
  94. extern void KeyDriver();
  95. extern void I2CStart();
  96. extern void I2CStop();
  97. extern bit I2CWrite(unsigned char dat);

  98. void main()
  99. {   
  100.     EA = 1;             //開(kāi)總中斷
  101.     ConfigTimer0(100);  //配置T0定時(shí)1ms
  102.     pWave = SinWave;  //默認(rèn)正弦波
  103.     SetWaveFreq(5);  //默認(rèn)頻率100Hz
  104.         f = 128;
  105.    
  106.     while (1)
  107.     {
  108.                KeyDriver();  //調(diào)用按鍵驅(qū)動(dòng)
  109.     }
  110. }

  111. /*改變波形*/
  112. void KeyAction(unsigned char keycode)
  113. {        
  114.         static unsigned char i = 0;

  115.         if(keycode == 0x26)
  116.         {
  117.                 if(i==0)
  118.                 {
  119.                         i = 1;
  120.                         pWave = TriWave;
  121.                 }
  122.                 else if(i==1)
  123.                 {
  124.                         i = 2;
  125.                         pWave = SawWave;
  126.                 }
  127.                 else if(i==2)
  128.                 {
  129.                         i = 3;
  130.                         pWave = SquWave;
  131.                 }
  132.                 else if(i==3)
  133.                 {
  134.                         i = 4;
  135.                         pWave = TraWave;
  136.                 }
  137.                 else
  138.                 {
  139.                         i = 0;
  140.                         pWave = SinWave;
  141.                 }
  142.         }
  143. }
  144. /*改變頻率*/
  145. void KeyAction_f(unsigned char keycode)
  146. {
  147.         static unsigned char i = 0;

  148.         if(keycode == 0x25)
  149.         {
  150.                 if(i==0)
  151.                 {
  152.                         i = 1;
  153.                         f = 128;
  154.                 }
  155.                 else
  156.                 {
  157.                         i = 0;
  158.                         f = 64;
  159.                 }
  160.         }        
  161. }

  162. /* 設(shè)置DAC輸出值,val-設(shè)定值 */
  163. void SetDACOut(unsigned char val)
  164. {
  165.     I2CStart();
  166.     if (!I2CWrite(0x48<<1)) //尋址PCF8591,如未應(yīng)答,則停止操作并返回
  167.     {
  168.         I2CStop();
  169.         return;
  170.     }
  171.     I2CWrite(0x40);         //寫(xiě)入控制字節(jié)
  172.     I2CWrite(val);          //寫(xiě)入DA值  
  173.     I2CStop();
  174. }

  175. /*改變頻率*/
  176. void SetWaveFreq(unsigned char freq)
  177. {
  178.         unsigned long tmp;

  179.         tmp = (11059200/12)/(freq * 128);
  180.         tmp = 65536 - tmp;
  181.         tmp = tmp + 33;
  182.         T1RH = (unsigned char)(tmp >> 8);
  183.         T1RL = (unsigned char)tmp;
  184.         TMOD &= 0x0F;
  185.         TMOD |= 0X10;
  186.         TH1 = T1RH;
  187.         TL1 = T1RL;
  188.         ET1 = 1;
  189.         PT1 = 1;
  190.         TR1 = 1;
  191. }
  192. /* 配置并啟動(dòng)T0,ms-T0定時(shí)時(shí)間 */
  193. void ConfigTimer0(unsigned int ms)
  194. {
  195.     unsigned long tmp;  //臨時(shí)變量
  196.    
  197.     tmp = 11059200 / 12;       //定時(shí)器計(jì)數(shù)頻率
  198.     tmp = (tmp * ms) / 1000;  //計(jì)算所需的計(jì)數(shù)值
  199.     tmp = 65536 - tmp;         //計(jì)算定時(shí)器重載值
  200.     tmp = tmp + 28;            //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
  201.     T0RH = (unsigned char)(tmp>>8);  //定時(shí)器重載值拆分為高低字節(jié)
  202.     T0RL = (unsigned char)tmp;
  203.     TMOD &= 0xF0;   //清零T0的控制位
  204.     TMOD |= 0x01;   //配置T0為模式1
  205.     TH0 = T0RH;     //加載T0重載值
  206.     TL0 = T0RL;
  207.     ET0 = 1;        //使能T0中斷
  208.     TR0 = 1;        //啟動(dòng)T0
  209. }
  210. /* T0中斷服務(wù)函數(shù),執(zhí)行按鍵掃描 */
  211. void InterruptTimer0() interrupt 1
  212. {
  213.     TH0 = T0RH;  //重新加載重載值
  214.     TL0 = T0RL;
  215.     KeyScan();   //按鍵掃描        
  216.         
  217. }
  218. /* T1中斷服務(wù)函數(shù),執(zhí)行波形輸出 */
  219. void InterruptTimer1() interrupt 3
  220. {
  221.     static unsigned char i = 0;
  222.    
  223.     TH1 = T1RH;  //重新加載重載值
  224.     TL1 = T1RL;
  225.     //循環(huán)輸出波表中的數(shù)據(jù)
  226.     SetDACOut(pWave[i]);

  227.         if(f == 128)
  228.         {
  229.             i++;
  230.             if (i >= 128)
  231.             {
  232.                 i = 0;
  233.             }
  234.         }

  235.         if(f == 64)
  236.         {
  237.             i = i+2;
  238.             if (i >= 128)
  239.             {
  240.                 i = 0;
  241.             }
  242.         }
  243. }
復(fù)制代碼

新建文件1.png (41.33 KB, 下載次數(shù): 81)

正弦波

正弦波

新建文件2.png (40.8 KB, 下載次數(shù): 75)

三角波

三角波

新建文件3.png (39.53 KB, 下載次數(shù): 68)

鋸齒波

鋸齒波

新建文件4.png (35.7 KB, 下載次數(shù): 80)

方波

方波

新建文件5.png (41.31 KB, 下載次數(shù): 71)

梯形波

梯形波

51hei.png (4.13 KB, 下載次數(shù): 72)

51hei.png

波形發(fā)生器.rar

1.24 MB, 下載次數(shù): 246, 下載積分: 黑幣 -5

評(píng)分

參與人數(shù) 1黑幣 +80 收起 理由
admin + 80 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:604918 發(fā)表于 2022-4-28 15:05 | 只看該作者
這是用啥仿真的
回復(fù)

使用道具 舉報(bào)

板凳
ID:903830 發(fā)表于 2022-11-14 16:45 | 只看該作者
請(qǐng)問(wèn)如何實(shí)現(xiàn)峰峰值0-3V的鋸齒波
回復(fù)

使用道具 舉報(bào)

地板
ID:433219 發(fā)表于 2022-11-15 10:38 | 只看該作者
PCF8591   這死貴的價(jià)格,還不如用stc去做。大不了2片
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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