[操作疑難] [已解決]

本帖最後由 boy50000 於 2016-7-26 23:44 編輯

最近整緊音樂盒
呢日係proteus到寫好段code
當我去模擬個陣
用內置個counter timer去check個個pin
發現do音調唔到261 Hz
只係得131Hz
其他音調更加唔洗講

小弟捻極都捻唔明點解
求各位指點迷津:crybye
  1. #include <reg51.h>

  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. #define c 191                // Do - 261 Hz
  5. #define d 170                // Re - 294 Hz
  6. #define e 152                // Mi - 329 Hz
  7. #define f 143                // Fa - 349 Hz
  8. #define g 127                // Sol - 392 Hz
  9. #define a 113                // La - 440 Hz
  10. #define b 101                // Ti - 493 Hz
  11. #define C 95                // Do# - 523 Hz

  12. #define MAXMIUM_MUSIC 3

  13. uint music;

  14. uint is_pressed;
  15. uint looping;

  16. uint melody_1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };       
  17. uint beats_1[] = { 100, 50, 75, 100, 75, 100, 200, 300 };

  18. sbit buzzer = P3^7;

  19. sbit button_play = P1^0;
  20. sbit button_next = P1^3;
  21. sbit button_looping = P1^7;

  22. void key_scanning();
  23. void play_music();
  24. void delay(int time);
  25. void melody_effect(int key);

  26. void main(void)
  27. {
  28.    P1 = 0x0;
  29.    P3 = P2 = 0xFF;
  30.    
  31.    music = 0;
  32.    
  33.    buzzer = 0;
  34.    
  35.    is_pressed = 0;
  36.    
  37.    while (1)
  38.    {
  39.       melody_effect(0);
  40.       //key_scanning();
  41.    }
  42. }

  43. void key_scanning()
  44. {
  45.    if (button_play || button_next || button_looping)
  46.    {
  47.       if (is_pressed)
  48.          return;
  49.       
  50.       if (button_play)
  51.          play_music();
  52.       else if (button_next)
  53.       {
  54.          music++;
  55.          
  56.          if (music > MAXMIUM_MUSIC)
  57.             music = 0;
  58.       }
  59.       else
  60.          looping = ~looping;
  61.       
  62.       is_pressed = 1;
  63.    }
  64.    else if (!button_play && !button_next && !button_looping)
  65.       is_pressed = 0;
  66. }

  67. void play_music()
  68. {
  69.    switch(music)
  70.    {
  71.       case 0:
  72.       {
  73.          int i, j;
  74.          for(i=0;i<=7;i++)
  75.          {
  76.             for(j=0;j<=beats_1[i];j++)
  77.                melody_effect(i);
  78.          }
  79.          break;
  80.       }
  81.    }
  82.    
  83.    P2 = 0xFF;
  84. }

  85. void melody_effect(int key)
  86. {
  87.    char led = 0;
  88.    int time = 0;
  89.    
  90.    switch(key)
  91.    {
  92.       case 0:
  93.       {
  94.          led = 0xFE;                // Red LED
  95.          time = c;
  96.          break;
  97.       }
  98.       case 1:
  99.       {
  100.          led = 0xFD;                // Orange LED
  101.          time = d;
  102.          break;
  103.       }
  104.       case 2:
  105.       {
  106.          led = 0xFB;                // Yellow LED
  107.          time = e;
  108.          break;
  109.       }
  110.       case 3:
  111.       {
  112.          led = 0xF7;                // Green LED
  113.          time = f;
  114.          break;
  115.       }
  116.       case 4:
  117.       {
  118.          led = 0xEF;                // Blue LED
  119.          time = g;
  120.          break;
  121.       }
  122.       case 5:
  123.       {
  124.          led = 0xDF;                // Pink LED
  125.          time = a;
  126.          break;
  127.       }
  128.       case 6:
  129.       {
  130.          led = 0xBF;                // Purple LED
  131.          time = b;
  132.          break;
  133.       }
  134.       case 7:
  135.       {
  136.          led = 0x7F;                // White LED
  137.          time = C;
  138.          break;
  139.       }
  140.    }
  141.    
  142.    P2 = led;
  143.    buzzer = 1;
  144.    delay(time);
  145.    buzzer = 0;
  146.    delay(time);
  147. }

  148. void delay(int time)
  149. {
  150.    int i;
  151.    
  152.    TMOD = 0x00;
  153.    
  154.    while(time--)
  155.    {
  156.       TH0 = 255;
  157.       TL0 = 22;
  158.       TR0 = 1;
  159.       while(TF0 = 0);
  160.       TR0 = 0;
  161.    }
  162. }
複製代碼
Crystal用左12Mhz

---------------------------------------

岩岩發現捻錯左方向
依加已經重新寫返好program

while(time--)
   {
      TH0 = 255;
      TL0 = 22;
      TR0 = 1;
      while(TF0 = 0);
      TR0 = 0;
   }

你用 13bit timer mode0
內圈timer set 太細
while(TF0 = 0); 10下就overflow
呢句上下太多overhead, add up 差唔多啦
你睇下assmebly 就知咩事~

最懶人包方法用 mode2 auto reload啦

TOP

while(time--)
   {
      TH0 = 255;
      TL0 = 22;
      TR0 = 1;
      while(TF0 = 0);
      TR0 = ...
michael2010 發表於 2016-7-27 00:00


唔該哂Ching

TOP