您的当前位置:首页正文

课程设计电子琴

2024-04-24 来源:好走旅游网
目录

摘要…………………………………………………………………………. 1 第一章 前言………………………………………………………………… 1 1.1 电子琴介绍……………………………………………………………... 1 1.2 课程设计简介…………………………………………………………… 1 第二章 课程设计目的及要求………………………………………………. 2 2.1 设计的目的……………………………………………………………… 2 2.2 课程设计要求…………………………………………………………… 2 第三章 硬件的设计与说明............................................................................. 2 3.1基本原理..................................................………………………………… 2 3.2单片机AT89C55介绍…………………………………………………….. 3 3.3 74LS373简介……………………………………………………………. 5 3.4 6264简介………………………………………………………………… 5 3.5各模块电路图……………………………………………………………… 6 第四章 系统软件设计………………………………………………………… 7 4.1音乐相关知识……………………………………………………………… 7 4.2 如何用单片机实现音乐节拍……………………………………………... 7 第五章 软件的调试…………………………………………………………… 9 5.1 keil调试成功的截图................................................................................... 9 5.2 prtoteus中的仿真图……………………………………………………….9 第六章 实物组装及调试……………………………………………………….10 6.1实物图……………………………………………………………………….10 6.2组装和调试………………………………………………………………… 10 第七章 心得体会……………………………………………………………….10 附录一………………………………………………………………………… 11 电路图…………………………………………………………………….... …..11 程序…………………………………………………………………………. ….11 元件清单……………………………………………………………………….. 18 附录二 参考文献……………………………………………………………… 18

摘要

电子琴不仅是儿童喜欢的玩具,而且还是开发儿童智能和培养儿童创造力的教具,具有宽广的市场。此次设计研发是基于单片机的有声光效果的简易电子琴,它具有弹奏和播放音乐的基本功能,还具有花样繁多的流水灯功能。该电路由 STC89C52RC 单片机、扬声器、LED 灯及一些微动按钮组成。具有低成本、结构简单、功能强大的优越特点,而且再加上软件的帮助,它的市场前景广大。

关键词:单片机 电子琴 STC89C52RC

Abstract

Keyboard is not only the children like toys and children's intelligence, or development and cultivate children's creative teaching AIDS, has the broad market. The design and development is based on SCM has the effects of sound simple keyboard, it has to play and play music of the basic functions, but also has the great variety of running water lamps function. The circuit by STC89C52RC SCM, speaker, LED lamp and a slightly move button composition. With low cost, simple structure, powerful superior characteristic, and coupled with the help of software, its market prospect broad.

Key words:Singlechip keyboard STC89C52RC。

第一章 前言

1.1 电子琴简介

电子琴又称作电子键盘,属于电子乐器(区别于电声乐器),发音音量可以自由调节。音域较宽,和声丰富,甚至可以演奏出一个管弦乐队的效果,表现力极其丰富。它还可模仿多种音色,甚至可以奏出常规乐器所无法发出的声音(如合唱声,风雨声,宇宙声等)。另外,电子琴在独奏时,还可随意配上类似打击乐音响的节拍伴奏,适合于演奏节奏性较强的现代音乐。另外,电子琴还安装有效果器,如混响、回声、延音,震音轮和调制轮等多项功能装置,表达各种情绪时运用自如。电子琴是键盘乐器,采用半导体集成电路,对乐音信号进行放大,通过扬声器产生音响。有多种类型。 使用五线谱,多为高低音双行记谱。有时也用中音谱。 电子琴是现代电子技术与音乐结合的产物,是一种新型的键盘乐器。它在现代音乐扮演着重要的角色,单片机具有强大的控制功能和灵活的编程实现特性,他已经融入现代人们的生活中,成为不可替代的一部分。单片机可以利用软硬件实现电子琴的功能,从而实现电子琴的微型化,可以用做玩具琴、音乐转盘及音乐童车等等。

1.2 课程设计简介

随着电子科技的飞速发展,电子技术正在逐渐改善人们的学习、生活、工作,因此开发本系统希望能够给人们多带来一点生活上的乐趣。基于当前市场上的玩具市场需求量大,其中电子琴就是一个很好的应用方面。单片机技术使我们可以利用软硬件实现电子琴的功能,从而实现电子琴的微型化,可以用作玩具琴、音乐转盘以及音乐童车等等。并且可以进行一定的功能扩展。鉴于传统电子琴可以用键盘上的“k0”到“k16”键演奏从低 So 到高 DO 等 16 个音,从而可以用来弹奏喜欢的乐曲。

单片机微型计算机是大规模集成电路技术发展的产物,属于第四代电子计算机,它具

有高性能、高速度、体积小、价格低廉、稳定可靠、应用广泛的特点。它的应用必定导致传统的控制技术从根本上发生变革。因此,单片机的开发应用已成为高科技和工程领域的一项重大课题。 基于单片机的电子琴设计

本文主要对使用单片机设计简易电子琴进行了分析,并介绍基于单片机电子琴系统硬件组成。利用单片机产生不同频率来获得我们要求的音阶,最终可随意弹奏想要表达的音乐。并且本文分别从原理图,主要芯片,各模块原理及各模块的程序的调试来详细阐述。

第二章 课程设计的目的及要求

2.1 设计目的

1、加强对单片机和C 语言的认识,充分掌握和理解设计各部分的工作原理、设计过程、选择芯片器件、模块化编程等多项知识。

2、用单片机模拟,使实现具体应用个人设计能够真正使用。

3、把理论知识与实践相结合,充分发挥个人能力,并在实践中锻炼自己。 4、提高利用已学知识分析和解决问题的能力。 5、提高实践动手能力。

2.2 课程设计要求

设计基于55单片机的电子琴电路,用μC/OS-II操作系统的移植代码。设计的电子琴可以有如下功能:

1、 可以完成弹奏和演奏两种功能

2、 按下弹奏按键可以开始弹奏,按某个按键就能发出相应音调的声音。 3、 按下演奏按键时就开始自动弹奏(生日歌)歌曲。

第三章 系统硬件设计及说明

3.1 基本原理

本设计基于单片机技术原理,以单片机芯片AT89C55作为核心控制器,通过硬件电路的制作以及软件程序的编制,设计制作出一个电子琴系统。整个设计包括两大部分:硬件部分和软件部分。硬件部分以单片机为核心,配以所需的外围模块设计;软件部分主要利用keil和proteus的联合编程达到硬件电路的设计要求。另外还需要μC/OS-II操作系统的移植代码。

该电子琴主要由键盘模块,弹奏和演奏转换按键模块,发生电路模块以及单片机的扩展模块组成。本设计以硬件软件为指导思想,充分发挥单片机功能,大部分功能通过软件编程来实现,电路简单明了,系统稳定性高。 3.2单片机AT89C55介绍

图一 AT89C55 PDIP封装芯片

AT89C55的是一种低功耗,高性能8位CMOS单片机,具有20K字节可重擦写Flash闪速存储器,该设备是采用Atmel的高密度非易失性内存技术,并与业界标准80C51指令集和引脚兼容,片上闪存程序存储器可重新编程的系统或由传统的非易失性内存编程通过将通用的8位CPU与Flash在monolithicchip芯片, AT89C55是一个强大的微型计算机提供了一个高度灵活和成本有效地解决许多嵌入式控制应用。

图二PDIP封装的AT89C55引脚图

AT89C52 为8 位通用微处理器,采用工业标准的C51 内核,在内部功能及管脚排布上与通用的8xc52 相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC 内部寄存器、数据RAM 及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR 的接收解码及与主板CPU 通信等。主要管脚有:XTAL1(19 脚)和XTAL2(18 脚)为振荡器输入输出端口,外接 12MHz 晶振。RST/Vpd(9 脚)为复位输入端口,外接电阻电容组成的复位电路。 VCC(40 脚)和VSS(20 脚)为供电端口,分别接+5V 电源的正负端。P0~P3 为可编程通用I/O 脚,其功能用途由软件定义,在本设计中,P0 端口(32~39 脚)被定义为N1 功能控制端口,分别与N1 的相应功能管脚相连接,13 脚定义为IR 输入端,10 脚和11 脚定义为I2C 总线控制端口,分别连接N1 的SDAS(18 脚)和SCLS(19 脚)端口,12 脚、27 脚及28 脚定义为握手信号功能端口,连接主板CPU 的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。

P0 口 P0 口是一组8 位漏极开路型双向I/O 口, 也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的 。

方式驱动8 个TTL 逻辑门电路,对端口P0 写“1”时,可作为高阻抗输入端用。 在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8 位)和数据总线复用,在访问期间激活内部上拉电阻。

在Flash 编程时,P0 口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。

P1 口

P1 是一个带内部上拉电阻的8 位双向I/O 口, P1 的输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻辑门电路。对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。与AT89C51 不同之处是,P1.0 和P1.1 还可分别作为定时/计数器2 的外部计数输入(P1.0/T2)和输入(P1.1/T2EX),Flash 编程和程序校验期间,P1 接收低8 位地址。

P2 口

P2 是一个带有内部上拉电阻的8 位双向I/O 口,P2 的输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻辑门电路。对端口P2 写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。在访问外部程序存储器或16 位地址的外部数据存储器(例如执行MOVX @DPTR 指令)时,P2 口送出高8 位地址数据。在访问8 位地址的外部数据存储器(如执行MOVX @RI 指令)时,P2 口输出P2 锁存器的内容。Flash 编程或校验时,P2 亦接收高位地址和一些控制信号。

P3 口

P3 口是一组带有内部上拉电阻的8 位双向I/O 口。P3 口输出缓冲级可驱动(吸收或输出电流)4 个TTL 逻 辑门电路。对P3 口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。此时,被外部拉低的P3 口将用上拉电阻输出电流(IIL)。

P3 口除了作为一般的I/O 口线外,更重要的用途是它的第二功能 。 P3 口还接收一些用于Flash 闪速存储器编程和程序校验的控制信号。

RST:复位输入。当振荡器工作时,RST 引脚出现两个机器周期以上高电平将使单片机复位。

ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8 位字节。一般情况下,ALE 仍以时钟振荡频率的1/6 输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。要注意的是:每当访问外部数据存储器时将跳过一个ALE 脉冲。对Flash 存储器编程期间,该引脚还用于输入编程脉冲(PROG)。如有必要,可通过对特殊功能寄存器(SFR)区中的8EH 单元的D0 位置位,可禁止ALE 操作。该位置位后,只有一条MOVX 和MOVC 指令才能将ALE 激活。此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE 禁止位无效。

PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89C52 由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN 有效,即输出两个脉冲。在此期间,当访问外部数据存储器,将跳过两次PSEN 信号。

EA/VPP:外部访问允许。欲使CPU 仅访问外部程序存储器(地址为 0000H—FFFFH),EA 端必须保持低电平(接地)。需注意的是:如果加密位LB1 被编程,复位时内部会锁存EA 端状态。如EA 端为高电平(接Vcc 端),CPU 则执行内部程序存储器中的指令。Flash 存储器编程时,该引脚加上+12V 的编程允许电源Vpp,当然这必须是该器件是使用12V 编程电压Vpp。

XTAL1:振荡器反相放大器的及内部时钟发生器的输入端。 XTAL2:振荡器反相放大器的输出端。

3.3 74LS373简介

74ls373是常用的地址锁存器芯片,它实质是一个是带三态缓冲输出的8D触发器,在单片机系统中为了扩展外部存储器,通常需要一块74ls373芯片。当74LS373用作地址锁存器时,应使OE为低电平,此时锁存使能端C为高电平时,输出Q0~Q7 状态与输入端D1~D7状态相同;当C发生负的跳变时,输入端D0~D7 数据锁入Q0~Q7。51单片机的ALE信号可以直接与74LS373的C连接。在MCS-51单片机系统中,常采用74LS373作为地址锁存器使用,其连接方法如上图所示。其中输入端1D~8D接至单片机的P0口,输出端提供的是低8位地址,G端接至单片机的地址锁存允许信号ALE。输出允许端OE接地,表示输出三态门一直打开。

图四 74LS373芯片图

3.4 6264简介

Intel 6264的容量为8KB,是28引脚双列直插式芯片,采用CMOS工艺制造 A12~A0(address inputs):地址线,可寻址8KB的存储空间。 D7~D0(data bus):数据线,双向,三态。 OE(output enable):读出允许信号,输入,低电平有效。 WE(write enable):写允许信号,输入,低电平有效。 CE1(chip enable):片选信号1,输入,在读/写方式时为低电平。 CE2(chip enable):片选信号2,输入,在读/写方式时为高电平。

VCC:+5V工作电压。 GND:信号地。

Intel 6264的操作方式由OE,WE, CE1 , CE2的共同作用决定

① 写入:当WE和CE1为低电平,且OE和CE2为高电平时,数据输入缓冲器打开,数据由数据线D7~D0写入被选中的存储单元。

② 读出:当OE和CE1为低电平,且WE和CE2为高电平时,数据输出缓冲器选通,被选中单元的数据送到数据线D7~D0上。

③ 保持:当CE1为高电平,CE2为任意时,芯片未被选中,处于保持状态,数据线呈现高阻状态。

图五 626芯片

3.5各模块电路图

键盘模块

图六 键盘模块电路图

弹奏和演奏转换按键模块

图七 弹奏和演奏转换按键电路图

发生电路模块

图八 单片机发生电路模块电路图 单片机扩展模块

图九 单片机扩展模块电路图

第四章

4.1 音乐相关知识

系统软件设计

乐音听起来有的高,有的低,这就叫音高,音高是由发音物体振动频率的高低决定的,频率高声音就高,频率低,声音就低,不同音调的乐音是用C、D、E、 F、G、A、B 表示的,这7 个字母就是乐音的音名,它们一般依次唱成DO、RE、 MI、FA、SO、LA、SI,这是唱曲时乐音的发音,所以叫唱名。 音持续时间的长短即时值,一般用拍数表示,休止符表示暂停发音。

4.2 如何用单片机实现音乐节拍

除了音符以外,节拍也是音乐的关键组成部分。 节拍实际上就是音持续时间的长短,在单片机系统中可以用延时来实现,如果1/4 拍的延时是0.4 秒,则1 拍的延时是1.6 秒,只要知道1/4 拍的延时时间,其余的节拍延时时间就是它的陪数。如果单片机要自己播放音乐,那么必须在程序设计中考虑到节拍的设置,由于本例实现的音乐发生器是由用户通过键盘输入弹奏乐曲的,所以节拍由用户掌握,不由程序控制。

开始 Zi_zou=1 Zi_zou=1? Tan_zou=1? tan_zou=1 Song(); 播放歌曲 Key_san() 键扫 Sound(),判断按键播放音调 结束 图十 主要流程图

第五章

5.1、 keil调试成功的截图

软件的调试

图十一 keil调试成功图

5.2 prtoteus中的仿真图

图十二 prtoteus中的仿真图

第六章 实物组装和调试

6.1 实物图

图十三 电子琴实物图

6.2 组装和调试

焊接过程是一个很复杂的过程,由于线路很多所以很容易出错。开始的时候我们就是因为单片机31号脚没有接电源导致不能运行。程序很复杂,在μC/OS-II操作系统中代码移植问题,后来还是和大家一同研究解决了问题。

第七章 心得体会

我们组的三个人在这次课程设计中都获得了很多。通过几年来对电路的设计和对单片机

的学习,使我们能顺利的完成这次课程设计。同时这次的论文也是对我们毕业论文的一次演练,所以这次课程设计真的是受益太多了。 在设计电路时我们遇到的难题就是扩张,后来在老师和同学的帮助下我们很好地完成了。同时以前我们对于嵌入式并不是很了解,通过这次实践我们有了一定的了解,虽然说不是很熟练但也得到了很大的提高。焊接电路是一个很复杂的过程,在这次试验中我负责电路的焊接,因为各个芯片引脚很多,所以焊接起来很复杂,有的时候很容易把引脚焊接到一起。这个过程也是对我们做事情要仔细认真的一个很好的考验,在这其中我就出现了错误,由于单片机的31号脚忘记了接电源所以导致调试不成功。这多很好的给我们上了一课。 这次课程设计过程中我也深刻的意识到课本知识的重要性,光有动手的能力不行还要很好的与理论结合。同时我也深深的感受到团队的重要性,在这其中我们小组分工明确,遇到难题大家一同解决。总的来说这真是一个一举多得的课程设计。

附录一 1、电路图

2、程序

#include #include

#define uchar unsigned char #define uint unsigned int

//****************************************************************** //* mytest system timer initial

#define TIME_10mS (OS_TICKS_PER_SEC /100) #define TIME_50mS (OS_TICKS_PER_SEC /20 ) #define TIME_100mS (OS_TICKS_PER_SEC /10 ) #define TIME_200mS (OS_TICKS_PER_SEC /5 ) #define TIME_500mS (OS_TICKS_PER_SEC /2 ) #define TIME_1S (OS_TICKS_PER_SEC)

#define TIME_2S (OS_TICKS_PER_SEC * 2) #define TIME_3S (OS_TICKS_PER_SEC * 3) #define TIME_4S (OS_TICKS_PER_SEC * 4) #define TIME_5S (OS_TICKS_PER_SEC * 5)

//****************************************************************** //* mytest system crystalloid

#define XA_CRYSTAL_FREQ (INT32U)(11059200L)

//****************************************************************** //* SCR crystalloid

#define CFG_SCR_4 SCR&0x03

#define CFG_SCR_16 SCR&0x07 #define CFG_SCR_64 SCR&0x0B #define OS_CFG_SCR CFG_SCR_4

//****************************************************************** //* mytest system

#define TASK_STK_SIZE 100//* 64 unsigned char

#define NUMBER_TASKS 20

//****************************************************************** //* mytest task stack define

//OS_STK xdata AnPrintfStk[TASK_STK_SIZE]; 任务堆栈即被创建

//OS_STK xdata BnPrintfStk[TASK_STK_SIZE]; OS_STK xdata key_scan[TASK_STK_SIZE];

OS_STK xdata zi_zou[TASK_STK_SIZE];

//****************************************************************** //* OS_EVENT

OS_EVENT xdata * AnPrintfWait; OS_EVENT xdata * BnPrintfWait; //sfr AUXR = 0X8E; sbit BEEP=P1^0;

sbit zi_zou_flag=P1^7; sbit tan_zou_flag=P1^6; uchar time;

uchar th0_f; //在中断中装载的T0的值的高8位

uchar tl0_f; //在中断中装载的T0的值的低8位

//****************************************************************** INT8U xdata OSCtxSwCtrMax;

//INT8U xdata AnPrintfData[] = \"louxiaoxiao1\\r\\n\"; //INT8U xdata BnPrintfData[] = \"louxiaoxiao2\\r\\n\";

unsigned char code yuepu[]={5,1,1, 5,1,1, 6,1,2, 5,1,2, 1,2,2, 7,1,4, 5,1,1, 5,1,1, 6,1,2, 5,1,2, 2,2,2, 1,2,4,

5,1,1, 5,1,1, 5,2,2, 3,2,2, 1,2,2, 7,1,2, 6,1,2, 4,2,1, 4,2,1, 3,2,2, 1,2,2, 2,2,2, 1,2,4}; unsigned

//祝你生日快乐乐谱

char code TH_0[]={

0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

//声明事件指针变量

//在创建任务的同时,

0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,

0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF} ; //28个音阶高八位频率表装进定时器高八位 unsigned char code TL_0[]={ 0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6, 0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,

0xEE,0x44, 0x6B,0xB4,0xF4,0x2D, 0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16}; /28个音阶低八位频率表装进定时器低八位 unsigned char code tone[]={115,102,91,86,77,68,61,57};

/*

unsigned char table[9] = \"21:33:56\"; unsigned char code addr_table[8][2] = {

};

0,0,0,4, 1,0,1,4, 2,0,2,4, 3,0,3,4

*/

//------------------------------------------------------------------- void TimeTickInitial(void);

void AnPrintf(void *dataptr); //* Startup Task void BnPrintf(void *dataptr); //* 8 Identical Tasks void delay(uchar t); void delay_ms(uint xms); void delay8us(uchar x); void sound(uchar x); void keyscan(); void zizou();

//void louxiaoxiao(void *padaptr); //void lcd_ds1302(void *padaptr);

//void Serial_initialize(void); //static void XAInit (void);

//static void TimerInit (INT8U tmr, INT16U freq, INT8U prio); //static void SeryComm0Init (INT16U baud);

//****************************************************************** //****************************************************************** void main() { OSInit();

BnPrintfWait = OSSemCreate(1); //建立一个信号量,从OSEventFreeList中申请一个ECB信号量

//并进行初始化(用ECB(Sem)->OSEventCnt);返回一个已初始化的ECB的指针

cnt

初始化

//初值为0 //以下创建两个任务 /建立第一个任务

//指向任务的指针

//传递给任务的参数

//任务不能被主程序调用,只能建立或激活

OSTaskCreate( keyscan, (void *)0,

(void *)&key_scan[TASK_STK_SIZE-1], //任务堆栈栈顶的指针 //上面的指针为0,递增,进栈操作向大地址方向发展,为TASK_STK_SIZE-1,递减,进栈操作向小地址方向发展0x07); /*

OSTaskCreate( AnPrintf, //建立第一个任务 //指向任务的指针

(void *)0, //传递给任务的参数

(void *)&AnPrintfStk[TASK_STK_SIZE-1], //任务堆栈栈顶的指针 //上面的指针为0,递增,进栈操作向大地址方向发展,为TASK_STK_SIZE-1,递减,进栈操作向小地址方向发展 0x06); //任务的优先级别 OSTaskCreate( BnPrintf, (void *)0,

//建立第二个任务

(void *)&BnPrintfStk[TASK_STK_SIZE-1], 0x05); */

OSTaskCreate( zizou,

//建立第二个任务

(void *)0,

(void *)&zi_zou[TASK_STK_SIZE-1], 0x04); TimeTickConfig(); OSStart();

//定时器0初始化 //开始多任务处理

}

/****************************************************************** /*******************************************************************

任务优先级的反转现象

在剥夺式OS中,当任务以独占方式使用共享资源时,低优先级的任务可能先于高优先级任务得到系统调度而运行的现象

备注:决定任务得到运行的条件不仅仅是优先级,还有任务所需的资源。 造成的结果:Task_B 优先于 Task_A 得到运行。

问题的严重性:如果Task_B之类的任务较多时,甚至会影响系统的设计目标。

原因:低优先级的任务独占共享资源,迫使高优先级任务因等待资源而让出CPU。

解决办法:暂时提升获得共享资源任务的优先级别,尽快释放共享资源,之后再恢复其原有的优先级别。

*******************************************************************/ void AnPrintf(void *dataptr) //A任务 {

//任务A的初始化

//INT8U i; INT8U err;

dataptr = dataptr; //任务A的循环体 while(1) {

OSSemPend(BnPrintfWait,0,&err); //请求信号量BnPrintfWait

keyscan();

OSSemPost(BnPrintfWait); OSTimeDlyHMSM(0,0,10,0); } }

void BnPrintf(void *dataptr) { INT8U err;

dataptr = dataptr; while(1) { }

void delay(uchar t) { uchar t1;

//B任务要等待A任务之后才执行

OSSemPend(BnPrintfWait,0,&err); //请求信号量BnPrintfWait

zizou();

OSSemPost(BnPrintfWait);

OSTimeDlyHMSM(0,0,20,0);

}

unsigned long t2; for(t1=0;t1{ for(t2=0;t2<8000;t2++) { ; } }

}

/****************************************************** * 唱歌子程序

**********************************************************/ /*

void song()

{ TH0=th0_f;

TL0=tl0_f;

// 唱歌程序

TR0=1; delay(time); // 延时,让此音节播放长短

TR0=0; // 关定时器,为下个音节响做准备

} */

/******************************************** * 延迟函数 * xms为延迟xms毫秒 *

***********************************************/ void delay_ms(uint xms) {

uint i,j;

for(i=xms;i>0;i--)

for(j=110;j>0;j--); }

/***********************************************

* 延迟8us

*************************************************/ void delay8us(uchar x) {

uchar i,j;

for(i=0;i}

/********************************************** * 用于弹奏时八个音符(阶)的发音

************************************************/ void sound(uchar x) {

uchar i;

for(i=0;i<120;i++) { }

BEEP=0;

delay8us(tone[x]); BEEP=1;

delay8us(tone[x]);

}

/********************************************** * 键扫:

****************************************************/ void keyscan() {

uchar temp; while(1) {

if (!tan_zou_flag) {

P2=0Xff; temp=P2;

temp=0xff&temp; if(temp!=0xff) {

delay_ms(10); temp=P2;

temp=0xff&temp; if(temp!=0xff)

{

temp=P2;

switch(temp)

}

{ }

while(temp!=0xff) {

temp=P2;

temp=temp&0xff;

//按键没放开一直发声

case 0x7f: sound(7);break; case 0xbf: sound(6);break; case 0xdf: sound(5);break; case 0xef: sound(4);break; case 0xf7: sound(3);break; case 0xfb: sound(2);break; case 0xfd: sound(1);break; case 0xfe: sound(0);break;

}

} }

OSTimeDlyHMSM(0,0,2,0);

} }

void zizou() {

uchar k,i;

while(1) {

if(!zi_zou_flag) { i=0;

while(i<75) { }

if(zi_zou_flag) { }

k=yuepu[i]+7*yuepu[i+1]-1; th0_f=TH_0[k]; tl0_f=TL_0[k]; time=yuepu[i+2]; i+=3; song();

BEEP=1; break;

//自奏,实现生日歌的自动弹奏

//

//

}

}

}

OSTimeDlyHMSM(0,0,2,0);

3、元件清单 组件 STC89C55 6264 74LS373 数量 一片 一个 一个 一个 10个 一个 若干 若干 组件 30pF瓷片电容 数量 两个 11个 一个 一个 三个 一个 一个 一个 10K电阻 PNP普通三极管 11.0592M晶振 蜂鸣器 按键 5v电源 芯片底座 10uf极性电容 排针 排插

附录二 参考文献

电源接口 5电源 [1] Jean J Labrosse.嵌入式实时操作系统μC/OS-II[M].邵贝贝译.北京:北京航空航天大学出版社,2003.

[2] 任哲.嵌入式实时操作系统μC/OS-II原理及应用[M].北京:北京航空航天大学出版社,2003.

[3] 沈睿. μC/OS-Ⅱ在DSP2407 上若干移植问题的研究[J].中国水运,2007,5(5)::43-44.

[4] 马忠梅编著.单片机的C语言应用程序设计[M].北京:北京航空航天出版社,2OO3.

[5] 徐灵伟,刘飞.基于μC/OS-Ⅱ的嵌入式中断实现与扩展[C].北京:中国控制与决策学会,2007 :999-1002

[6] 何立民. 单片机高级教程-应用与设计[M]. 北京: 北京航空航天大学出版社, 2000. 8: 103-109.

[7] 李建忠. 单片机原理与应用[M]. 西安: 西安电子科技大学出版社, 2002,2: 121-123. [8] 戴佳, 苗龙, 陈斌. 51单片机应用系统开发典型实例[M], 北京: 中国电力出版社, 2005,7: 121-137.

[9] 张洪润, 易涛. 单片机应用技术教程[M]. 北京: 清华大学出版社, 2003,10: 119-122. [10] 蔡朝洋. 单片机控制实习与专题制作[M].北京: 北京航空航天大学出版社, 2006,11: 317-323.

因篇幅问题不能全部显示,请点此查看更多更全内容