欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2706|回復: 0
收起左側

51單片機用定時器T0的模式0控制播放《好人一生平安》

[復制鏈接]
ID:223935 發表于 2017-8-1 20:44 | 顯示全部樓層 |閱讀模式



C音調與譜曲控制對應表
音調   低1(低音“dao”)  低2  低3  低4  低5  低6  低7  

頻率   262                 294  330  349  392  440  494

音調   中1(中音“dao”)  中2  中3  中4  中5  中6  中7

頻率   523                 587  659  698  784  880  988

音調   高1(高音“dao”)  高2  高3  高4  高5  高6  高7

頻率   1046                1175 1318 1397 1568 1760 1967


實現方法

1.音頻控制

要讓蜂鳴器發出某音調的聲音,只要給蜂鳴器輸送該音調頻率的電平信號就可以了。
由于單片機I/O口的輸出只有高電平“1”和低電平“0”兩種狀態,因此給蜂鳴器輸送的電平信號實際上就是該音頻的方波。
例如:中音“1”的頻率為523HZ,它的周期為1/523s,即1.91ms,因此,只要給蜂鳴器輸送周期為1.91ms的脈沖方波電平信號就能發出
523HZ的音調,該方波的半周期為1.91/2=0.955ms.為此,需要利用定時器的中斷,讓輸送給蜂鳴器的電平信號每0.995ms取反一次即可,
單片機晶振頻率為11.0952MHZ,它的一個機器周期為12*(1/11.0592)us,所以需要的機器周期總數為

                                                955us/1.085us=880

即定時器的定時常數應取為880,由上述分析,發出頻率為f的音頻時,定時常數C計算公式為

                                                C=(10^6 / 2f)/1.085us =  460830/f

因為T0工作方式0,其最大計數值為8192,完全可以滿足各音頻定時常數設置的需要?梢宰C明,在已知定時常數C的條件下,13位計數器
的高8位和低5位的初值可由以下公式設定:

                    TH0=(8192-C)/32   //13位計數器高8位的賦初值方法
                    TL0=(8192-C)%32   //13位計數器低5位的賦初值方法


2.節拍控制

每分鐘72拍,每個節拍所需時間:(1000*60/72)ms=833ms     // 具體見單片機扉頁

3.音調與節拍的存儲

可以將簡譜中所有音調的頻率及節拍分別存儲于兩個數組,然后依次從數組中讀出頻率,再根據頻率和定時器延時常數的計算公式
即可由定時器中斷控制發出該音調的音頻,其發聲時間可由節拍控制(1-4個延時單位)。

4.音調的宏定義

直接將頻率存入數組,顯然不如以“dao,rei,mi,fa,sao……”的形式存儲方便,但是為了讓單片機認識這些,需要在程序開頭處對各音調
的頻率進行宏定義。例如,低音6的頻率為440Hz,中音6的頻率為880Hz,高音6的頻率為1760Hz。所以可以對這三個頻率進行如下宏定義


           #define l_la 440  //將“l_la”宏定義為低音“6”的頻率440Hz,以此類推
           #define la 880
           #define h_la 1760


程序設計

#include<reg52.h>
sbit deep=P2^3;
uint C;
#define uint unsigned int
#define uchar unsigned char
#define l_dao 262
#define l_re 286
#define l_mi 311
#define l_fa 349
#define l_sao 392
#define l_la 440
#define l_xi 494
#define dao 523
#define re 587
#define mi 659
#define fa 698
#define sao 784
#define la 880
#define xi 987
#define h_dao 1046
#define h_re 1174
#define h_mi 1318
#define h_fa 1396
#define h_sao 1567
#define h_la 1760
#define h_xi 1975

void delay(uint xms)
{
    uchar i,j;
    for(i=xms;i>0;i--)
       for(j=110;j>0;j--);
}


void main()
{
    uchar i.j;
    uint code f[]={re,mi,re,dao,l_la,dao,l_la,
                   l_sao,l_mi,l_sao,l_la,dao,
                   l_la,dao,sao,la,mi,sao,re,mi,re,mi,sao,mi,
                   l_sao,l_mi,l_sao,l_la,dao,
                   l_la,l_la,dao,l_la,l_sao,l_re,l_mi,
                   l_sao,re,re,sao,la,sao,
                   fa,mi,sao,mi,la,sao,mi,re,mi,l_la,dao,
                   re,mi,re,mi,sao,mi,l_sao,l_mi,l_sao,l_la,dao,
                   l_la,dao,re,l_la,dao,re,mi,re,l_la,dao,re,l_la,dao,
                   re,mi,re,l_la,dao,re,l_la,dao,re,mi,re,0xff};

    uchar code JP[]={4,1,1,4,1,1,2,           //每行對應一小節音調的節拍
                     2,2,2,2,8,
                         4,2,3,1,2,2,
                       10,
                      4,2,2,4,4,
                      2,2,2,2,4,
                   2,2,2,2,2,2,2,
                       10,
                      4,4,4,2,2,
                      4,2,4,4,
                      4,2,2,2,2,2,2,
                        10,
                      4,2,2,4,4,
                      2,2,2,2,6,
                      4,2,2,4,1,1,4,
                        10,
                      4,2,2,4,1,1,4,
                         10};


      EA=1;               //開總中斷
      ET0=1;              //定時器T0中斷允許
      TMOD=0X00;          //使用定時器T0的模式0(13位計數器)
      while(1)            //無限循環
       {
           i=0;
           while(1)
           {
              i=0;                     //從第一個音調f[0]開始播放
              while(f[i]!=0xff)        //只要沒有讀到結束標志就繼續播放  
                  {
                      C=460830/f[i];
                      TH0=(8192-C)/32;   
                      TL0=(8192-C)%32;
                      TR0=1;
                      for(j=0;j<JP[i];j++)  //控制節拍數
                      delay();              //延時一個節拍單位
                       TR0=0;              //關閉定時器T0
                        i++;               //播放下一個音調
                   }
            }
}


void Time() interrupt 1
{
        deep=!deep;
        TH0=(8192-C)/32;
        TL0=(8192-C)%32;
}

















































回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

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