当前位置:文档之家› 80c51单片机课程设计word文档良心出品

80c51单片机课程设计word文档良心出品

单片机课程设计报告题目:基于51单片机发光牌与伴奏音乐系统专业班级机械111班姓名学号一、设计目的(一)、以AT89C51单片机为主体,设计一个有伴奏音乐的发光牌。

1、功能放光牌用数码管显示,分别按顺序显示出“2”、“0”、“1”、“3”的数字样。

而且不断的循环从左到右显示。

同时还伴有歌名为“同一首歌”的旋律。

发光牌由数码管进行设置,歌声的旋律则由蜂鸣器来实现。

2、效果即数码管为发光牌,同时伴有歌声发光牌效果图可如下二、硬件系统AT89C51单片机是美国ATMEL公司生产的低电压、高性能CMOS8位单片机,具有丰富的内部资源:4kB闪存、128BRAM、32根I/O口线、2个16位定时/计数器、5个向量两级中断结构、2个全双工的串行口,具有4.25~5.50V的电压工作范围和0~24MHz工作频率,使用AT89C51单片机时无须外扩存储器。

(1)、硬件总电路图如下其中AT89C51单片机的设置如下选择12MH的晶振,该单片机选用24V的电压。

其中电路图中的7447芯片中的A,B,C,D,E,F,G 引脚是引出来用来分别接四个数码管的。

其中低电平代表通电,其数码管的0~9的数字代码如下:0X01、0X12、0X24、0X38、0X41、0X52、0X64、0X78、0X81、0X92.并通过p2.0、p2.1、p2.2、p2.3引脚分别来控制四个数码管的得电顺序。

从而实现发光牌的设置和控制。

、对蜂鸣器的控制的电路介绍)2(.为般是指时钟电路引脚、其中XTAL1XTAL2在片内它是振荡器反相放大器的输接外部晶振和微调电容的一端,TAL1:X入;若使用外部时钟时,该引脚必须接地。

在片内它是振荡器反相放大器的:接外部晶振和微调电容的另一端,XTAL2 输出;若使用外部时钟时,该引脚接外部时钟的输入端。

利用这两个引脚可以对歌曲的节奏和时间进行控制。

从而演奏蜂鸣器可根据不同代码发出声音。

其中歌曲的谱音可用代码表示,出“同一首歌”的旋律。

三、软件系统protues,仿真用软件软件编程序用keil软件其中控制歌曲播放的流程图如下开始定义晶振频率12000000HZ定义普通音符演奏的长度分率音符定时器初暂音符发生中断根据调号及升降八度计来生成新的频率表、算歌曲长度算出普通音符的演奏长度结束控制歌曲的子程序的功能是可以计算出歌曲的播放时间,与各个音符的停顿。

(3)对数码管控制a、数码管的接线图如下其中数码管的放大电路端如下图所示其中连接R1端的可与p22、p20、p21、p23连接。

b、对数码管控制的流程图如下开定义延迟时间常数显示第一个数码管显示第二个数码管显示第三个数码管“1”显示第四个数”3码管“结束四、仿真结果软件来实现,其仿真电路图如下仿真效果和预期一样。

其仿真用protues五、附件程序源代码如下#include <REG52.H>#include <stdio.h>#include SoundPlay.hvoid Delay1ms(unsigned int count){unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}65000 //定义延迟时间常数#define DELAYTIME unsigned int temp1;延时程序void delay(unsigned int temp)//{while(--temp);}同一首歌// unsigned char code Music_Same[]={0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03, 0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02 0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66, 0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00, 0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x030x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,0x00,0x00 };//********************************************************************************* **main(){InitialSound();while(1){Play(Music_Same,0,3,360);Delay1ms(500);}P2=0; //led is offwhile(1){P2=0X24;//显示2,P2口输出其BCD码和扫描码P2.temp1=DELAYTIMdelay(temp1);P2=0X01;//显示0,P2口输出其BCD码和扫描码P2.0temp1=DELAYTdelay(temp1);P2=0X12;//显示1,P2口输出其BCD码和扫描码P2.1temp1=DELAYTIME;delay(temp1);P2=0X38;//显示3,P2口输出其BCD码和扫描码P2.3temp1=DELAYTIME;delay(temp1);}}/**************************************************************************SOUNDPLAY FOR 51MCUCOPYRIGHT (c)2005 BY JJJ.--ALL RIGHTSRESERVED --File Name: SoundPlay.hAuthor: Jiang Jian JunCreated: 2005/5/16Modified: NORevision: 1.0*******************************************************************************//*说明**************************************************************************曲谱存贮格式unsigned char code MusicName{音高,音长,音高,音长...., 0,0}; 末尾:0,0 表示结束(Important)音高由三位数字组成:个位是表示1~7 这七个音符十位是表示音符所在的音区:1-低音,2-中音,3-高音;百位表示这个音符是否要升半音: 0-不升,1-升半音。

音长最多由三位数字组成:个位表示音符的时值,其对应关系是:|0 |1 |2 |3 | 4 | 5 | 6 (n): 数值||几分音符: |1 |2 |4 |8 |16 |32 |64 音符=2^n十位表示音符的演奏效果(0-2): 0-普通,1-连音,2-顿音百位是符点位: 0-无符点,1-有符点调用演奏子程序的格式Play(乐曲名,调号,升降八度,演奏速度);|乐曲名: 要播放的乐曲指针,结尾以(0,0)结束;|调号(0-11) : 是指乐曲升多少个半音演奏;|升降八度(1-3) : 1:降八度, 2:不升不降,3:升八度;|演奏速度(1-12000): 值越大速度越快;***************************************************************************/ #ifndef __SOUNDPLAY_H_REVISION_FIRST__#define __SOUNDPLAY_H_REVISION_FIRST__//**************************************************************************#define SYSTEM_OSC 12000000//定义晶振频率12000000HZ#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔sbit BeepIO = P3^7; //定义输出管脚unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 };//1~7在频率表中的位置unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存//************************************************************************** void InitialSound(void)BeepIO = 0;Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值(10ms的初装值)Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%6; // 计算TH1应装入的初值TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TMOD |= 0x11;ET0 = 1;ET1= 0;TR0= 0;TR1 = 0;EA = 1;}void BeepTimer0(void) interrupt 1 //音符发生中断{BeepIO = !BeepIO;TH0 = Sound_Temp_TH0;TL0 = Sound_Temp_TL0;}//************************************************************************** void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed){unsigned int NewFreTab[12]; //新的频率表unsigned char i,j;unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength; unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表{j = i + Signature;if(j > 11){j = j-12;NewFreTab[i] = FreTab[j]*2;}elseNewFreTab[i] = FreTab[j];if(Octachord == 1)NewFreTab[i]>>=2;else if(Octachord == 3)NewFreTab[i]<<=2;}SoundLength = 0;while(Sound[SoundLength] != 0x00) //计算歌曲长度{SoundLength+=2;}Point = 0;Tone = Sound[Point];Length = Sound[Point+1]; // 读出第一个音符和它时时值LDiv0 = 12000/Speed; // 算出1分音符的长度(几个10ms)LDiv4 = LDiv0/4; // 算出4分音符的长度LDiv4 = LDiv4-LDiv4*SOUND_SPACE; // 普通音最长间隔标准TR0= 0;TR1 = 1;while(Point < SoundLength){SL=Tone_x0010_; //计算出音符SM=Tone/10_x0010_;//计算出高低音SH=Tone/100; //计算出是否升半CurrentFre =NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率if(SL!=0){if (SM==1) CurrentFre >>= 2; //低音if (SM==3) CurrentFre <<= 2; //高音Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值Sound_Temp_TH0 = Temp_T/256;Sound_Temp_TL0 = Temp_T%6;TH0 = Sound_Temp_TH0;TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿}SLen=LengthTab[Length_x0010_]; //算出是几分音符XG=Length/10_x0010_; //算出音符类型(0普通1连音2顿音)FD=Length/100;LDiv=LDiv0/SLen; //算出连音音符演奏的长度(多少个10ms)if (FD==1)LDiv=LDiv+LDiv/2;if(XG!=1)if(XG==0) //算出普通音符的演奏长度if (SLen<=4)LDiv1=LDiv-LDiv4;elseLDiv1=LDiv*SOUND_SPACE;ElseLDiv1=LDiv/2; //算出顿音的演奏长度elseLDiv1=LDiv;if(SL==0) LDiv1=0;LDiv2=LDiv-LDiv1; //算出不发音的长if (SL!=0){TR0=1;for(i=LDiv1;i>0;i--) //发规定长度的音{while(TF1==0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;}}if(LDiv2!=0){TR0=0; BeepIO=0;for(i=LDiv2;i>0;i--) //音符间的间隔{while(TF1==0);TH1 = Sound_Temp_TH1;TL1 = Sound_Temp_TL1;TF1=0;}}Point+=2;Tone=Sound[Point];Length=Sound[Point+1];}BeepIO = 0;}//************************************************************************** #endif。

相关主题