网站右侧浮动广告,学习网站建设优化,怎样在微信中做网站,做网站用什么服务器会比较好#include reg51.h // 包含51单片机寄存器定义的头文件 #include intrins.h //包含_nop_()函数定义的头文件 #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写…#include reg51.h // 包含51单片机寄存器定义的头文件 #include intrins.h //包含_nop_()函数定义的头文件 #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写入操作,0xa1即为1010 0000B sbit SDAP3^4; //将串行数据总线SDA位定义在为P3.4引脚 sbit SCLP3^3; //将串行时钟总线SDA位定义在为P3.3引脚 sbit soundP3^7; //将sound位定义为P3.7,从该引脚输出音频 unsigned int C; //储存定时器的定时常数
//以下是C调低音的音频宏定义 #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调中音的音频宏定义 #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调高音的音频宏定义 #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 /******************************************* 函数功能节拍的延时的基本单位延时200ms ******************************************/ void delay() { unsigned char i,j; for(i0;i250;i) for(j0;j250;j) ; } /************************************************************************** 以下是对AT24C02进行读写操作的源程序 *************************************************************************/ /***************************************************** 函数功能延时1ms (3j2)*i(3×332)×101010(微秒),可以认为是1毫秒 ***************************************************/ void delay1ms() { unsigned char i,j; for(i0;i10;i) for(j0;j33;j) ; } /***************************************************** 函数功能延时若干毫秒 入口参数n ***************************************************/ void delaynms(unsigned char n) { unsigned char i; for(i0;in;i) delay1ms(); } /*************************************************** 函数功能开始数据传送 ***************************************************/ void start() { SDA 1; //SDA初始化为高电平1 SCL 1; //开始数据传送时,要求SCL为高电平1 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SDA 0; //SDA的下降沿被认为是开始信号 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) } /*************************************************** 函数功能结束数据传送 ***************************************************/ void stop() { SDA 0; //SDA初始化为低电平0 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL 1; //结束数据传送时,要求SCL为高电平1 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SDA 1; //SDA的上升沿被认为是结束信号 } /*************************************************** 函数功能从AT24Cxx读取数据 出口参数x ***************************************************/ unsigned char ReadData() { unsigned char i; unsigned char x; //储存从AT24Cxx中读出的数据 for(i 0;i 8;i) { SCL 1; //SCL置为高电平 x1; //将x中的各二进位向左移一位 x|(unsigned char)SDA; //将SDA上的数据通过按位或运算存入x中 SCL 0; //在SCL的下降沿读出数据 } return(x); //将读取的数据返回 } /*************************************************** 函数功能向AT24Cxx的当前地址写入数据 入口参数y (储存待写入的数据) ***************************************************/ //在调用此数据写入函数前需首先调用开始函数start(),所以SCL0 bit WriteCurrent(unsigned char y) { unsigned char i; bit ack_bit; //储存应答位 for(i 0; i 8; i) // 循环移入8个位 { SDA (bit)(y0x80); //通过按位与运算将最高位数据送到S //因为传送时高位在前,低位在后 _nop_(); //等待一个机器周期 SCL 1; //在SCL的上升沿将数据写入AT24Cxx _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL 0; //将SCL重新置为低电平,以在SC线形成传送数据所需的个脉冲 y 1; //将y中的各二进位向左移一位 } SDA 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL1)释放SDA线, //以让SDA线转由接收设备(AT24Cxx)控制 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL 1; //根据上述规定,SCL应为高电平 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 ack_bit SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节 //若送高电平,表示没有接收到,传送异常 SCL 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) return ack_bit;// 返回AT24Cxx应答位 } /*************************************************** 函数功能向AT24Cxx中的指定地址写入数据 入口参数add (储存指定的地址);dat(储存待写入的数据) ***************************************************/ void WriteSet(unsigned char add, unsigned char dat) { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(add); //写入指定地址 WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据 stop(); //停止数据传递 delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上 } /*************************************************** 函数功能从AT24Cxx中的当前地址读取数据 出口参数x (储存读出的数据) ***************************************************/ unsigned char ReadCurrent() { unsigned char x; start(); //开始数据传递 WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据 xReadData(); //将读取的数据存入x stop(); //停止数据传递 return x; //返回读取的数据 } /*************************************************** 函数功能从AT24Cxx中的指定地址读取数据 入口参数set_addr 出口参数x ***************************************************/ unsigned char ReadSet(unsigned char set_addr) { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(set_addr); //写入指定地址 return(ReadCurrent()); //从指定地址读出数据并返回 } /*************************************************** 函数功能主函数 ***************************************************/ main(void) { unsigned char i,j; unsigned char temp; //储存压缩后的音频 unsigned char Ji; //储存音符节拍 unsigned char N; //储存音符的最大个数以在AT24C02中为音符和节拍分配存储空间 unsigned int fr; //储存解压缩后的音频 //以下是《渴望》片头曲的一段简谱 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作为简谱的结束标志 //以下是简谱中每个音符的节拍 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 }; EA1; //开总中断 ET01; //定时器T0中断允许 TMOD0x00; // 使用定时器T0的模式113位计数器 SDA 1; // SDA1,SCL1,使主从设备处于空闲状态 SCL 1; while(1) //无限循环 { i0; //从第1个音符频率f[0]开始写入AT24C02 while(f[i]!0x01) //只要没有读到结束标志就继续写入 { temp(unsigned char)(f[i]/8); //将音频压缩为较小的字符变量 WriteSet(0x00i,temp); //在指定地址写入数据压缩后的音频 i; //指向下一个音符音频 } Ni; //将音符的最大个数存于N i0; //从第一个音符节拍JP[0]开始写入AT24C02 while(f[i]!0x00) { WriteSet(0x00Ni,JP[i]); //在指定地址写入音符的节拍 i; //指向下一个音符音频 } for(i0;iN;i) { tempReadSet(0x00i); //读出音频 JiReadSet(0x00Ni); //读出节拍 fr8*temp; //将音频解压 C460830/fr; //定时常数的计算公式 TH0(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法 TL0(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法 TR01; //启动定时器T0 for(j0;jJi;j) //控制节拍数 delay(); //延时1个节拍单位 TR00; //关闭定时器T0 } sound1; //播放完毕后关闭蜂鸣器 for(i0;i8;i) //播放完毕后停顿一段时间后继续播放 delay(); } } / /*********************************************************** 函数功能定时器T0的中断服务子程序使P3.7引脚输出音频的方波 ************************************************************/ void Time0(void ) interrupt 1 using 1 { TH0(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法 TL0(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法 sound!sound; //将P3.7引脚输出电平取反形成方波 }