实验十单片机演奏乐曲实验 (1)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告十

一、实验目的

1.、进一步掌握51单片机定时计数器、中断以及通过I/O口的综合应用

2.、熟练掌握有多种中断源应用系统程序的编写和调试方法

二、实验内容

1、编程实现通过键盘选择演奏曲目,驱动实验板上的喇叭,完成乐曲的演奏。

2、完成该任务要求用两个定时器,一个负责控制发出音符对应频率信号,另一个负责控制每个音的持续时间(节拍),同时,要求外部中断接受用户用按键对乐曲选择,用一位数码管显示正在演奏的乐曲代号。程序要求设计成能重复选择。

C调常用音频及其对应频率如下表:

音符频率T值音符频率T值

7

SI 494 64603 5 So 784 64948

1 DO 523 64654 6 La 880 65012

2 Re 587 64751 7 Si 987 65069

3 Mi 659 64837 1 DO 1046 65095

4 Fa 698 6487

5 2 RE 1174 65143

三、实验相关说明

1

、实验电路原理图

开始

中断初始化,TR0=0,TR1=0

T1装50ms初值

数码管显示歌曲代码,不选择则显示0

Si按下?

分离出第i首歌的音符跟音长

T0装第i首歌音符初值

TR0=1,TR1=1

结束

外部中断1流程图: T0中断流程图: T1中断流程图:

实验程序:

#include

#define TH (65536-46080)/256 //定时50ms 初值 #define TL (65536-46080)%256

sbit s1=P3^4; //定义按键s1 sbit s2=P3^5; //定义按键s2 sbit buz=P2^5; //定义蜂鸣器 char

led_mod[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //七段数码管0~9的值 unsigned char code

song1[]={0x54,0x32,0x52,0x88,0x64,0x82,0x62,0x58,0x54,0x12, //送别音码表

0x22,0x34,0x22,0x12,0x2c,0x54,0x32,0x52,0x84,0x74,

0x64,0x84,0x58,0x54,0x22,0x23,0x44,0x74,0x1c,0x64,

开始

Si 按下?

Flag_si=1,save=i

结束

开始

TR0=0,buz=~buz 装第i 首歌第j 个音符初值

第j 个音符时间到?

j++,count=0

TR0=1

结束

开始

TR1=0

装50ms 初值

统计50ms 计数了多少次,每计数一次,count++

TR1=1

结束

0x84,0x88,0x74,0x62,0x72,0x88,0x62,0x72,0x82,0x62,

0x62,0x52,0x32,0x12,0x2c,0x54,0x32,0x52,0x84,0x74,

0x64,0x84,0x58,0x54,0x22,0x32,0x44,0x74,0x1c,0x00};

unsigned char

song2[]={0x01,0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81,0x91,0x00}; //第二首歌音码表

unsigned int

hz[]={64603,64654,64751,64837,64876,64948,65012,65069,65095,65143};

//各种音符计数初值

int a=0,b=0; //a为音码表的高位,b为音码表的低位

int k=0,j=0,count=0,flag_s1=0,flag_s2=0,save=0;

void init(); //中断初始化

void main()

{

P2=0x08; //关蜂鸣器

P3=0x08; //键盘扫描

init(); //中断初始化

TH1=TH; //装50ms初值

TL1=TL;

while(1)

{

P3=0x08; //键盘扫描

P0=led_mod[save]; //显示歌曲代码

if(k)

{

if(k==1) //S1键按下

{

a=song1[j]/16;

b=song1[j]%16;

TH0=hz[a]/256; //装初值

TL0=hz[a]%256;

}

if(k==2) //S2键按下

{

a=song2[j]/16;

b=song2[j]%16;

TH0=hz[a]/256; //装初值

TL0=hz[a]%256;

}

k=0;

TR0=1;

TR1=1;

}

}

}

void init() //中断初始化程序

{

IE=0x8e;

TCON=0x04;

IP=0x04;

TMOD=0x11;

TR0=0;

TR1=0;

}

void time1(void) interrupt 1 //TO中断{

TR0=0;

buz=~buz;

if(flag_s1==1) //S1键按下{

a=song1[j]/16;

b=song1[j]%16;

TH0=hz[a]/256; //装初值

TL0=hz[a]%256;

}

if(flag_s2==1) //S2键按下

{

a=song2[j]/16;

b=song2[j]%16;

TH0=hz[a]/256; //装初值

TL0=hz[a]%256;

}

if(count==5*b) //音长

{

count=0;

j++;

相关文档
最新文档