当前位置:文档之家› 音乐盒设计

音乐盒设计


2方案设计
• 总体设计框图
• 本设计采用89C52作为主控芯片,蜂鸣器作为输出设备产 生音乐,通过按键1和2能够选择歌曲。LCD1602能够实 时的显示当前的歌曲名及歌曲号。其中P3.3和P3.2外接按 键,P2口用作LCD输出数据端口,P1.4接蜂鸣器端口。
3 系统硬件设计
3 系统硬件设计
主控芯片:设计中所采用主控芯片为AT89C52。因其价格便宜,在市场上已经很 成熟,各个方面都能够满足设计要求故选择它。 蜂鸣器及蜂鸣器驱动:从价格及控制上方面,我们选择市场上常见的有源蜂
基于单片机的音乐盒设计
电信0902
摘要:
单片机因其体积小、功能强、价格低廉而 得到广泛应用。本文介绍用AT89C52单片 机设计音乐盒的方法,仅需AT89C51最小系 统,扩展两个按键,再加一片由两个NPN组成 的达林顿管以及输出设备蜂鸣器和LCD。 通过两个按键可以选择上一首歌曲及下一 首歌曲,并在LCD上直观的显示出歌曲的 序号。
鸣器作为音频输出设备。选择通过两个NPN三级管搭建成一个达林顿作为 为驱动。 按键:采用常用的四引脚按键,其中各有两个引脚相连。按下时,接通, 放开时,将断开。设计中需要两个按键,作为上一首和下一首的信号输入。
显示设备:为了在播放过程中能够清晰的知道当前歌曲的信息,我们采用市场上常 见的LCD1602显示屏作为输入显示设备
音调
• • 4.1.1 音频脉冲 要生产音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周 期的时间。利用定时器计时这个半周期时间,每当计时到后就将输出脉冲的I/O反相,然 后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。 4.1.2 方法 利用8051的内部定时器使用其工作在计数器模式MODE1下,改变计数值THO及TLO以 产生不同频率的方法。 • 计算公式 例如频率为523Hz,其周期T=1/523=1912us,因此只要令计数器计时956us/1us= 956,在每次计数956次时将I/O反相,就可得到中音DO (523Hz)。 计数脉冲值与频率的关系公式如下:
• • • • • • • • • • • • • void dis_song(char a); /*****************设置音调*******************/ //对定时器0的初始值更新 void SET_BUZZER_TONE(unsigned int tone) { TR0=0; th=(65536-tone)/256; tl=(65536-tone)%256; TR0=1; 4,4,4,4,16,8,4,8,4,4,8,4,4,16,8,4,8,8,4,4,8,16,8,4,16, 8,4,8,8,4,4,4,4,16}, {4,4,4,4,4,4,4,4,4,4,8,4,4,8,2,2,2,2,4,4,2,2,2,2,4,4,4,
• • • • • • • • • • • • • • • • • • • • • • • • • • • • •
unsigned char flag1; num1=0; num2=0; flag1=1; flag2=0; flag3=0; BUZZER=0; TIME0_INIT(); //定时器初始化 INT_INIT(); //外部中断初始化 LCD_INIT(); //LCD初始化 while(1) { dis_song(num1); while(flag1) { if(SONG[num1][num2]==20)flag1=0; //如果检测到最后一个音调为20,说明此 曲应该结束 else { if(flag2==1) //中断检测 { num1++; if(num1>3)num1=0; num2=0; flag2=0; dis_song(num1); } if(flag3==1) //中断检测 { num1--; if(num1<0)num1=3;
{4,4,4,4,16,4,4,4,4,16,8,4,8,8,4,4,4,4,16,8,4,8,4,4,8,4,4,16, 4,4,8,16,8,4,4,8,8,8,4,4,16,4,4,4,4,16,4,4,4,4,16,8,4,8,8,
4,8,4,4,8}};
• • • • • • • • • • • • • • • • • • • • • • • • • • • • •
/**************设置节拍**********************/ //x为最小节拍的倍数 void DELAY_MIN_BEAT(unsigned char x) { unsigned int i,j,k; for(i=0;i<x;i++) { for(j=0;j<100;j++) for(k=0;k<120;k++); } TR0=0; } /***************定时器0初始化****************/ void TIME0_INIT() { IE|=0x82; TMOD=0x01; //定时器0工作在方式1 IP=0x02; //定时器0具有最高优先级 } /**************外部中断0和1初始化***********/ void INT_INIT() { IE|=0x85; TCON|=0x05; //外部中断0和1负边缘触发 } /****************主函数*********************/ void main() { char num1,num2;
• •
• • •

• 4.1.4 其计数值的求法
4.2 基本知识--节拍表二 值T的对照表
C调各音符频率与计数
• •
4.2.1相关知识 每个音符使用1个字节,字节的高4位代表音符的高低,低4位代表音符的节拍, 表三为节拍与节拍码的对照.如果1拍为0.4秒,1/4拍是0.1秒,只要设定延迟时 间就可求得节拍的时间.假设1/4拍为1DELAY,则1拍应为4DELAY,以此类推. 所以只要求得1/4拍的DELAY时间,其余的节拍就是它的倍数,如表四为1/4和 1/8节拍的时间设定。
• • • • • • • • • • • • • • • • • • • • • • • • • • • • •
num2=0; flag3=0; dis_song(num1); } SET_BUZZER_TONE(TONE[SONG[num1][num2]]); DELAY_MIN_BEAT(BEAT[num1][num2]); num2++; } } num2=0; flag1=1; num1++; if(num1==4)num1=0; }
• 4.3 程序流程图
• 外部中断0中断程序中令Flag2=1, • 中断1的中断程序中令Flag=1 • 定时器0中断流程图如图四。
• 。
主 程 序 流 程 图 如 图 五
ห้องสมุดไป่ตู้ •
• • • • • • • • • • • • • • • • • • • •

程序代码
KCSJ.C
#include "reg52.h" #include "LCD.h" sbit BUZZER=P3^1; unsigned char th,tl; unsigned char flag2,flag3; char song1[14]="NUM1"; char song2[14]="NUM2"; char song3[14]="NUM3"; char song4[14]="NUM4"; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // 7L 1 2 3 4 5 6 7 1H 2H 3H 5L 6L 4L unsigned int TONE[14]={1012,956,852,759,716,638,568,506,478,426,379,1276,1136,1433}; // 1 2 5 6 7 // 低音 1908 1701 1515 1433 1276 1136 1012 // 中音 956 852 759 716 638 568 506 // 高音 478 426 379 358 319 284 253 unsigned char code SONG[4][150]={
• • • • • • • • • • • •
3,2,1,2,2,2,3,5,5,8,2,3,5,3,5,8,6,5,3,5,6,8,5,8,10,9,8, 9,8,6,8,5,3,5,6,5,6,8,9,5,6,3,8,6,5,3,2,1,2,2,3,5, 8,10,9,8,9,8,5,6,8,20}, //两只老虎 {1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1, 2,11,1,2,11,1,20}}; unsigned char code BEAT[4][150]={{4,4,4,4,4,4,8,8,4,4,4,4,4,4,8,4, 4,4,4,4,4,4,8,8,4,4,4,4,4,2,8,8, 4,4,4,4,4,4,8,4,8,4,4,4,4,2,4,8,8, 4,4,4,4,4,4,8,8,4,4,4,4,4,4,8,8}, {8,8,4,4,8,4,4,4,4,8,4,4,4,4,4,4,4,4, 4,8,4,8,4,4,4,4,16,4,4,4,4,8, 4,4,4,4,4,4,8,4,4,4,4,16},
} /*************定时器0中断函数****************/ void T0_TONE(void) interrupt 1 { TH0=th; TL0=tl; BUZZER=~BUZZER; } /**************外部中断0函数*****************/ void INT0_SELECT(void) interrupt 0 { flag2=1; } /**************外部中断1函数*****************/ void INT1_SELECT(void) interrupt 2
相关主题