📄 c24c02.music.txt
字号:
//main.c 主程序,设定参数,调用音乐处理函数,播放函数//
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
extern void play(uchar *songdata);
extern void delay(uint m);
extern void musicdata(void);
uchar xdata yinyue[256];
void main(void)
{
TMOD=0x01;
ET0=1;
TR0=0;
EA=1;
while(1)
{
musicdata();
delay(5);
play(yinyue);
}
}
//musicdata.c 音乐处理函数,将音乐数组存入ROM中,根据键值扫描结果判定播放哪一首歌,为验证24C02的存储功能,先将数据存入外部ROM,再取出播放//
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
extern uchar Read24c02(uchar address);
extern void Write24c02(uchar ch,uchar address);
extern void delay(uint m);
extern uchar keysearch(void);
extern void send(unsigned char a);
uchar buffer;
extern uchar xdata yinyue[256];
//老鼠爱大米
uchar code dami[]={ "321-|3.2_1-|3231|3_6.5-|3_5_665|65-3_2_|122_3_2|12--|" };
uchar code xianjian[]={
"|3_3_3_2_3-|2_3_2_2_,6,6_,7_|12_1_,7,6_,5_|,6---|"
"3_3_3_2_3.6_|5_6_5_5_22_3_|45_4_32_1_|3.--3_|"
"67_6_55_3_|5--3_5_|26_5_32_3_|3---|"
"26_6_6-|16_6_66_7_|`17_6_76_7_|3.--3_|"
"67_6_55_3_|5--3_5_|67_6_76_7_|3---|"
"26_6_6-|16_6_66_7_|`17_6_7.5_|6---|"
};
//我是一只菠萝
uchar code boluo[]={
"1-|2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_`1_7_6_|5_4_2_3_11|"
"2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_5_2_3_|1---|"
};
//小星星
uchar code xingxing[]={
"1155|665-|4433|221-|"
"5544|332-|5544|332-|"
"1155|665-|4433|221-|"
};
void musicdata(void)
{
uint i,j;
uchar key=0x00;
while(1)
{
key= keysearch();
send(key);
P1&=0x7f;
switch(key)
{
case 0xfe:{
for(j=0; dami[j]!='\0';j++)
{
Write24c02(dami[j],j);
buffer=j;
send(j);
}
Write24c02(0x00,j);
delay(50);
for(i=0;i<=buffer;i++)
{
yinyue[i]=Read24c02(i);
delay(2); send(i);
}
}break;
case 0xfd:{
for(j=0; xianjian[j]!='\0';j++)
{
Write24c02(xianjian[j],j);
buffer=j;
send(j);
}
Write24c02(0x00,j);
delay(50);
for(i=0;i<=buffer;i++)
{
yinyue[i]=Read24c02(i);
delay(2);
send(i);
}
}break;
case 0xfb:{
for(j=0; boluo[j]!='\0';j++)
{
Write24c02(boluo[j],j);
send(j);
buffer=j;
}
Write24c02(0x00,j);
delay(50);
for(i=0;i<=buffer;i++)
{
yinyue[i]=Read24c02(i);
delay(2);
send(i);
}
}break;
case 0xf7:{
for(j=0; xingxing[j]!='\0';j++)
{
Write24c02(xingxing[j],j);
send(j);
buffer=j;
}
Write24c02(0x00,j);
delay(50);
for(i=0;i<=buffer;i++)
{
yinyue[i]=Read24c02(i);
delay(2);
send(i);
}
}break;
default :break;
}
if (key!=0x00) break ;
}
}
//24C02.C IIC总线实现外部ROM读取功能函数//
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define WC24C02 0xA0
#define RC24C02 0xA1
#define WRADR 0x00
#define _Nop() _nop_()
sbit SDA=P3^4;
sbit SCL=P3^5;
void delay(uint m)
{
uint i,j;
for(i=0;i<m;i++)
for(j=0;j<2000;j++);
}
void Start() //开始总线
{
SDA=1; /*发送起始条件的数据信号*/
SCL=1;
SDA=0; /*发送起始信号*/
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
}
void Stop() //结束总线
{
SDA=0; /*发送结束条件的数据信号*/
/*发送结束条件的时钟信号*/
SCL=1; /*结束条件建立时间大于4μs*/
SDA=1; /*发送I2C总线结束信号*/
}
//发ACK0
void NoAck()
{
SDA=1;
SCL=1;
SCL=0;
}
bit TestAck() //测试
{
bit ErrorBit;
SDA=1;
SCL=1;
ErrorBit=SDA;
SCL=0;
return(ErrorBit);
}
void Write8Bit(uchar input) //写入8bit
{
uchar temp;
for(temp=8;temp!=0;temp--)
{
SDA=(bit)(input &0x80);
SCL=1;
SCL=0;
input=input<<1;
}
}
void Write24c02(uchar ch,uchar address)//写入一个字节到24c02中
{
Start();
Write8Bit(WC24C02);
_Nop();
_Nop();
TestAck();
_Nop();
_Nop();
Write8Bit(address);
_Nop();
_Nop();
TestAck();
Write8Bit(ch);
_Nop();
_Nop();
TestAck();
_Nop();
_Nop();
_Nop();
_Nop();
Stop();
delay(10);
}
uchar Read8Bit() //读8bit
{
uchar temp,rbyte=0;
for(temp=0;temp<8;temp++)
{
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((uchar)(SDA));
SCL=0;
}
return(rbyte);
}
uchar Read24c02(uchar address)//读一个字节
{
uchar ch;
Start();
Write8Bit(WC24C02);
TestAck();
Write8Bit(address);
TestAck();
Start();
Write8Bit(RC24C02);
TestAck();
ch=Read8Bit();
NoAck() ;
Stop();
return(ch);
}
//music.c 音乐播放处理函数//
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit ledcs=P1^7;
uchar v_th0,v_tl0;
uchar code freq[36*2]={ 0xA9,0xEF,//00220HZ ,1 //0
0x93,0xF0,//00233HZ ,1#
0x73,0xF1,//00247HZ ,2
0x49,0xF2,//00262HZ ,2#
0x07,0xF3,//00277HZ ,3
0xC8,0xF3,//00294HZ ,4
0x73,0xF4,//00311HZ ,4#
0x1E,0xF5,//00330HZ ,5
0xB6,0xF5,//00349HZ ,5#
0x4C,0xF6,//00370HZ ,6
0xD7,0xF6,//00392HZ ,6#
0x5A,0xF7,//00415HZ ,7
0xD8,0xF7,//00440HZ 1 //12
0x4D,0xF8,//00466HZ 1# //13
0xBD,0xF8,//00494HZ 2 //14
0x24,0xF9,//00523HZ 2# //15
0x87,0xF9,//00554HZ 3 //16
0xE4,0xF9,//00587HZ 4 //17
0x3D,0xFA,//00622HZ 4# //18
0x90,0xFA,//00659HZ 5 //19
0xDE,0xFA,//00698HZ 5# //20
0x29,0xFB,//00740HZ 6 //21
0x6F,0xFB,//00784HZ 6# //22
0xB1,0xFB,//00831HZ 7 //23
0xEF,0xFB,//00880HZ `1
0x2A,0xFC,//00932HZ `1#
0x62,0xFC,//00988HZ `2
0x95,0xFC,//01046HZ `2#
0xC7,0xFC,//01109HZ `3
0xF6,0xFC,//01175HZ `4
0x22,0xFD,//01244HZ `4#
0x4B,0xFD,//01318HZ `5
0x73,0xFD,//01397HZ `5#
0x98,0xFD,//01480HZ `6
0xBB,0xFD,//01568HZ `6#
0xDC,0xFD,//01661HZ `7 //35
};
void changedata(uchar *song,uchar *diao,uchar *jie)
{
uchar i,i1,j;
char gaodi; //高低+/-12音阶
uchar banyin;//有没有半个升音阶
uchar yinchang;//音长
uchar code jie7[8]={0,12,14,16,17,19,21,23}; //C调的7个值
*diao=*song;
for(i=0,i1=0;;)
{
gaodi=0; //高低=0
banyin=0;//半音=0
yinchang=4;//音长1拍
if((*(song+i)=='|') || (*(song+i)==' ')) i++; //拍子间隔和一个空格过滤
switch(*(song+i))
{
case ',': gaodi=-12;i++;//低音
break;
case '`': gaodi=12;i++; //高音
break;
}
if(*(song+i)==0) //遇到0结束
{ *(diao+i1)=0; //加入结束标志0
*(jie+i1)=0;
return;
}
j=*(song+i)-0x30;
i++; //取出基准音
j=jie7[j]+gaodi; //加上高低音
yinc: switch(*(song+i))
{ case '#': //有半音j加一个音阶
i++;
j++;
goto yinc;
case '-': //有一个音节加长
yinchang+=4;
i++;
goto yinc;
case '_': //有一个音节缩短
yinchang/=2;
i++;
goto yinc;
case '.': //有一个加半拍
yinchang=yinchang+yinchang/2;
i++;
goto yinc;
}
*(diao+i1)=j; //记录音符
*(jie+i1)=yinchang; //记录音长
i1++;
}
}
void play(uchar *songdata)
{
uchar i,c;
uint n;
uchar xdata diaodata[112]; //音调缓冲
uchar xdata jiedata[112]; //音长缓冲
changedata(songdata,diaodata,jiedata); //解释音乐符号串
TR0=1;
for(i=0;diaodata[i]!='\0';i++) //逐个符号演奏
{
v_tl0=freq[diaodata[i]*2]; //取出对应的定时值送给T0
v_th0=freq[diaodata[i]*2+1];
for(c=0;c<jiedata[i];c++) //按照音长延时
for(n=0;n<6000;n++);
TR0=0;
for(n=0;n<120;n++); //音符间延时
TR0=1;
}
TR0=0;
}
void timer0 (void ) interrupt 1
{
TH0=v_th0;
TL0=v_tl0;
ledcs=~ledcs;
}
//keysearch.c 键盘扫描处理函数//
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define shut() P1|=0x80;
extern void delay(uint m);
sbit sda=P1^0;
sbit clk=P1^1;
sbit KD_KEY=P1^2;
void send(unsigned char a)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(_crol_(a,i)&0x80)
sda=1;
else
sda=0;
clk=0;
clk=1;
}
}
uchar keysearch(void)
{
uchar i;
uchar buffer=0;
uchar scan=0xfe;
shut(); //*******在键盘操作时一定要关显示器*******//
for(i=0;i<8;i++)
{
send(scan);
if(!KD_KEY)
{
buffer=scan;
break;
}
scan=_crol_(scan,1);
}
return(buffer);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -