小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

EX89 將"好人一生平安"樂(lè)譜寫(xiě)入AT24C02并讀出播放

 jianke 2009-09-20
//實(shí)例89:將"渴望"樂(lè)譜寫(xiě)入AT24C02并讀出播放
#include <reg51.h>         // 包含51單片機(jī)寄存器定義的頭文件
#include <intrins.h>       //包含_nop_()函數(shù)定義的頭文件
#define OP_READ 0xa1  // 器件地址以及讀取操作,0xa1即為1010 0001B
#define OP_WRITE 0xa0  // 器件地址以及寫(xiě)入操作,0xa1即為1010 0000B
sbit SDA=P3^4;             //將串行數(shù)據(jù)總線SDA位定義在為P3.4引腳
sbit SCL=P3^3;             //將串行時(shí)鐘總線SDA位定義在為P3.3引腳
sbit sound=P3^7;           //將sound位定義為P3.7,從該引腳輸出音頻
unsigned int C;            //儲(chǔ)存定時(shí)器的定時(shí)常數(shù)
//以下是C調(diào)低音的音頻宏定義
#define l_dao 262   //將“l_dao”宏定義為低音“1”的頻率262Hz
#define l_re 286    //將“l_re”宏定義為低音“2”的頻率286Hz
#define l_mi 311    //將“l_mi”宏定義為低音“3”的頻率311Hz
#define l_fa 349    //將“l_fa”宏定義為低音“4”的頻率349Hz
#define l_sao 392   //將“l_sao”宏定義為低音“5”的頻率392Hz
#define l_la 440    //將“l_a”宏定義為低音“6”的頻率440Hz
#define l_xi 494    //將“l_xi”宏定義為低音“7”的頻率494Hz
//以下是C調(diào)中音的音頻宏定義
#define dao 523     //將“dao”宏定義為中音“1”的頻率523Hz
#define re 587      //將“re”宏定義為中音“2”的頻率587Hz
#define mi 659      //將“mi”宏定義為中音“3”的頻率659Hz
#define fa 698      //將“fa”宏定義為中音“4”的頻率698Hz
#define sao 784     //將“sao”宏定義為中音“5”的頻率784Hz
#define la 880      //將“la”宏定義為中音“6”的頻率880Hz
#define xi 987      //將“xi”宏定義為中音“7”的頻率523Hz
//以下是C調(diào)高音的音頻宏定義
#define h_dao 1046     //將“h_dao”宏定義為高音“1”的頻率1046Hz
#define h_re 1174      //將“h_re”宏定義為高音“2”的頻率1174Hz
#define h_mi 1318      //將“h_mi”宏定義為高音“3”的頻率1318Hz
#define h_fa 1396     //將“h_fa”宏定義為高音“4”的頻率1396Hz
#define h_sao 1567    //將“h_sao”宏定義為高音“5”的頻率1567Hz
#define h_la 1760     //將“h_la”宏定義為高音“6”的頻率1760Hz
#define h_xi 1975     //將“h_xi”宏定義為高音“7”的頻率1975Hz
/*******************************************
函數(shù)功能:節(jié)拍的延時(shí)的基本單位,延時(shí)200ms
******************************************/
void delay()              
   {
     unsigned char i,j;
   for(i=0;i<250;i++)
     for(j=0;j<250;j++)
        ;
   }
/**************************************************************************
以下是對(duì)AT24C02進(jìn)行讀寫(xiě)操作的源程序
 *************************************************************************/
/*****************************************************
函數(shù)功能:延時(shí)1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j; 
  for(i=0;i<10;i++)
   for(j=0;j<33;j++)
         ;  
 }
/*****************************************************
函數(shù)功能:延時(shí)若干毫秒
入口參數(shù):n
***************************************************/
 void delaynms(unsigned char n)
 {
   unsigned char i;
 for(i=0;i<n;i++)
    delay1ms();
 }
/***************************************************
函數(shù)功能:開(kāi)始數(shù)據(jù)傳送
***************************************************/
void start()
{
 SDA = 1;     //SDA初始化為高電平"1"
 SCL = 1;     //開(kāi)始數(shù)據(jù)傳送時(shí),要求SCL為高電平"1"
 _nop_();    //等待一個(gè)機(jī)器周期
 _nop_();    //等待一個(gè)機(jī)器周期
 SDA = 0;     //SDA的下降沿被認(rèn)為是開(kāi)始信號(hào)
 _nop_();    //等待一個(gè)機(jī)器周期
 _nop_();    //等待一個(gè)機(jī)器周期
 _nop_();    //等待一個(gè)機(jī)器周期
 _nop_();    //等待一個(gè)機(jī)器周期
 SCL = 0;     //SCL為低電平時(shí),SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞)
}
/***************************************************
函數(shù)功能:結(jié)束數(shù)據(jù)傳送
***************************************************/
void stop()
{
 SDA = 0;      //SDA初始化為低電平"0"
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 SCL = 1;      //結(jié)束數(shù)據(jù)傳送時(shí),要求SCL為高電平"1"
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 SDA = 1;     //SDA的上升沿被認(rèn)為是結(jié)束信號(hào)
}
/***************************************************
函數(shù)功能:從AT24Cxx讀取數(shù)據(jù)
出口參數(shù):x
***************************************************/
unsigned char ReadData()
{
 unsigned char i;
 unsigned char x;               //儲(chǔ)存從AT24Cxx中讀出的數(shù)據(jù)
 for(i = 0;i < 8;i++)
 {
  SCL = 1;                 //SCL置為高電平
  x<<=1;                  //將x中的各二進(jìn)位向左移一位
  x|=(unsigned char)SDA; //將SDA上的數(shù)據(jù)通過(guò)按位"或"運(yùn)算存入x中
  SCL = 0;                //在SCL的下降沿讀出數(shù)據(jù)
 }
 return(x);                  //將讀取的數(shù)據(jù)返回
}
/***************************************************
函數(shù)功能:向AT24Cxx的當(dāng)前地址寫(xiě)入數(shù)據(jù)
入口參數(shù):y (儲(chǔ)存待寫(xiě)入的數(shù)據(jù))
***************************************************/
//在調(diào)用此數(shù)據(jù)寫(xiě)入函數(shù)前需首先調(diào)用開(kāi)始函數(shù)start(),所以SCL=0
bit WriteCurrent(unsigned char y)
{
 unsigned char i;
 bit ack_bit;                  //儲(chǔ)存應(yīng)答位
 for(i = 0; i < 8; i++)   // 循環(huán)移入8個(gè)位
 {
     SDA = (bit)(y&0x80); //通過(guò)按位"與"運(yùn)算將最高位數(shù)據(jù)送到S
                          //因?yàn)閭魉蜁r(shí)高位在前,低位在后
  _nop_();              //等待一個(gè)機(jī)器周期  
    SCL = 1;                //在SCL的上升沿將數(shù)據(jù)寫(xiě)入AT24Cxx     
       _nop_();              //等待一個(gè)機(jī)器周期
    _nop_();              //等待一個(gè)機(jī)器周期      
    SCL = 0;  //將SCL重新置為低電平,以在SCL線形成傳送數(shù)據(jù)所需的8?jìng)€(gè)脈沖
  y <<= 1;             //將y中的各二進(jìn)位向左移一位
 }
 SDA = 1; // 發(fā)送設(shè)備(主機(jī))應(yīng)在時(shí)鐘脈沖的高電平期間(SCL=1)釋放SDA線,
           //以讓SDA線轉(zhuǎn)由接收設(shè)備(AT24Cxx)控制
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 SCL = 1;      //根據(jù)上述規(guī)定,SCL應(yīng)為高電平
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 _nop_();     //等待一個(gè)機(jī)器周期
 ack_bit = SDA; //接受設(shè)備(AT24Cxx)向SDA送低電平,表示已經(jīng)接收到一個(gè)字節(jié)
                //若送高電平,表示沒(méi)有接收到,傳送異常
 SCL = 0;      //SCL為低電平時(shí),SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞)
 return  ack_bit;// 返回AT24Cxx應(yīng)答位
}
/***************************************************
函數(shù)功能:向AT24Cxx中的指定地址寫(xiě)入數(shù)據(jù)
入口參數(shù):add (儲(chǔ)存指定的地址);dat(儲(chǔ)存待寫(xiě)入的數(shù)據(jù))
***************************************************/
void WriteSet(unsigned char add, unsigned char dat)
{
 start();                   //開(kāi)始數(shù)據(jù)傳遞
 WriteCurrent(OP_WRITE);  //選擇要操作的AT24Cxx芯片,并告知要對(duì)其寫(xiě)入數(shù)據(jù)
 WriteCurrent(add);        //寫(xiě)入指定地址
 WriteCurrent(dat);        //向當(dāng)前地址(上面指定的地址)寫(xiě)入數(shù)據(jù)
 stop();                  //停止數(shù)據(jù)傳遞
 delaynms(4);           //1個(gè)字節(jié)的寫(xiě)入周期為1ms, 最好延時(shí)1ms以上
}
/***************************************************
函數(shù)功能:從AT24Cxx中的當(dāng)前地址讀取數(shù)據(jù)
出口參數(shù):x (儲(chǔ)存讀出的數(shù)據(jù))
***************************************************/
unsigned char ReadCurrent()
{
 unsigned char x;
 start();                   //開(kāi)始數(shù)據(jù)傳遞
 WriteCurrent(OP_READ);   //選擇要操作的AT24Cxx芯片,并告知要讀其數(shù)據(jù)
 x=ReadData();            //將讀取的數(shù)據(jù)存入x
 stop();                   //停止數(shù)據(jù)傳遞
 return x;                   //返回讀取的數(shù)據(jù)
}
/***************************************************
函數(shù)功能:從AT24Cxx中的指定地址讀取數(shù)據(jù)
入口參數(shù):set_addr
出口參數(shù):x
***************************************************/
unsigned char ReadSet(unsigned char set_addr)
{
 start();                  //開(kāi)始數(shù)據(jù)傳遞
 WriteCurrent(OP_WRITE); //選擇要操作的AT24Cxx芯片,并告知要對(duì)其寫(xiě)入數(shù)據(jù)
 WriteCurrent(set_addr);    //寫(xiě)入指定地址
 return(ReadCurrent());   //從指定地址讀出數(shù)據(jù)并返回
}
/***************************************************
函數(shù)功能:主函數(shù)
***************************************************/
main(void)
{
  unsigned char i,j;
  unsigned char temp;   //儲(chǔ)存壓縮后的音頻
  unsigned char Ji;     //儲(chǔ)存音符節(jié)拍
  unsigned char  N;    //儲(chǔ)存音符的最大個(gè)數(shù)以在AT24C02中為音符和節(jié)拍分配存儲(chǔ)空間
  unsigned int fr;     //儲(chǔ)存解壓縮后的音頻          
  //以下是《渴望》片頭曲的一段簡(jiǎn)譜
   unsigned  int 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,
         0x00};   //以頻率0x00作為簡(jiǎn)譜的結(jié)束標(biāo)志     
//以下是簡(jiǎn)譜中每個(gè)音符的節(jié)拍
 unsigned char 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;         //開(kāi)總中斷
  ET0=1;        //定時(shí)器T0中斷允許
    TMOD=0x00;    // 使用定時(shí)器T0的模式1(13位計(jì)數(shù)器)
   SDA = 1;                // SDA=1,SCL=1,使主從設(shè)備處于空閑狀態(tài)
    SCL = 1;         
    while(1)       //無(wú)限循環(huán)
  {
      i=0;   //從第1個(gè)音符頻率f[0]開(kāi)始寫(xiě)入AT24C02
        while(f[i]!=0x01)            //只要沒(méi)有讀到結(jié)束標(biāo)志就繼續(xù)寫(xiě)入
     {
      temp=(unsigned char)(f[i]/8); //將音頻壓縮為較小的字符變量
              WriteSet(0x00+i,temp);       //在指定地址寫(xiě)入數(shù)據(jù)壓縮后的音頻
      i++;                         //指向下一個(gè)音符音頻
      }
      N=i;      //將音符的最大個(gè)數(shù)存于N
      i=0;      //從第一個(gè)音符節(jié)拍JP[0]開(kāi)始寫(xiě)入AT24C02
      while(f[i]!=0x00)
      {
        WriteSet(0x00+N+i,JP[i]);  //在指定地址寫(xiě)入音符的節(jié)拍
        i++;                       //指向下一個(gè)音符音頻
      }
        for(i=0;i<N;i++)   
      {
         temp=ReadSet(0x00+i);  //讀出音頻
       Ji=ReadSet(0x00+N+i);  //讀出節(jié)拍
       fr=8*temp;             //將音頻解壓
       C=460830/fr;           //定時(shí)常數(shù)的計(jì)算公式
               TH0=(8192-C)/32;       //可證明這是13位計(jì)數(shù)器TH0高8位的賦初值方法
               TL0=(8192-C)%32;       //可證明這是13位計(jì)數(shù)器TL0低5位的賦初值方法
               TR0=1;                 //啟動(dòng)定時(shí)器T0
         for(j=0;j<Ji;j++)      //控制節(jié)拍數(shù)
                   delay();           //延時(shí)1個(gè)節(jié)拍單位
       TR0=0;                 //關(guān)閉定時(shí)器T0                   
      } 
      sound=1;                  //播放完畢后,關(guān)閉蜂鳴器
      for(i=0;i<8;i++)            //播放完畢后,停頓一段時(shí)間后繼續(xù)播放
        delay(); 
  }    
}
 

/////////////////////////
/***********************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序,使P3.7引腳輸出音頻的方波
************************************************************/
  void Time0(void ) interrupt 1 using 1 
  {
        
       TH0=(8192-C)/32;   //可證明這是13位計(jì)數(shù)器TH0高8位的賦初值方法
       TL0=(8192-C)%32;   //可證明這是13位計(jì)數(shù)器TL0低5位的賦初值方法   
     sound=!sound;     //將P3.7引腳輸出電平取反,形成方波
  }

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多