单片机课程设计报告电子琴.docx
- 文档编号:24183707
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:42
- 大小:62.53KB
单片机课程设计报告电子琴.docx
《单片机课程设计报告电子琴.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告电子琴.docx(42页珍藏版)》请在冰豆网上搜索。
单片机课程设计报告电子琴
电子音调发生器
一、实验目的
1。
了解计算机发声原理。
2。
熟悉定时器和键盘扫描电路的工作原理及编程方法。
二、实验完成的功能
1。
利用键盘1~7进行音调选择,即按下音符产生对应音调.
2.事先存储三首歌曲,并可进行选择播放.
3. 谱曲功能:
通过按键对LCD菜单选项进行选择,进入谱曲界面,通过按键1~7分别输入音高与几分音符类型,由按键输入若干数据完成谱曲。
4. 在播放存储歌曲与谱曲播放时,对应音符及其节奏LCD显示对应频谱.
5.在播放音乐时按“返回”键出现返回界面,由键盘按“确认”键选择返回主菜单或循环播放。
三、实验原理
1。
音节由不同频率的方波产生,音节与频率的关系如表(1)所示。
要产生音频方波,只要计算出某一音频的周期(1 /频率),然后将此周期除以2,即为半周期的时间.利用计时器计时此半周期时间,每当计时到后就将输出方波的I/O(P1.7)反相,然后重复计时此半周期时间再对I/O反相,就可在P1.7脚得到此频率的方波.将P1.7经过驱动电路与蜂鸣器相连,随着P1.7口输出不同频率的方波,蜂鸣器便会发出不同的声音。
音乐的节拍是由延时实现的,如果1拍的时间为0.4秒,1/4拍是0。
1秒.只要设定延时时间,就可得到节拍的时间。
延时实现基本延时时间,节拍值只能是它的整数倍.
每个音节相应的定时器初值计算公式如下:
(1/2)*(1/f)=(12/fose)*(216-x)
即x=216-(fose/24f)
其中,f是音调频率,当晶振fosc=11.0592MHz时,音节“1”相应的定时器初值为x,则可得到x=63777D=F921H,其它的可同样得到。
表
(1)音节与频率的关系
音调
频率(Hz)
X(HEX)
1
262
F921
2
294
F9E1
3
330
FA8C
4
349
FAD8
5
392
FB68
6
440
FBE9
7
494
FC5B
i
523
FC8F
在编写歌曲代码过程中,音高由三位数字组成:
个位是表示1~7 这七个音符;十位是表示音符所在的音区:
1-低音,—中音,—高音;百位表示这个音符是否要升半音:
0—不升,—升半音。
音长最多由三位数字组成:
个位表示音符的时值,其对应关系是:
|数值(n):
|0 |1|2 |3| 4|5|6
ﻩ|几分音符:
|1|2 |4 |8|16|32 |64音符=2^n
十位表示音符的演奏效果(0—2):
0—普通,—连音,-顿音,百位是符点位:
0-无符点,1—有符点。
2。
键盘扫描
将单片机P1。
0~P1。
7(引脚1~8)与键盘上对应引脚相连,其中P1。
0~P1。
3控制键盘的行,P1.4~P1。
7控制键盘的列,这次使用的键盘是4行4列,键盘上的第一行到第四行由8位十六进制代码的低四位控制,即第一行若有键按下,则8位十六进制代码的后四位为0x8,第二行有按键按下,则后四位代码为0x4,依此规律类推;键盘上的第一列到第四列由8位十六进制代码的高四位控制,即第一列若有键按下,则8位十六进制代码的前四位为0x8,第二列有按键按下,则前四位代码为0x4,依此规律类推。
综上所述,可以根据8位十六进制的高四位和低四位数据,分别确定按下的键处于第几行第几列,从而确定按键的位置,实现键盘扫描的功能。
3.LCD显示
根据写命令函数wrcomd和写数据函数wrdata分别控制LCD的命令写入和数据写入。
具体操作方法是由写命令函数wrcomd编程控制数据输入的行列,再由写数据函数wrdata编程写入需要在LCD上显示的数据或应执行的操作,结合两个命令一起控制LCD显示。
四.产品展示
五.实验程序
#ifndef_DRIVEFUTION_H_
#define _DRIVEFUTION_H_
/*********************EEPROM函数*******************/
/**************************************************/
/******************关闭ISP,IAP 功能**************/
voidISP_IAP_disable(void)
{
ISP_CONTR=0X00;
ISP_CMD=0X00;
ISP_TRIG= 0x00;
}
/*******************字节读***************************/
ucharByte_read(uintbyte_addr)
{
EA=0; //关中断
ISP_CONTR= En_Wait_TIME; //开启ISP/IAP;并送等待时间
ISP_CMD =Read_COM; //送字节读命令字
ISP_ADDRH=(uchar)(byte_addr〉〉8); //送地址高字节
ISP_ADDRL =(uchar)(byte_addr& 0X00FF); //送地址低字节
ISP_TRIG = 0X46; //送触发命令字 0X46、0XB9
ISP_TRIG=0XB9;
_nop_();
ISP_IAP_disable(); //关闭ISP/IAP功能
EA = 1; //开中断
return (ISP_DATA);
}
/********************字节编程***********************/
voidByte_program(uint byte_addr,ucharisp_iap_data)
{
EA=0; //关中断
ISP_CONTR=En_Wait_TIME; //开启ISP/IAP;并送等待时间
ISP_CMD=Prog_COM; //送字节编程命令字
ISP_ADDRH=(uchar)(byte_addr〉〉8); //送地址高字节
ISP_ADDRL=(uchar)(byte_addr&0X00FF);//送地址低字节
ISP_DATA=isp_iap_data; //送数据进ISP_DATA
ISP_TRIG=0X46; //送触发命令字0X46、0XB9
ISP_TRIG =0XB9;
_nop_();
ISP_IAP_disable(); //关闭ISP/IAP功能
EA=1; //开中断
}
/********************* 扇区擦除*********************/
void Sector_erase(uintsector_addr)
{
EA= 0; //关中断
ISP_CONTR=En_Wait_TIME; //开启ISP/IAP;并送等待时间
ISP_CMD =Dele_COM; //送扇区擦除命令字
ISP_ADDRH=(uchar)(sector_addr >〉8); //送地址高字节
ISP_ADDRL=(uchar)(sector_addr&0X00FF);//送地址低字节
ISP_TRIG=0X46; //送触发命令字 0X46、0XB9
ISP_TRIG=0XB9;
_nop_();
ISP_IAP_disable(); //关闭ISP/IAP功能
EA=1;
}
/*********************写入函数**********************/
voidEEPROM_write(uint addr, ucharin_data)
{
Sector_erase(addr);
ﻩByte_program(addr,in_data);
}
/*********************EEPROM函数*******************/
/**************************************************/
/***************音乐播放相关子函数*******************/
/****************************************************/
voidInitialSound(void)ﻩ //初始化定时器
{
ﻩBeepIO =0;
Sound_Temp_TH1=(65535—(1/1200)*SYSTEM_OSC)/256;ﻩ// 计算TL1应装入的初值 ﻩ(10ms的初装值)
ﻩSound_Temp_TL1 =(65535-(1/1200)*SYSTEM_OSC)%256;//计算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;
}
/*********************END****************************/
/****************************************************/
/*****************LCD操作子函数**********************/
/****************************************************/
voidwrcomd(charcomd)ﻩ//写入命令
{
cs =0;_nop_();
rs=0;_nop_();
e =1;_nop_();
rw=0;_nop_();
P0=comd;_nop_();
rw = 0;_nop_();_nop_();
rw=1;_nop_();_nop_();_nop_(); _nop_();
}
voidwrdata(char data_wri)ﻩ//往液晶中写入数据
{
cs =0; _nop_();
rs =1;_nop_();
e=1;_nop_();
rw=0;_nop_();
P0=data_wri; _nop_();
rw =0;_nop_();_nop_();
rw=1;_nop_();_nop_();_nop_();_nop_();
}
voidbmp(chardata_write,introw_start,int row_end,uchar column_start,uchar column_end)//刷屏子函数ﻩ
//初始化设置,对屏幕清零,默认值,为0,0,8,2,132
{
unsignedchar i,j;
intnum_3;
char num_0=0xb0;
//ucharcolumn_h,column_l;
num_0+=row_start;
for(i=row_start;i〈row_end;i++)
{
num_3=column_end;
ﻩwrcomd(num_0);//写入命令设置页,从0页开始,0xb0=10110000;delay(time_def);//设置页ﻩ
ﻩwrcomd(0x10|(0xf0&column_start)>>4); //设置列,先写入高4位再写入低四位
wrcomd(0x00|(0x0f&column_start));
ﻩfor(j=column_start;j〈num_3;j++)
ﻩ{
ﻩ wrdata(data_write);
}
num_0++;
}
}
void delay(longinttime_delay)//延时子程序,执行time_delay个_nop_()延时
{
longinti;
for(i=0;i ﻩ _nop_(); } voidwrite_word(char*p_word,intnum,int pos_x,intpos_y,intwidth,intheight)//写汉字/字符子函数 ﻩﻩﻩ ﻩ //对应参数数据数组名,数组中位置,行位置,列位置,宽,高 { charpage;ﻩ//页号 unsignedinti,j,k,p; p=(unsignedint)num*2*width;ﻩ//p确定汉字字模数据初始位置 i= height%8; k=(i)? (height/8+1): (height/8); page=0xb0+ pos_y; for(i=0;i<2;i++) { wrcomd(page); ﻩ wrcomd(0x10|(0xf0&pos_x)>〉4); ﻩ wrcomd(0x00|(0x0f&pos_x)); for(j=0;j ﻩ { ﻩwrdata(p_word[j+p]);ﻩ ﻩﻩ} ﻩ p=p+width; page++; if(page-(unsignedchar)0xb0>7||page—(unsigned char)0xb0〈0) return; } } /**************************END***********************/ /****************************************************/ /******************键盘扫描函数*********************/ /****************************************************/ /****************判断是否有键盘输入*********************/ bit CheckState(void)//键盘状态判断子函数 { bitstate=0; ﻩP1=0x0F; //键盘扫描ﻩﻩ ﻩif(P1! =0x0F)state=1;//检测是否有按键输入 ﻩelsestate=0; ﻩreturn(state); } /******************获取键盘输入值*****************/ ucharGetKeys(void)ﻩ//键盘值获取子函数 { ucharcolumn,line; ﻩscan=0xFE; ﻩwhile((scan&0x10)! =0) { ﻩP1=scan; ﻩif((P1&0xF0)! =0xF0) //line 1 have keypressed ﻩ{ ﻩ ﻩcolumn=~(P1|0x0F); ﻩline=~(scan|0xF0); key=column+line; ﻩreturn(key);ﻩ ﻩ} ﻩﻩelsescan=(scan〈〈1)|0x01; ﻩ} ﻩreturn(0); } /******************应用子函数*****************/ /*********************************************/ voidcsh(void) //初始化,清屏 { int i; res=0;ﻩ delay(time_def); delay(time_def); res=1; delay(time_def); cs=0;//片选一直有效 delay(time_def); delay(time_def); for(i=0;i〈12;i++)ﻩ //初始命令写入 { wrcomd(tab1[i]); delay(time_def); } bmp(0,0,8,0,132); } void start_print(void)ﻩ//开机显示画面子函数 { inti,j; for(i=0;i〈4;i++) { write_word(star_welcome,i,36+i*16,2,16,16); if((i+4)〈7) ﻩ { ﻩ write_word(star_welcome,i+4,44+i*16,4,16,16); ﻩﻩ if((i+7)〈10) ﻩ{ ﻩﻩwrite_word(star_welcome,i+7,36+i*16,6,16,16); ﻩ } ﻩﻩ } } ﻩ write_word(number,10,4+5*16,6,8,16); for(j=5;j〉=0;j-—) { write_word(number,j,12+5*16,6,8,16); delay(5000); ﻩ} } voidmenu_first_symbol(intchoose) //菜单选择符刷新子函数,即“打钩项" { bmp(0,0,8,4,18);ﻩ write_word(menu_one,20,4,choose*2,16,16); } /*********************音乐播放显示函数******************/ /*******************************************************/ voidmusic_display_one(unsigned char s,unsigned intx) //显示最底层子函数 { inti; ﻩbmp(0,2,8,18+x*16,34+x*16); ﻩfor(i=3;i〉0;i-—) { if(s! =0) { write_word(display,1,20+16*x,2*i,16,16); s=s-1; } ﻩ else ﻩ { write_word(display,0,20+16*x,2*i,16,16); ﻩ//delay(200); } } } voidmusic_display_two(unsignedintp_x)//显示次底层子函数 { int sign; sign=mc_size[p_x][0]; if(sign) { if(! size[p_x]) ﻩ{ ﻩsign=0; ﻩ mc_size[p_x][0]=sign; ﻩmc_size[p_x][1]=0; ﻩ} else { music_display_one(size[p_x],p_x); mc_size[p_x][1]+=1; ﻩ if(mc_size[p_x][1]>3) ﻩ size[p_x]—=1; ﻩ else ﻩsize[p_x]+=1; } } /*************************************/ else { bmp(0,2,8,18+p_x*16,34+p_x*16);ﻩ write_word(display,2,20+16*p_x,6,16,16); //delay(500); } /************************************/ } voidmusic_display_three(unsignedintmc) //音符状态置位函数 { mc_size[mc—1][0]=1; mc_size[mc—1][1]=1; size[mc-1]=1; } void music_display_four(void)//显示次顶层子函数 { inti; for(i=0;i〈7;i++) { music_display_two(i); ﻩ} } voidmusic_display_five()//显示顶层子函数 { inti; allsize=0; for(i=0;i〈7;i++) allsize+=mc_size[i][0]; ﻩmusic_display_four(); } /* void music_display(void) //显示主函数 { inti; for(i=0;i<10;i++) { music_display_three(music_code[i]); music_display_five();ﻩ } while(allsize) music_display_five(); }*/ voiddisplay_between_musicplay(unsignedinttone) //播放音乐同时显示音符显示界面 { music_display_three(tone); music_display_five(); } /****************************************************/ /*********************播放子程序*********************/ voidmusic_play_one(uint *NewFreTab,uc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机课程设计报告 电子琴 单片机 课程设计 报告