添加链接描述## 红外无线控制单片机播放图片与音乐
通过无线红外模块来控制51单片机来实现图片、音乐自由切换。
系统概要图:

音乐播放程序:
音乐播放流程图如3-2-1所示
分析音乐播放的过程,其为不同频率声音的组合,当一组恰当频率声音组合按照一定的先后顺序与节拍播放时,即可产生音乐。故要产生音频信号,只要算出某一音频的周期,将此周期除以2即为半周期的时间,利用定时器计时此半周期时间,计时到后取反输出,重复此过程即得到此频率的声音信号。此信号从P2.3脚输出,用ULN2003驱动蜂鸣器播放音乐。其中每个音符使用两个字节表示:低位字节(偶地址)代表音级,表示的音级为c、﹟c、d、﹟d、e、f、……a3、﹟a3、b3;高位字节(奇地址)代表音符的时值(节拍),表示拍数为1/8拍(0.10s)~8拍(6.40s)。
程序设计中用软件延时程序来控制音级, 与红外解码共用定时器0进行节拍的控制,并在播放和暂停播放中随时判断是否有红外信号的改变,以便随时更换或结束音乐。本设计中歌曲的音符存在一个数组中,以在开始位置和在中间位置播放不同的曲目
控制发声频率:
要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。利用STC89C52RC的内部定时器使其工作在计数器模式MODE1下,改变计数值TH0及TL0从而产生不同频率。此外结束符和休止符可以分别用代码00H和FFH来表示,若查表结果为0x00,则表示曲子终了;若查表结果为0xff,则产生相应的停顿效果。
以标准音高A为例,A的频率是440Hz,周期T=1/440=2272us。在占空比为50%的情况下,导通时间=断开时间=半周期t=2272us/2=1136us,利用P3^4端口的位操作,经过不断地反相变换即可得到标准音高A的音频脉冲。端口导通时间与断开时的时间利用定时器实现。具体的方法是将单片机定时器的中断触发时间设为半周期t,这样每隔半周期端口反相,输出连续的对应音高的频率。
设晶振的频率为f0,中断触发时间(半周期)为t,定时器工作在模式1时计数器的初值为THL,高8位为THL,低8位为TL。时钟周期即为1/f0,定时器每一次累加用去一个机器周期,一个机器周期包含12个时钟周期,即定时器每次加一所用时间是12/f0。定时器在模式1下计时采用16位数,最大计数为2^16-1(65535),再次加一(65536)溢出触发中断

12864液晶显示程序
如图3-2-2 12864实物图、3-2-3点阵图所示:
12864点阵液晶显示模块(LCM)就是由12864个液晶显示点组成的一个128列64行的阵列。每个显示点对应一位二进制数,1表示亮,0表示灭。存储这些点阵信息的RAM称为显示数据存储器。要显示某个图形或汉字就是将相应的点阵信息写入到相应的存储单元中。图形或汉字的点阵信息由自己设计,问题的关键就是显示点在液晶屏上的位置(行和列)与其在存储器中的地址之间的关系。由于多数液晶显示模块的驱动电路是由一片行驱动器和两片列驱动器构成,所以12864液晶屏实际上是由左右两块独立的6464液晶屏拼接而成,每半屏有一个5128 bits显示数据RAM。左右半屏驱动电路及存储器分别由片选信号CS1和CS2选择。显示点在6464液晶屏上的位置由行号(line,063)与列号(column,063)确定。5128 bits RAM中某个存储单元的地址由页地址(Xpage,07)和列地址(Yaddress,063)确定。每个存储单元存储8个液晶点的显示信息。
为了使液晶点位置信息与存储地址的对应关系更直观关,将6464液晶屏从上至下8等分为8个显示块,每块包括8行64列个点阵。每列中的8行点阵信息构成一个8bits二进制数,存储在一个存储单元中。(注意:二进制的高低有效位顺序与行号对应关系因不同商家而不同)存放一个显示块的RAM区称为存储页。即6464液晶屏的点阵信息存储在8个存储页中,每页64个字节,每个字节存储一列(8行)点阵信息。因此存储单元地址包括页地址(Xpage,07)和列地址(Yaddress,063)。例如点亮12864的屏中(20,30)位置上的液晶点,因列地址30小于64,该点在左半屏第29列,所以CS1有效;行地址20除以8取整得2,取余得4,该点在RAM中页地址为2,在字节中的序号为4;所以将二进制数据00010000(也可能是00001000,高低顺序取决于制造商)写入Xpage=2,Yaddress=29的存储单元中即点亮(20,30)上的液晶点。


数码管显示图片与音乐的编号就不多讲啦
项目代码如下:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit IR=P3^2; //红外接口标志
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
sbit LATCH1=P2^0;//定义锁存使能端口 段锁存
sbit LATCH2=P2^1;// 位锁存
sbit LCD1602=P2^5;
sbit P2_3=P2^3;
void Draw_PM(const uchar *ptr);
void Ir_work(void);
void Ircordpro(void);
uchar time;
unsigned char IRcord[4];
sbit DU = P2^0; //段选,申明U1锁存器的锁存端,锁存器使用的是74HC573
sbit WE= P2^1; //位选,申明U2锁存器的锁存端,锁存器使用的是74HC573
uchar code table[]={0x3f,0x06,0x5b,
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};
int n;
/*
延时函数
*/
void delay1() //位码的转换 3*5*125=1875ms=1.875s
{
for(n=0;n<125;n++);
}
void xianshi(){
while(IRcord[2]==0x0c){
DU=1;
P0=0x77; //第一位断码
DU=0;
WE=1;
P0=0xfe; //第一位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第二位断码
DU=0;
WE=1;
P0=0xfd; //第二位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第三位断码
DU=0;
WE=1;
P0=0xfb; //第三位位码
WE=0;
delay1();
DU=1;
P0=0x06; //第四位断码
DU=0;
WE=1;
P0=0xf7; //第四位位码
WE=0;
delay1();
Ircordpro();
}
}
void xianshi1(){
while(IRcord[2]==0x18){
DU=1;
P0=0x77; //第一位断码
DU=0;
WE=1;
P0=0xfe; //第一位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第二位断码
DU=0;
WE=1;
P0=0xfd; //第二位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第三位断码
DU=0;
WE=1;
P0=0xfb; //第三位位码
WE=0;
delay1();
DU=1;
P0=0x59; //第四位断码
DU=0;
WE=1;
P0=0xf7; //第四位位码
WE=0;
delay1();
Ircordpro();
}
}
void xianshi2(){
while(IRcord[2]==0x5e){
DU=1;
P0=0x77; //第一位断码
DU=0;
WE=1;
P0=0xfe; //第一位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第二位断码
DU=0;
WE=1;
P0=0xfd; //第二位位码
WE=0;
delay1();
DU=1;
P0=0x3f; //第三位断码
DU=0;
WE=1;
P0=0xfb; //第三位位码
WE=0;
delay1();
DU=1;
P0=0x4f; //第四位断码
DU=0;
WE=1;
P0=0xf7; //第四位位码
WE=0;
delay1();
Ircordpro();
}
}
bit flag; //标志音乐输出脚电平的高低
uchar ptr = 0x00; //取音符
uchar high; //计数器高位
uchar low; //计数器低位
// 本曲谱为 "新年好",前两个十六进制表示发声频率,后一个表示发声时间,0xFF,0xFF 表示休止符
// 0x00 表示结束
// 1 _ 1_ 1 .5
uchar code music[] = {
0xFC,0x44,0x7F, 0xFC,0x44,0x7F, 0xFC,0x44,0xFF, 0xFA,0x68,0xFF,
// 3 _ 3_ 3 1
0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
// 1_ 3_ 5 5
0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFD,0x82,0xFF, 0xFD,0x82,0xFF,
// 4_ 3_ 2 -
0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFF,0xFF,0xFF,
// 2_ 3_ 4 4
0xFC,0xAC,0x7F, 0xFD,0x23,0x7F, 0xFD,0x34,0xFF, 0xFD,0x34,0xFF,
// 3_ 2_ 3 1
0xFD,0x23,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
// 1_ 3_ 2 .5
0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFA,0x68,0xFF,
// .7_ 2_ 1 -
0xFC,0x0C,0x7F, 0xFC,0xAC,0x7F, 0xFC,0x44,0xFF, 0xFF,0xFF,0xFF,
0x00//结束
};
uchar code music1[]={
0xFC,0x44,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x09,0x7F, 0xFC,0x44,0xFF,
// 1 _ 2 3_1 5
0xFC,0x44,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x09,0x7F, 0xFC,0x44,0xFF,
// 1_ 2 3_1
0xFD,0x09,0x7F, 0xFD,0x34,0x7F, 0xFD,0x82,0xFF,
// 3_ 4 5
0xFD,0x09,0x7F, 0xFD,0x34,0x7F, 0xFD,0x82,0xFF,
// 3_ 4 5
0xFD,0x82,0x7F, 0xFD,0xCB,0x7F, 0xFD,0x82,0x7F,
0xFD,0x34,0x7F,0xFD,0x09,0X7F,0XFC,0X44,0XFF,
// 5_ 6 5_4 3 1
0xFD,0x82,0x7F, 0xFD,0xCB,0x7F, 0xFD,0x82,0x7F,
0xFD,0x34,0x7F,0xFD,0x09,0X7F,0XFC,0X44,0XFF,
// 5_ 6 5_4 3 1
0xFC,0xAC, 0X7F,0xFC,0x44,0X7F, 0xFC,0xAC,0X7F,0xFA,0x44,0xFF,
// 2 5 1 0
0xFC,0xAC,0X7F, 0xFC,0x44,0X7F, 0xFC,0xAC,0X7F, 0xFA,0x44,0xFF,
0x00
};
/*********************************************************************************
* 名称:Init()
* 功能:设置计数器0 工作方式,16 位计数,溢出中断方式
*****************************************************************************

本项目介绍了一种基于51单片机的红外遥控音乐播放系统,通过无线红外模块控制单片机实现图片、音乐的自由切换。系统利用定时器精确控制音频信号的频率,实现不同音乐的播放,并通过12864液晶显示屏显示当前状态。项目还包含了详细的程序代码,包括音乐播放流程、定时器配置、红外信号解码和液晶显示控制。
最低0.47元/天 解锁文章
1167

被折叠的 条评论
为什么被折叠?



