51单片机的音乐跑马灯设计

合集下载

单片机闪烁灯跑马灯控制课程设计

单片机闪烁灯跑马灯控制课程设计

单片机闪烁灯跑马灯控制课程设计单片机闪烁灯跑马灯控制课程设计报告一、引言本课程设计旨在通过学习和实践单片机(MCU)编程,实现闪烁灯和跑马灯的控制。

我们将使用嵌入式C语言编程,通过了解单片机的内部结构、电路设计和编程流程,深入理解单片机的工作原理和应用。

二、系统硬件设计本课程设计选用51单片机作为主控芯片,外接8个LED灯和1个按键。

硬件电路设计如下:1.单片机:采用AT89C51,该芯片具有32K字节的Flash存储器,256字节的RAM,以及两个16位定时器/计数器。

2.LED灯:采用普通LED灯珠,与单片机引脚相连,通过编程控制LED灯的亮灭状态。

3.按键:采用机械按键,与单片机的外部中断0(EX0)相连,用于触发闪烁灯和跑马灯的切换。

三、系统软件设计1.闪烁灯模式:在此模式下,8个LED灯将按照一定的频率交替闪烁。

我们可以通过计时器和GPIO口控制LED灯的亮灭状态。

void blink_LED(void) {int i;while(1) {for(i = 0; i < 8; i++) {P1_0 = ~P1_0; // 翻转LED状态delay(500); // 延时,控制闪烁频率}}}2.跑马灯模式:在此模式下,8个LED灯将按照一定的顺序依次点亮。

我们可以通过计时器和GPIO口控制LED灯的亮灭状态。

void marquee_LED(void) {int i;int led_state[8] = {0, 1, 0, 1, 0, 1, 0, 1}; // LED状态数组,初始为交替亮灭while(1) {for(i = 0; i < 8; i++) {P1_0 = led_state[i]; // 设置LED状态delay(50); // 延时,控制跑马灯速度}}}四、按键处理程序我们通过外部中断0(EX0)接收按键信号,当按键按下时,将切换闪烁灯和跑马灯模式。

按键处理程序如下:void EX0_ISR(void) interrupt 0 { // EX0中断服务程序if (key_flag) { // 如果按键已经被按下过if (key_value == 0) { // 如果按键状态为低电平marquee_LED(); // 切换到跑马灯模式key_flag = 0; // 标记按键状态已经改变} else { // 如果按键状态为高电平blink_LED(); // 切换到闪烁灯模式key_flag = 0; // 标记按键状态已经改变}key_value = ~key_value; // 翻转按键状态值} else { // 如果按键还没有被按下过key_value = ~key_value; // 翻转按键状态值if (key_value == 0) { // 如果按键状态为低电平blink_LED(); // 切换到闪烁灯模式key_flag = 1; // 标记按键状态已经改变} else { // 如果按键状态为高电平marquee_LED(); // 切换到跑马灯模式key_flag = 1; // 标记按键状态已经改变}}}。

51单片机实用教程入门之跑马灯

51单片机实用教程入门之跑马灯

MCS-8051 单片机实用教程深圳伟凡数码 QQ:59059381上一节讲了 KEIL 软件的基本使用, 本节开始学习编程,编写第一个程序,如果从没学过的朋友不需要深入了解,只 要按照下面写出第一个程序。

好, 就来试试,很有意思的。

这里主要讲些技巧, 而不是专门的 C 语言,如过想学习更深入 的 C 语言, 请参考相关 C 语言书籍。

前面我们已经讲了怎样建立文件,这里就不多讲了。

按照下面动手写下面程序,当写好后, 我们就可以进行编译了, 点工具栏上的按钮或者 按键盘的功能键 F7 开始编译了,在最下面一个白色窗口显示编译结果, 0 Error(s)表示没有错误,正确的通过编译,0 Warning 表示 0 警告,这里 如果有 1 个或多个警告,并不影响程序的正确编译, 只是表明程序有多余的没有应用的程序。

下面表示程序已经正确的通过了. 如果你的也是这样的, 那就恭喜你成功了。

下面我们就来说说这个程序的基本知识,要记住的, a. 符号// 后面表示注释部分,或者程序的说明部分, 比如上面的程序名称, 日期等 b. /* */ 这个也是表示注释部分. 注意, 注释部分是不被编译的,注释是方便我们更能理解程序 c . #include<stdio.h> 这个表示头文件,表示我们要用到的函数或者定义,由#include<头文件名> 组成,编写规则头文件MCS-8051 单片机实用教程存深圳伟凡数码 QQ:59059382后面不能 有分号" ; ". #include<reg51.h> 也是头文件, 这是我们 51 单片机的头文件, 定义了单片机的特殊功能寄器的定义,我们可以打开头文件查看, 方法是: 将鼠标移动到文件名上, 点鼠标右键,出现以下菜单,点击蓝色部 分,这样就打开了 51 头文件。

打开 51 文件之后, 我们看到了对 51 单片机的端口定时器中断等进行了定义,想要了解含义,去看看单片机的资料, 这里不多讲。

单片机课程设计--跑马灯设计

单片机课程设计--跑马灯设计

单片机课程设计(跑马灯设计)专业:电气自动化摘要AT89C51是一种带4K字节闪存可编程可擦除只读存储器)(FPEROM—Flash Programmable and Erasable Read Only Memory 的低电压、高性能CMOS 8位微处理器,即单片机。

AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。

单片机的可擦除只读存储器可以反复擦除1000次。

该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。

该设计使用A T89C51芯片作为控制芯片,利用P1口连接8个发光二极管,通过I/O的值控制“跑马灯”的亮灭,以达到显示效果。

开始时所有灯全亮,按下按键S时开始跑马灯,再按下按键S时停止,再按下S时继续,并要求有多种亮暗组合。

时继续,并要求有多种亮暗组合。

按键跑马灯 按键单片机 跑马灯关键词:A T89C51单片机目录摘要 (I)第一章芯片分析和设计概述 (3)第一节 AT89C51芯片分析 (3)第一节第二节 设计概述 (8)第二节第二章硬件电路设计 (9)第三章程序部分设计 (10)参考文献 (18)第一章 芯片分析和设计概述第一节 AT89C51芯片分析ATMEL 的AT89S51是一种高效微控制器,将多功能8位CPU 和闪烁存储器组合在单个芯片中,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。

且价廉的方案。

AT89C51AT89C51的芯片引脚图如下:的芯片引脚图如下:图1.1 AT89C51引脚图引脚图各引脚的说明和功能分析如下:各引脚的说明和功能分析如下:VCC VCC:供电电压。

:供电电压。

:供电电压。

GND GND:接地。

:接地。

:接地。

P0口:口:P0P0口为一个8位漏级开路双向I/O 口,每脚可吸收8TTL 门电流。

当P1口的管脚第一次写1时,被定义为高阻输入。

时,被定义为高阻输入。

P0P0能够用于外部程序数据存储器,它可以被定义为数据外部程序数据存储器,它可以被定义为数据//地址的第八位。

51单片机8个跑马灯程序汇编设计思路

51单片机8个跑马灯程序汇编设计思路

【51单片机8个跑马灯程序汇编设计思路】1. 引言在嵌入式系统中,跑马灯程序是一个非常常见且基础的程序设计。

通过控制LED灯的亮灭顺序,实现灯光在一组灯中顺序轮流亮起的效果。

其中,51单片机是一种常用的嵌入式系统开发评台,本文将探讨如何通过汇编语言设计实现8个跑马灯程序的思路和方法。

2. 分析题目我们需要对题目进行细致的分析。

51单片机8个跑马灯程序要求我们设计并实现一个程序,能够控制8个LED灯依次轮流亮起的效果。

这意味着我们需要对LED灯进行控制,并且需要考虑如何实现循环、延时等功能。

3. LED灯控制在实现跑马灯程序时,首先需要考虑如何控制LED灯的亮灭。

一种常见的方法是通过I/O口控制LED灯的高低电平,从而实现灯的亮灭。

我们需要了解51单片机的I/O口控制方式,并结合LED灯的连接方式进行设计。

4. 循环控制跑马灯程序的核心在于实现LED灯的依次轮流亮起。

这就需要我们设计循环控制的程序结构。

在汇编语言中,可以通过跳转指令和计数器来实现循环效果,我们需要考虑如何设计循环的次数和顺序。

5. 延时控制为了让人眼能够观察到LED灯的亮灭效果,我们需要在程序中添加延时控制。

这需要我们了解51单片机的定时器控制和时钟频率,并根据LED灯的亮度要求设计合适的延时程序。

6. 汇编设计思路在进行汇编设计时,可以按照以下步骤进行:1)设置I/O口控制LED灯的引脚,确定LED的连接方式;2)设计循环控制结构,确定LED灯的顺序和次数;3)添加延时程序,控制LED灯亮灭的时间间隔;4)编写中断程序,处理定时器中断等事件;5)调试程序,验证跑马灯效果是否符合要求。

7. 个人观点和理解通过设计这个跑马灯程序,我深切体会到了汇编语言的精妙之处。

通过对硬件的直接控制和对程序结构的精心设计,我感受到了嵌入式系统开发中的乐趣和挑战。

而对于初学者来说,设计跑马灯程序也是一个很好的学习过程,可以加深对于51单片机结构和编程思想的理解。

跑马灯

跑马灯

基于C51单片机的跑马灯程序设计本文由仇看风雨贡献/************ 单片机学习板V1.0 ********************//*功能描述:跑马灯练习 */*//*功能:控制学习板上的8个LED显示 *//*接外部晶振11.0592 MHZ *//**************************************************///P0口控制8个LED 把学习板上的4位拨码开关的 1 拨到ON#include <reg51.h>#include <stdio.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned longvoid delay(unsigned int count);//延时程序void led_display(void);//LED显示子程序//数据模式 LED_DATA[0]显示次数 LED_DATA[1]显示速度LED_DATA[2]-[18]显示数据uchar codeLED_DATA1[18]={3,50,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0 x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00};//弹跳灯uchar codeLED_DATA2[18]={5,120,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3, 0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3};//双灯对撞模式uchar codeLED_DATA3[18]={5,80,0x00,0x81,0xc3,0xe7,0xff,0xe7,0xc3,0x81,0 x00,0x81,0xc3,0xe7,0xff,0xe7,0xc3,0x81};//拉链模式uchar codeLED_DATA4[18]={3,50,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0 xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00};//LED灯柱uchar codeLED_DATA5[18]={3,100,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa};//动感灯uchar codeLED_DATA6[18]={10,40,0xFF,0x00,0xFF,0x00,0xAA,0x00,0x55,0x00, 0x2A,0x00,0x54,0x28,0x00,0x28,0x00,0x10};//特殊爆闪uchar codeLED_DATA7[18]={10,50,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00};//爆闪/***************************延时子程序start***************************/void delay(unsigned int count){unsigned int i,j;for(j=0;j<120;j++);}/***************************延时子程序end***************************/void led_display(void){uchar i,j;/****************显示模式1**********************/ for(i=0;i<LED_DATA1[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA1[j];delay(LED_DATA1[1]);}}/**********************************************/ /****************显示模式2**********************/ for(i=0;i<LED_DATA2[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA2[j];delay(LED_DATA2[1]);}}/**********************************************/ /****************显示模式3**********************/ for(i=0;i<LED_DATA3[0];i++){P0=~LED_DATA3[j];delay(LED_DATA3[1]);}}/**********************************************/ /****************显示模式4**********************/ for(i=0;i<LED_DATA4[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA4[j];delay(LED_DATA4[1]);}}/**********************************************/ /****************显示模式5**********************/ for(i=0;i<LED_DATA5[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA5[j];delay(LED_DATA5[1]);}}/**********************************************/ /****************显示模式6**********************/for(i=0;i<LED_DATA6[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA6[j];delay(LED_DATA6[1]);}}/**********************************************/ /****************显示模式7**********************/ for(i=0;i<LED_DATA7[0];i++){ for(j=2;j<18;j++){P0=~LED_DATA7[j];delay(LED_DATA7[1]);}}/**********************************************/ }main(){P0=1;//清LEDwhile(1){led_display();//调用LED显示程序}}。

51单片机8个跑马灯程序设计思路

51单片机8个跑马灯程序设计思路

51单片机8个跑马灯程序设计思路单片机是一种集成电路,内部包含了计算机的主要组件,如中央处理单元(CPU)、存储器等。

通过编程,可以实现各种不同的功能。

在这里,我将以设计一个8个跑马灯的程序为例,来讲解单片机程序的设计思路。

1.硬件准备首先,我们需要准备一个适用于单片机的开发板,例如STC89C52,以及8个LED灯。

将LED灯连接到开发板的GPIO引脚上,并通过电阻进行限流。

使用跳线将GPIO引脚与LED灯的正极连接。

2.程序结构设计在单片机程序中,我们通常会使用循环结构。

因此,在设计跑马灯程序时,我们可以使用一个无限循环,来实现LED灯的闪烁效果。

具体的程序结构如下所示:```c#include <reg52.h>sbit led0 = P0 ^ 0; //第1个LED灯sbit led1 = P0 ^ 1; //第2个LED灯sbit led2 = P0 ^ 2; //第3个LED灯//...sbit led7 = P0 ^ 7; //第8个LED灯void mainwhile (1)//跑马灯代码}}```在这段代码中,我们首先引入头文件`reg52.h`,它包含了STC89C52的寄存器定义和常用函数的声明。

然后,我们定义了8个宏,用于表示8个LED灯所连接的引脚号。

接下来,在`main(`函数中,我们使用一个无限循环`while(1)`,来实现LED灯的闪烁效果。

3.跑马灯实现思路在无限循环中,我们需要通过对GPIO的控制来实现8个LED灯的闪烁。

具体的实现思路如下:- 首先,我们可以定义一个变量`index`,用于表示当前亮起的LED灯的索引值。

初始时,`index`的值为0,表示第一个LED灯亮起。

- 然后,我们可以使用`switch...case`语句来判断当前的`index`值,从而控制不同的LED灯亮起。

- 在每次循环中,我们可以通过对`index`的递增来实现灯的滚动效果。

单片机 跑马灯实验精选全文

单片机 跑马灯实验精选全文

可编辑修改精选全文完整版实验一跑马灯实验一、实验内容1、基本的流水灯根据图1电路,编写一段程序,使8个发光二极管D1、D2、D3、D4、D5、D6、D7、D8顺序(正序)点亮:先点亮D1,再点亮D2、D3……D8、D1……,循环点亮。

每点亮一个LED,采用软件延时一段时间。

2、简单键控的流水灯不按键,按正序点亮流水灯;按下K1不松手,按倒序点亮流水灯,即先点亮D8,再顺序点亮D7、D6……D1、D8……。

松手后,又按正序点亮流水灯。

3、键控的流水灯上电,不点亮LED,按一下K1键,按正序点亮流水灯。

按一下K2键,按倒序点亮流水灯,按一下K3键,全部关闭LED。

二、实验方案1、总体方案设计考虑到K4键未被使用,所以将实验内容中的三项合并到一个主函数中:K4键代替实验内容第二项中的K1键;单片机一开机即执行实验内容第一项;K1、K2、K3键实现实验内容第三项。

所用硬件:AT89C52、BUTTON、LED-BLUE、电源输入:P2.0-K1;P2.1-K2;P2.2-K3;P2.3-K4。

低电平有效输出:P0.0~P0.7-D0~D7。

LED组连线采用共阳极,低电平有效软件设计:软件延时采用延时函数delay(t),可调整延迟时间:void delay(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK&&P2!=K[0])break;//按下了其他键退出循环}}由于涉及到按键变化所以要设置一个变量oldK保留按键键值,要在延时程序中检测是否按键,当按键后立即设置oldK的值。

按键判断采用在while循环中利用条件语句判断P2的值然后执行该键对应的代码段,达到相应的响应。

为了让K4键的效果优化,即状态变化从当前已亮灯开始顺序点亮或逆序点亮,利用全局变量n来记录灯号,利用算法即可实现。

主要算法:1、全局变量的定义:uchar D[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0X7f};//单个LED亮uchar AllOff=0xff;//LED全灭uchar AllOn=0x00;//LED全亮uchar K[]={0xff,0xfe,0xfd,0xfb,0xf7};//按键开关uchar oldK;//记录已按键int n;2、顺序、逆序点亮流水灯:void forward(){for(n=0;n<=7;n++){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}void backward(){for(n=7;n>=0;n--){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}3、实验内容第二项流水灯灯亮顺序变换:void hold(){n=8;while(1){if(P2==K[4]){//一直按着K4键,逆序点亮跑马灯oldK=K[4];if(n==-1)n=7; //D0灯亮后点亮D7while(n>=0){out=D[n];n--;if(delay4(15))break;}}if(P2==K[0]){//未按下K4键,一直正序点亮跑马灯oldK=K[0];if(n==8)n=0;//D7灯亮后点亮D0while(n<=7){out=D[n];n++;if(delay4(15))break;}}if(P2!=K[4]&&P2!=K[0]){//按下了其他键,退出hold函数break;}}}4、对应实验内容第一项,开机顺序点亮流水灯:while(1){//开机即正序点亮流水灯forward();if(P2!=K[0]){break;}}2、实验原理图图2-1 实验原理图3、程序流程图图2-2 程序流程图三、源程序#include"reg51.h"#define uchar unsigned char#define uint unsigned int#define out P0uchar D[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0X7f};//单个LED亮uchar AllOff=0xff;//LED全灭uchar AllOn=0x00;//LED全亮uchar K[]={0xff,0xfe,0xfd,0xfb,0xf7};//按键开关uchar oldK;//记录已按键int n;//记录当前亮的灯号void delay(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK&&P2!=K[0])break;//按下了其他键退出循环}}void delay10ms(){uint i;for(i=0;i<10000;i++);}void forward(){for(n=0;n<=7;n++){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}void backward(){for(n=7;n>=0;n--){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}int delay4(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK){ //按键变化退出循环return 1;}}return 0;}void hold(){n=8;while(1){if(P2==K[4]){//一直按着K4键,逆序点亮跑马灯oldK=K[4];if(n==-1)n=7; //D0灯亮后点亮D7while(n>=0){n--;if(delay4(15))break;}}if(P2==K[0]){//未按下K4键,一直正序点亮跑马灯oldK=K[0];if(n==8)n=0;//D7灯亮后点亮D0while(n<=7){out=D[n];n++;if(delay4(15))break;}}if(P2!=K[4]&&P2!=K[0]){//按下了其他键,退出hold函数break;}}}void main(){oldK=K[0];while(1){//开机即正序点亮流水灯forward();if(P2!=K[0]){break;}}while(1){out=AllOff;if((P2&0x0f)!=0x0f){//检测有键按下delay10ms();//延时10ms再去检测//P2.0_K1键按下正序点亮流水灯if(P2==K[1]){oldK=K[1];while(1){forward();if(P2!=K[1]&&P2!=K[0]){//按下了其他键,退出break;}}}//P2.1_K2键按下逆序点亮流水灯if(P2==K[2]){while(1){backward();if(P2!=K[2]&&P2!=K[0]){//按下了其他键,退出break;}}}//P2.2_K3键按下关闭全部LEDif(P2==K[3]){oldK=K[3];out=AllOff;}//P2.3_K4键按下长按逆序点亮流水灯,不按正序点亮流水灯,直到其他键按下停止if(P2==K[4]){hold();}}}}四、实验结果1、基本的流水灯:开机后即重复顺序点亮流水灯,等待其他按键。

如何用51单片机数码管实现跑马灯功能?

如何用51单片机数码管实现跑马灯功能?

如何用51单片机数码管实现跑马灯功能?51单片机数码管显示跑马灯程序源代码讲解基于51单片机学习板。

用S1键作为控制跑马灯的方向按键,S5键作为控制跑马灯方向的加速度按键,S9键作为控制跑马灯方向的减速度按键,S13键作为控制跑马灯方向的启动或者暂停按键。

记得把输出线P0.4一直输出低电平,模拟独立按键的触发地GND。

(2)实现功能:跑马灯运行:第1个至第8个LED灯一直不亮。

在第9个至第16个LED灯,依次逐个亮灯并且每次只能亮一个灯。

每按一次独立按键S13键,原来运行的跑马灯会暂停,原来暂停的跑马灯会运行。

用S1来改变方向。

用S5和S9来改变速度,每按一次按键的递增或者递减以10为单位。

数码管显示:本程序只有1个窗口,这个窗口分成3个局部显示。

8,7,6位数码管显示运行状态,启动时显示“on”,停止时显示“oFF”。

5位数码管显示数码管方向,正向显示“n”,反向显示“U”。

4,3,2,1位数码管显示速度。

数值越大速度越慢,最慢的速度是550,最快的速度是50。

(3)源代码讲解如下:#include "REG52.H"#define const_voice_short 40 //蜂鸣器短叫的持续时间#define const_key_time1 20 //按键去抖动延时的时间#define const_key_time2 20 //按键去抖动延时的时间#define const_key_time3 20 //按键去抖动延时的时间#define const_key_time4 20 //按键去抖动延时的时间void initial_myself();void initial_peripheral();void delay_short(unsigned int uiDelayShort);void delay_long(unsigned int uiDelaylong);。

多模式带音乐跑马灯单片机课程设计说明书

多模式带音乐跑马灯单片机课程设计说明书

课程设计任务书题目: 多模式带音乐跑马灯设计初始条件:1.采用MCS51作为主控芯片;2.采用16个发光二极管做跑马灯,要求有5种灯亮方式,并带音乐; 3.可实现速度控制,显示当前模式号,可手动或自动切换模式。

要求完成的主要任务:1、查阅参考资料,自学相关可编程接口芯片的内部结构、工作方式和初始化编程过程;2、根据设计系统的具体功能和性能参数,明确设计目标;3、单片机系统及其扩展接口电路设计,绘制系统硬件原理图;4、编制系统控制源程序,绘制源程序流程图,包括初始化和监控程序;5、撰写设计说明书(包括参考资料目录,字数不少于5000字)时间安排:(两周)序号内容所用时间(天)1 查阅资料,学习相关芯片知识 22 系统及扩展电路硬件设计 33 初始化程序和应用程序设计 34 相关硬件电路和程序调试 35 课程设计答辩 1合计12指导教师签名: 2013年 12 月 27 日系主任(或责任教师)签名:年月日目录1、系统功能及需求分析及设计意义 (3)1.1 功能要求分析 (3)1.2 设计意义 (3)2、总体方案设计 (4)3、系统硬件部分分析及设计 (5)3.1 硬件总体设计 (5)3.2 硬件各部分设计说明 (5)3.2.1 主控芯片AT89C52 (5)3.2.2 跑马灯设计 (11)3.2.3 模式显示设计 (11)3.2.4 音乐播放设计 (12)3.2.5按键控制设计 (12)4、系统软件部分设计 (14)4.1 软件总体设计思路 (14)4.2 主程序说明 (14)4.3子程序说明 (17)4.4各个程序调用和被调用关系 (19)4.5编写程序时发现的问题 (19)5、总结与体会 (21)6、参考文献 (22)附录程序编写 (23)附录评分表 (39)1、功能需求分析及设计意义1.1 功能要求分析多模式带音乐跑马灯系统要求采用MCS51作为主控芯片,驱动16个发光二极管做5种模式跑马灯灯亮方式,并带有音乐;并且可实现速度控制,显示当前模式号,可手动或自动切换模式。

单片机跑马课程设计

单片机跑马课程设计

单片机跑马课程设计一、课程目标知识目标:1. 让学生掌握单片机的基本原理,理解跑马灯程序的设计思路。

2. 使学生了解单片机编程的基本语法和指令,并能运用到跑马灯程序编写中。

3. 帮助学生掌握跑马灯程序中涉及的电子元件使用方法,如LED灯、电阻等。

技能目标:1. 培养学生动手操作单片机的能力,能够独立完成跑马灯程序的下载、调试和运行。

2. 提高学生的问题解决能力,能够分析并解决跑马灯程序中可能出现的故障。

3. 培养学生的团队协作能力,能够在小组内分工合作,共同完成跑马灯项目的设计与实现。

情感态度价值观目标:1. 激发学生对单片机及电子制作的兴趣,培养其创新意识和探索精神。

2. 培养学生严谨、细心的学习态度,养成良好的编程习惯。

3. 增强学生的自信心,使其在跑马灯项目实践中感受到成功的喜悦。

本课程针对单片机跑马项目设计,结合学生年级特点,注重理论与实践相结合,旨在提高学生的动手能力、问题解决能力和团队协作能力。

课程目标具体、可衡量,为后续教学设计和评估提供明确方向。

二、教学内容1. 单片机基本原理:介绍单片机的组成、工作原理,引导学生了解和掌握单片机的基本功能和应用。

- 教材章节:第1章 单片机概述- 内容:单片机的发展历程、内部结构、工作原理。

2. 单片机编程基础:讲解单片机编程的基本语法、指令和编程环境,为学生编写跑马灯程序奠定基础。

- 教材章节:第2章 单片机编程基础- 内容:C语言基础、单片机指令系统、编程环境搭建。

3. 跑马灯程序设计:分析跑马灯程序的设计思路,教授编程技巧,让学生学会编写和调试程序。

- 教材章节:第3章 单片机程序设计实例- 内容:跑马灯程序设计原理、程序编写、调试方法。

4. 电子元件应用:介绍跑马灯项目中涉及的LED灯、电阻等元件的使用方法,指导学生进行电路搭建。

- 教材章节:第4章 电子元件及其应用- 内容:LED灯、电阻、杜邦线等元件的功能和连接方法。

5. 跑马灯项目实践:引导学生分组进行跑马灯项目的设计与实现,培养其动手能力、团队协作能力和问题解决能力。

MCS-51单片机控制跑马灯的三种方法

MCS-51单片机控制跑马灯的三种方法

MCS-51单片机控制跑马灯的三种方法
在MCS一51单片机的控制系统中,它的四个并行8位输入输出端口P0一P3是我们经常使用的。

在并行端口的编程学习中,跑马灯是单片机并行端口输出控制的典型实例。

所谓跑马灯,是指将八个发光二极管分别连接到单片机的某一并行端口的八根线上,通过编程控制这八个发光二极管从低到高或从高到低依次点亮。

图1 跑马灯电路图
如图1所示,将8个发光二极管阴极接到MCS一51单片机P1端口的8根端口线上,阳极通过限流电阻接+5V电源。

要让发光二极管点亮,则对应的端口线应该为低电平(0);而要让其熄灭,对应的端I=I线应该为高电平(1)。

由此,我们假定跑马灯由端I=1的低位向高位轮流点亮.可以得到如下状态:
表1 跑马灯状态表
从表1可以看出,P1端口的状态共有8种,在跑马灯的显示过程中.这8种状态依次出现,循环往复。

而要实现跑马灯的这种显示功能.我们可以采用三种方法:
(1)穷举法;
(2)移位法;
(3)查表法。

下面分别来介绍一下这三种方法。

一、穷举法对于单片机的显示状态来说,它的8种状态是循环显示的。

所谓穷举法。

是指将单片机所有的显示状态全部列举出来。

写在程序的主函数中,通过while(1)的死循环来实现这些状态的循环显示。

程序如下:
#include<reg51.h>//延时函数.延时0.5s
voiddelay()。

51单片机跑马灯程序编程高四位亮

51单片机跑马灯程序编程高四位亮

51单片机跑马灯程序编程高四位亮51单片机是一种非常常用的微控制器,它具有强大的功能和广泛的应用领域。

跑马灯是一种非常简单且常见的程序,可以用来展示LED灯在一组灯中依次亮起的效果。

在51单片机中实现跑马灯程序,可以通过控制IO口的状态来控制LED的亮灭。

假设我们有8个LED灯,要实现高四位亮的跑马灯效果,可以按照以下步骤进行编程:1. 首先,需要定义8个IO口作为LED灯的控制口。

假设我们将P0口的高四位作为控制LED的口,可以通过以下代码进行定义:```sbit LED1 = P0^4;sbit LED2 = P0^5;sbit LED3 = P0^6;sbit LED4 = P0^7;```2. 在主函数中,需要设置IO口的工作模式。

由于我们要控制LED亮灭,需要将相应的IO口设置为输出模式,可以通过以下代码实现:```LED1 = LED2 = LED3 = LED4 = 0; // 初始化为低电平P0M0 = P0M1 = 0; // P0口设置为推挽输出模式```3. 接下来,可以编写一个循环来实现跑马灯效果。

在每一次循环中,将高四位中的一个LED口设置为高电平,其他的LED口设置为低电平,通过不断循环改变高四位LED口的状态,从而实现跑马灯效果。

可以通过以下代码实现:```while (1) {LED1 = 1; // 第一个LED口亮LED2 = 0; // 其他LED口灭LED3 = 0;LED4 = 0;Delay(500); // 延时一段时间,控制灯的亮灭速度LED1 = 0; // 第一个LED口灭LED2 = 1; // 第二个LED口亮LED3 = 0;LED4 = 0;Delay(500);// 依次类推...}```通过以上代码,就可以在51单片机上实现高四位亮的跑马灯效果。

通过改变循环中的延时时间,还可以调节灯的亮灭速度。

此外,还可以通过调节亮灭的顺序,改变跑马灯的效果,使其更加多样化。

51单片机8个跑马灯程序汇编设计思路

51单片机8个跑马灯程序汇编设计思路

51单片机8个跑马灯程序汇编设计思路51单片机8个跑马灯程序汇编设计思路主题:51单片机8个跑马灯程序汇编设计思路引言:在微电子领域中,51单片机是应用最广泛的一种单片机。

它具有性能稳定、开发简单、存储容量大等特点,广泛应用于各种电子设备中。

其中,跑马灯程序是初学者最常接触的一个项目,通过实践该项目,我们可以提高对汇编语言的理解和应用能力。

本文将介绍51单片机8个跑马灯程序汇编设计的思路,以帮助读者更好地掌握该项目。

一、跑马灯程序的基本原理1.1 硬件设计51单片机跑马灯程序的实现需要使用LED灯和适当的电路连接。

我们可以选择使用8个LED灯,分别连接到IO口P0.0~P0.7上。

通过对IO口的控制,即可控制LED灯的亮灭。

1.2 软件设计在51单片机中,我们需要使用汇编语言来编写程序。

跑马灯程序的实现思路是通过对LED灯的逐个依次点亮和熄灭,实现灯光在各个LED之间不断左右滚动的效果。

通过不断循环该过程,即可实现跑马灯效果。

二、跑马灯程序的编写2.1 初始化设置在程序的开始部分,我们需要进行一些初始化设置。

需要设置IO口的工作模式,将所有IO口设置为输出模式。

需要设置定时器和中断相关的参数,以便后续的延迟操作。

2.2 跑马灯效果的实现跑马灯的实现思路可以分为两个部分:向左滚动和向右滚动。

2.2.1 向左滚动向左滚动的实现思路是依次点亮LED灯,然后通过适当的延迟时间熄灭LED灯,实现灯光的滚动效果。

在点亮一个LED灯之后,下一个LED灯便开始点亮。

通过循环该操作,即可实现向左滚动的效果。

2.2.2 向右滚动向右滚动的实现思路与向左滚动类似,只是点亮LED灯的顺序相反。

在点亮一个LED灯之后,上一个LED灯便开始点亮。

通过循环该操作,即可实现向右滚动的效果。

2.3 循环控制为了实现跑马灯的效果,我们需要将向左滚动和向右滚动两个操作循环执行。

通过添加一个计数器变量,当计数器达到一定的值时,切换滚动方向,实现跑马灯效果的循环。

51单片机的音乐跑马灯设计

51单片机的音乐跑马灯设计

摘要单片机技术是一门不可或缺的技术,对我们将来的工作以及生活和学习都有很密切的联系。

近年来,随着电子技术和微机计算机的迅速发展,单片机的档次不断提高,其应用领域也在不断的扩大,已在工业控制、尖端科学、智能仪器仪表、日用家电、汽车电子系统、办公自动化设备、个人信息终端及通信产品中得到了广泛的应用,成为现代电子系统中最重要的智能化的核心部件。

本设计使用AT89C52芯片,利用P0的8个端口连接8个发光二极管,P1的8个端口连接8个发光二极管,通过P0.0到P0.7的值和P1.0到P1.7的值控制“跑马灯”的亮灭,以达到显示效果。

设计的中断程序要对多个按键动作进行响应,灯光变换的花样有15种,用模式按钮切换。

按下模式按钮键,程序将按十五种模式切换,每按一次模式按钮键,切换一次跑马灯模式,而加速按钮和减速按钮可以改变闪烁速度;最后一种模式为音乐模式,加速按钮可切换音乐。

在单片机运行时,可以在不同状态下让跑马灯显示不同的组合,作为单片机系统正常的指示。

当单片机系统出现故障时,可以利用跑马灯显示当前的故障码,对故障做出诊断。

此外,跑马灯在单片机的调试过程中也非常有用,可以在不同时候将需要的寄存器或关键变量的值显示在跑马灯上,提供需要的调试信息。

关键词:音乐跑马灯;AT89C52单片机;74LS245驱动芯片;LED发光二极管1 设计概述 (1)1.1设计目的 (1)1.2设计作用 (1)1.3设计要求 (1)1.4系统设计框图 (1)2元器件介绍 (3)2.1AT89C52单片机 (3)2.2驱动芯片74LS245 (3)2.3其他元件及功能 (4)3 硬件电路设计 (6)3.1单片机最小系统 (6)3.2LED显示部分 (7)3.3按钮控制部分 (7)3.4数码管显示电路 (8)3.5蜂鸣器部分 (8)3.6系统总电路图 (9)4 软件设计 (10)4.1 程序流程图 (10)4.2 程序设计 (10)5 结束语 (32)参考文献 (33)1 设计概述1.1设计目的利用所学单片机的理论知识进行软硬件整体设计,培养学生分析、解决问题的能力,锻炼学生理论联系实际、综合应用的能力。

单片机课程设计跑马灯的控制

单片机课程设计跑马灯的控制

单片机课程设计跑马灯的控制摘要:本设计选择对跑马灯的控制,先构思跑马灯实现预想效果,然后进行分析,根据要求编写程序,选择硬件端口,并进行调试致预想效果,最后浅谈课程设计的经历,以及总结。

目录一)课程设计的目的二)课程设计的要求三)流程图四)原理图五)程序语言六)总结七)参考资料设计题目:试设计一个闪烁跑马灯控制器,该控制器可以控制8个灯顺序亮灭。

当单片机上电后,8个灯依次从左向右亮,并且每个灯亮的时间为1秒钟。

这时,如果按钮K1按下,则灯亮的顺序是从右向左,同样,每个灯亮的时间是1秒钟。

这时,如果按下按钮K2,则此时,4个灯亮4个灯灭,延迟4秒钟以后,又开始从左向右点亮。

最后,若按下按钮K3,则全部灯亮。

此时若想再次点亮灯,必须重新上电。

题目分析:该题目要求控制8盏灯的亮灭,可使用单片机的P1.0到P1.8口来控制。

按钮K1用P3.4口,K2用P3.2口,及外部中断0,K3用P3.3口,及外部中断1,分别来实现。

单片机使用AT89C52,电源使用5V标准电源。

顺序亮灭使用外部中断源构成循环控制语句。

一、课程设计的目的课程设计是本专业集中实践环节的主要内容之一。

训练正确地应用单片机,培养解决工业控制、工业检测等领域具体问题的能力。

学生通过所做课题,熟悉单片机应用系统开发研制的过程,软硬件设计的工作方法、内容及步骤,对学生进行基本技能训练。

例如组成系统、编程、调试、绘图等。

使学生理论联系实际,提高动手能力和分析问题、解决问题的能力。

通过本课程设计,主要达到以下目的:1.使学生增进对单片机的感性认识,加深对单片机理论方面的理解。

2.使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片内外存贮器、I/O口、串行口通讯等。

3.使学生了解和掌握单片机应用系统的软/硬件设计过程、方法及实现,为以后设计和实现单片机应用系统打下良好基础。

二、课程设计的要求1.学生需认真阅读课程设计任务书,熟悉有关设计资料及参考资料,熟悉各种设计规范的有关内容,认真完成任务书规定的设计内容。

基于AT89C51单片机的跑马灯电路课程设计

基于AT89C51单片机的跑马灯电路课程设计

目录1 实验目的 (1)2 元器件清单及简介 (1)3 设计原理及分析 (1)3.1 主要设计要求 (1)3.2 实验总流程图 (2)3.3 实验总图及说明 (3)4 实验中的问题与改进 (3)5 总结 (4)5.1 四级调速 (4)5.2 跑马灯闪烁方向的改变 (5)5.3 跑马灯循环闪烁灯的个数的改变 (6)6 实验分析与心得 (7)参考文献: (9)附录............................................... 错误!未定义书签。

基于AT89C51单片机的跑马灯电路课程设计1实验目的了解AT89C51管脚的基本功能,学会运用Proteus 7.7设计电路,学会运用汇编语言编写程序,来实现跑马灯的左右转换、0.1ms,0.25ms,0.5ms,1ms的四级变速、灯的闪烁个数为1,2,3,4等功能。

使用KEIL C51设计单片机程序,生成HEX文件,将程序烧录到AT89C51芯片中。

然后在实验电路中运行,调试。

2元器件清单及简介3设计原理及分析3.1主要设计要求1.灯的循环左右移动。

2.灯循环闪烁的个数可由1变到4。

3.灯循环闪烁的速度可变,分别是现0.1ms,0.25ms,0.5ms,和1ms的循环转变。

4.能在仿真图和面包板上进行实物运行并实现以上功能。

并能尽量节省器材。

3.2实验总流程图图1实验流程图3.3实验总图及说明图2 实验总图1.右边与P0口相连的8个灯采用上拉电阻方式,采用此方式是因为P0口驱动能力较大,且内部无上拉电阻,因此采用低电平驱动时,需加上拉电阻;且防止因电流过大而烧毁二极管。

2.左边依次与P1.0-P1.5的开关K0、K1、K2、K3、K4、K5,右边与P2.0-P2.3依次相连开关为K6、K7、K8、K9。

3.K0、K1控制灯的闪烁方向;K2、K3、K4、K5控制跑马灯闪烁的速度;K6、K7、K8、K9控制跑马灯灯闪烁的个数。

4.当有开关按下时相应的P口被置0,定时器中扫描P口程序扫描到相应P口为低电平,从而转到相应子程序执行,从而达到1所说功能。

基于单片机的跑马灯控制系统设计__课程设计__学士学位论文

基于单片机的跑马灯控制系统设计__课程设计__学士学位论文

江西环境工程职业学院大专毕业生毕业论文(毕业设计)题目: 基于单片机的可控制跑马灯的设计摘要单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。

而51单片机是各单片机中最为典型和最有代表性的一种。

本课程设计是基于MCS51系列单片机所设计的,用AT89S52芯片控制跑马灯(流水灯),整个系统有8种跑马灯模式可以选择,K1是选择模式键,并将相应的模式在LED七段数码管中显示出来,K2可以对跑马灯的速度进行加速,K3可以对跑马灯的速度进行减速。

整个系统可以实现对跑马灯模式的多层控制,还可以进行加减速。

关键词:MCS51、跑马灯、加减速、七段数码管目录摘要 (2)绪论 (4)第一章本设计意义和主要任务、内容概述 (5)1.1设计内容概述 (5)1.2设计的主要任务 (5)1.3设计要求 (5)第二章系统总体方案及硬件电路设计 (6)2.1 AT89C51的硬件结构 (6)2.2 AT89C51的工作模式 (9)2.3 AT89C51程序存储器的加密 (10)2.4 数码管显示原理 (10)2.5 单片机控制原理 (12)2.6 硬件电路设计 (13)第三章系统的软件设计 (14)3.1 程序流程图 (14)3.2 定时/计数器 (15)3.3 程序代码 (15)第四章总结 (16)致谢 (17)附录 (18)参考文献 (22)绪论在生活和生产的各领域中,凡是有制动控制要求的地方都会有单片机的身影出现;从简单到复杂,从空中、地面带地下,凡是能想象到的地方几乎都有使用单片机的需求。

现在尽管单片机的应用已经很普遍了,但仍有许多可以用单片机控制而没有实现的项目,因此,单片机的应用大有想象和拓展空间。

单片机的应用有利于产品的小型化、多功能化和智能化,有助于提高劳动效率,减轻劳动强度,提高产品质量,改善劳动环境,减少能源和材料消耗,保真安全等。

但是单片机应用的意义绝不仅限于它的广阔范围以及所带来俄经济效益上,更重要的意义还在于:单片机的应用正从根本上改变者传统的控制系统设计思想和设计方法。

51单片机走马灯实验报告

51单片机走马灯实验报告

微机原理及单片机应用实验实验报告实验跑马灯一、实验内容开关控制输出方式,共四种,开关拨到k1时奇数灯亮,开关拨到k2时偶数灯亮,开关k3时奇数偶数灯轮流亮,开关拨到k4时从左到右依次亮,开关拨到k5时从右到左依次亮。

二、实验步骤①依次L1-L8接入P1.0-P1,7,将P3接入高低电平开关②编程③实现三、实验原理图四.实验程序清单ORG 0000HPX00: MOV P1,#0FFH KEY : MOV A,#0FEHPO00: JB P3.0,PO01JNB P3.0,PO02PO01: MOV A,#055HMOV P1,ALJMP PO00PO02: JB P3.1,PO03JNB P3.1,PO04PO03: MOV A,#0AAHMOV P1,ALJMP PO00PO04: JB P3.2,PO05JNB P3.2,PO06PO05:MOV A,#0FEHK1:MOV P1,AJNB P3.2,LASTAJMP W1W1:RL ASJMP K1C1:MOV R6,#0A0HMOV R7,#0FFHK2:MOV R7,#0FFHK3:DJNZ R7,K3DJNZ R6,K2LJMP W1PO06:JB P3.3,PO07JNB P3.3,PO08PO07:MOV A,#7FHK4:MOV P1,AJNB P3.3, LASTAJMP W2W2: RR ASJMP K4C2: MOV R6,#0A0HMOV R7,#0FFHK5:MOV R7,#0FFHK6:DJNZ R7,K6DJNZ R6,K5LJMP W2PO08:JB P3.4,PO09JNB P3.4,LASTPO09:MOV A,#55HMOV P1,AMOV R6,#0A0HMOV R7,#0FFHK7:MOV R7,#0FFHK8:DJNZ R7,K8DJNZ R6,K7MOV A,#0AAHMOV P1,AMOV R6,#0A0HMOV R7 ,#0FFHK9:MOV R7,#0FFHK10:DJNZ R7,K10DJNZ R6,K9LJMP PO08LAST:MOV P1,#0FFHLJMP PO00END五、实验总结参考8255交通灯实验,加上延时程序以及查询式的跳转方法实现跑马灯。

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

摘要单片机技术是一门不可或缺的技术,对我们将来的工作以及生活和学习都有很密切的联系。

近年来,随着电子技术和微机计算机的迅速发展,单片机的档次不断提高,其应用领域也在不断的扩大,已在工业控制、尖端科学、智能仪器仪表、日用家电、汽车电子系统、办公自动化设备、个人信息终端及通信产品中得到了广泛的应用,成为现代电子系统中最重要的智能化的核心部件。

本设计使用AT89C52芯片,利用P0的8个端口连接8个发光二极管,P1的8个端口连接8个发光二极管,通过P0.0到P0.7的值和P1.0到P1.7的值控制“跑马灯”的亮灭,以达到显示效果。

设计的中断程序要对多个按键动作进行响应,灯光变换的花样有15种,用模式按钮切换。

按下模式按钮键,程序将按十五种模式切换,每按一次模式按钮键,切换一次跑马灯模式,而加速按钮和减速按钮可以改变闪烁速度;最后一种模式为音乐模式,加速按钮可切换音乐。

在单片机运行时,可以在不同状态下让跑马灯显示不同的组合,作为单片机系统正常的指示。

当单片机系统出现故障时,可以利用跑马灯显示当前的故障码,对故障做出诊断。

此外,跑马灯在单片机的调试过程中也非常有用,可以在不同时候将需要的寄存器或关键变量的值显示在跑马灯上,提供需要的调试信息。

关键词:音乐跑马灯;AT89C52单片机;74LS245驱动芯片;LED发光二极管1 设计概述 (1)1.1设计目的 (1)1.2设计作用 (1)1.3设计要求 (1)1.4系统设计框图 (1)2元器件介绍 (3)2.1AT89C52单片机 (3)2.2驱动芯片74LS245 (3)2.3其他元件及功能 (4)3 硬件电路设计 (6)3.1单片机最小系统 (6)3.2LED显示部分 (7)3.3按钮控制部分 (7)3.4数码管显示电路 (8)3.5蜂鸣器部分 (8)3.6系统总电路图 (9)4 软件设计 (10)4.1 程序流程图 (10)4.2 程序设计 (10)5 结束语 (32)参考文献 (33)1 设计概述1.1设计目的利用所学单片机的理论知识进行软硬件整体设计,培养学生分析、解决问题的能力,锻炼学生理论联系实际、综合应用的能力。

通过实践动手制作硬件和软件,综合应用本学期所学的单片机知识,达到加深学习该专业知识的目的。

1.2设计作用跑马灯是一种能像马儿一样跑的灯,就是利用单片机控制LED灯的闪烁方式使其就像马儿奔跑时马蹄的起落。

音乐跑马灯,就是在普通跑马灯的基础上加入了音乐,并通过喇叭将其在适当的时刻播放出来。

单片机的音乐跑马灯由16个LED发光二极管组成,在单片机系统中一般用来指示和显示单片机的运行状态。

通过程序控制使得单片机不同状态下的16个LED发光二级管显示不同的组合,以此显示单片机的工作状态,也可检查单片机是否发生故障。

当然,在实际生活中音乐跑马灯还有许多用处,其可以应用于各种建筑物、大楼、酒吧、KTV和夜总会等娱乐场所,可以制作出各种各样的炫目多彩的霓虹灯,为夜晚带来不一样的光彩。

1.3设计要求⑴有16个发光二极管做跑马灯,其中跑马灯有16种灯亮模式。

⑵有专门的键盘用以切换跑马灯的模式,并且对于任何一种跑马灯模式都可以对亮灯速度进行控制。

⑶每一种跑马灯模式用LED数码管进行显示。

⑷当跑马灯处于一种模式时,伴随的音乐响起,音乐有3首,并可以对其进行切换。

1.4系统设计框图基于AT89C52单片机的多模式带音乐的跑马灯控制系统由电路电源、单片机主控电路、模式切换以及调速按键控制电路、LED数码管显示电路和十六个发光二极管的跑马的电路几部分组成,系统框图如图1.1所示。

图1.1系统设计框图2元器件介绍2.1AT89C52单片机AT89C52是51系列单片机的一个型号,它是ATMEL公司生产的。

AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的AT89C52单片机可为您提供许多较复杂系统控制应用场合。

AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。

其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

AT89C52单片机如图2.1所示。

图2.1 AT89C52单片机2.2驱动芯片74LS24574LS245是我们常用的芯片,用来驱动LED或者其他的设备,它是8路同相三态双向总线收发器,可双向传输数据。

74LS245还具有双向三态功能,既可以输出,也可以输入数据。

当AT89C52单片机的P0口总线负载达到或超过P0最大负载能力时,必须接入74LS245等总线驱动器。

当片选端CE低电平有效时,BA=“0”,信号由 B 向 A 传输;AB=“1”,信号由 A 向B 传输;(发送)当CE为高电平时,A、B均为高阻态。

由于P2口始终输出地址的高8位,接口时74LS245的三态控制端1G和2G接地,P2口与驱动器输入线对应相连。

P0口与74LS245输入端相连, CE端接地,保证数据线畅通。

8051的RD和PSEN相与后接AB/BA,使得RD和PSEN有效时,74LS245输入(P0.1←D1),其它时间处于输出(P0.1→D1)。

74LS245驱动芯片如图2.2所示。

图2.2 74LS245驱动芯片2.3其他元件及功能⑴ LED发光二极管:指示和显单片机状态。

⑵扬声器:播放歌曲。

⑶按钮:模式按钮用于切换单片机工作模式,加速按钮用于加快LED灯的闪烁频率,减速按钮用于减缓LED灯的闪烁频率,复位按钮用于人工复位。

⑷数码管:用于显示单片机当前处于何种模式。

⑸晶体振荡器:用于构成单片机的复位电路。

⑹电容:用于构成单片机的复位电路。

⑺电阻:限流分压作用,是电路正常工作并保护电路。

元件清单如表2.1所示。

表2.1 元件清单3 硬件电路设计3.1单片机最小系统单片机最小系统或者称为最小应用系统,素质用最少的元件组成的单片机可以工作的系统,对51系列单片机来说,最小系统一般应该包括:单片机、复位电路、晶振电路。

复位电路:该复位电路采用手动复位和按键复位,所谓手动复位,是指通过接通一按钮开关,使单片机进入复位状态,使RST获得高电平,该方法可实现比较快速的复位。

当然,若不按下按钮,需等待电容充完电后使得RST获得高电平复位,复位电路如图3.1所示。

图3.1复位电路晶振电路:8051单片机的时钟信号通常用两种电路形式电路得到:内部震荡方式和外部中断方式。

在引脚XTAL1和XTAL2外部接晶振电路器(简称晶振)或陶瓷晶振器,就构成了内部晶振方式。

由于单片机内部有一个高增益反相放大器,当外接晶振后,就构成了自激振荡器并产生振荡时钟脉冲。

内部振荡方式的外部电路如下图所示。

其电容值一般在5~30pF,晶振频率的典型值为12MHz,采用6MHz的情况也比较多。

内部振荡方式所得的时钟信号比较稳定,实用电路使用较多。

晶振电路图如图3.2所示。

图3.2 晶振电路3.2LED显示部分显示部分,用十六个发光二极管通过总线和74LS245驱动芯片分别接到了AT89C52单片机的P0和P1口。

通过程序控制P0和P1的十六个端口按一定方式一次为低电平点亮端口LED。

若把P0口当作了通用的I/O口,则需要加上拉电阻,可是我们所采用的是使用总线方式输出因此不需要上拉电阻。

本设计采用的是发光二极管阳极接电源,因此要求P0口P1口输出低电平时,二极管才会发光。

LED显示部分如图3.3所示。

图3.3 LED显示部分3.3按钮控制部分用一个按钮进行模式的切换,即用该按钮控制多种不同的亮灯模式,分别有16种模式,从模式“0”至模式“F”,开启模式“F”是有音乐放出。

用一个按钮(加速按钮)进行发光二极管亮灯加速的调节,在第“F”模式时该按钮则可进行歌曲的切换。

用一个按钮(减速按钮)进行发光二极管亮灯减速的调节,在第9模式时该按钮则可进行歌曲的切换。

按钮控制部分如图3.4所示。

图 3.4 按钮控制部分3.4数码管显示电路数码管上分别显示0~F十六个数字,分别代表十六种模式。

采用共阳极连接,即数码管的a~f端要输入低电平时内部二极管才导通。

在数码管每个端口与74LS24 5驱动芯片与数码管之间连上100Ω的电阻。

数码管显示电路的具体硬件设计如图3.5所示。

图3.5 数码管显示电路3.5蜂鸣器部分蜂鸣器是一种将电信号转换成声音信号的电声元件。

确切的说,蜂鸣器工作实际上是把一定范围内的音频电功率讯号通过换能方式转变失真小并且有足够声压级的可听声音。

本课程设计直接将蜂鸣器街道单片机的P2.6端口,蜂鸣器具体电路如图3.6所示。

图3.6 蜂鸣器电路3.6系统总电路图音乐跑马灯的总电路图如3.7所示。

图3.7 音乐跑马灯总电路3.7操作说明在仿真软件中,按下屏幕左下角开始按键时,数码管显示为“0”,发光二极管以一定方式开始闪烁,此时按下模式按钮使得数码管显示为“1”时,发光二极管以一另种方式开始闪烁。

此时,若按加速按钮,则加快了发光二极管的闪烁速度,有4种不同的速度。

当加速到最大速度时,再按加速按钮则无法继续加速,此时可以按减速按钮进行减速。

以此类推,模式“1”到模式“E”,每种模式都给有一种闪烁方式。

当继续按模式按钮使的模式转换为模式“F”时,蜂鸣器开始放歌,发光二极管按照音乐音调变动闪烁。

此时的加速按钮可以进行歌曲的切换,按一次按钮换一首歌。

4 软件设计4.1 程序流程图该程序采用两个程序编写:第一个位单片机主程序,作用是使单片机完成相应上电功能;第二个是音乐产生程序,在第一个程序中包含第二个程序的头文件即可。

程序流程图如图4.1及4.2所示。

图4.1 主程序 图4.2 音乐程序流程图4.2 程序设计#include <REG52.H>//包括一个52标准的内核头文件//#include <SoundPlay.h> unsigned char RunMode;void Delay1ms(unsigned int Count) //延时子程序 {unsigned int i,j;for(i=0;i<Count;i++)for(j=0;j<1200;j++);}unsigned char code LEDDisplayCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //LED数码管void Display(unsigned char Value){P3=LEDDisplayCode [Value];} //数值输出至LED void LEDFlash(unsigned char Count){unsigned char i;bit Flag;for(i=0;i<Count;i++){Flag=!Flag;if(Flag)Display(RunMode);elseDisplay(0x10);Delay1ms(100);}Display(RunMode);}unsigned char GetKey(void) //判断按键是否按下{unsigned char KeyTemp,CheckValue,Key=0x00;CheckValue=P2&0x32;if(CheckValue==0x32)return 0x00;Delay1ms(10); //调用延时KeyTemp=P2&0x32;if(KeyTemp==CheckValue) return 0x00;if(!(CheckValue&0x02)) Key|=0x01;if(!(CheckValue&0x10)) Key|=0x02;if(!(CheckValue&0x20)) Key|=0x04;return Key;}unsigned int Timer0Count,SystemSpeed,SystemSpeedIndex;void InitialTimer2(void){T2CON=0x00;TH2=RCAP2H=0xfc;ET2=1; //定时器2中断允许TR2=1; //定时器2启动EA=1;}unsigned int code SpeedCode[]={1,100,500,1000};void SetSpeed(unsigned char Speed) //跑马灯速度控制{SystemSpeed=SpeedCode[Speed];}void LEDShow(unsigned int LEDStatus) //跑马灯的输出{P1=~(LEDStatus&0x00ff);P0=~((LEDStatus>>8)&0x00ff);}{RunMode=0x00;Timer0Count=0; SystemSpeedIndex=4;P1=0x00;P0=0x00;P2=0xff;P3=0x00;Delay1ms(500);P1=0xff;P0=0xff;P2=0xff;P3=0xff;SetSpeed(SystemSpeedIndex); Display(RunMode);}unsigned int LEDIndex=0;bit LEDDirection=1,LEDFlag=1; void Mode_0(void){LEDShow(0x0001<<LEDIndex); LEDIndex=(LEDIndex+1)%16; }void Mode_1(void){LEDShow(0x8000>>LEDIndex); LEDIndex=(LEDIndex+1)%16; }{if(LEDDirection)LEDShow(0x0001<<LEDIndex); elseLEDShow(0x8000>>LEDIndex);if(LEDIndex==15)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%16;}void Mode_3(void){if(LEDDirection)LEDShow(~(0x0001<<LEDIndex)); elseLEDShow(~(0x8000>>LEDIndex)); if(LEDIndex==15)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%16;}void Mode_4(void){if(LEDDirection){if(LEDFlag)LEDShow(0xfffe<<LEDIndex);elseLEDShow(~(0x7fff>>LEDIndex)); }{if(LEDFlag)LEDShow(0x7fff>>LEDIndex);elseLEDShow(~(0xfffe<<LEDIndex)); }if(LEDIndex==15){LEDDirection=!LEDDirection;if(LEDDirection)LEDFlag=!LEDFlag;}LEDIndex=(LEDIndex+1)%16;}void Mode_5(void){if(LEDDirection)LEDShow(0x000f<<LEDIndex); elseLEDShow(~(0xf000>>LEDIndex)); if(LEDIndex==15)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%16;}void Mode_6(void){if(LEDDirection)LEDShow(~(0x000f<<LEDIndex));LEDShow(~(0xf000>>LEDIndex)); if(LEDIndex==15)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%16;}void Mode_7(void){if(LEDDirection)LEDShow(0x003f<<LEDIndex); elseLEDShow(0xfc00>>LEDIndex);if(LEDIndex==9)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%10;}void Mode_8(void){LEDShow(++LEDIndex);}void Mode_9(void){LEDShow(0x0003<<LEDIndex); LEDIndex=(LEDIndex+1)%16;}void Mode_A(void){LEDShow(0xc000>>LEDIndex); LEDIndex=(LEDIndex+1)%16;}void Mode_b(void){if(LEDDirection)LEDShow(0x0003<<LEDIndex); elseLEDShow(0xc000>>LEDIndex); if(LEDIndex==15)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%16;}void Mode_C(void){if(LEDDirection)LEDShow(0x8080>>LEDIndex); elseLEDShow(0x0101<<LEDIndex); if(LEDIndex==7)LEDDirection=!LEDDirection; LEDIndex=(LEDIndex+1)%8;}void Mode_d(void){if(LEDDirection)LEDShow(0x1111<<LEDIndex); elseLEDShow(0x8888>>LEDIndex); if(LEDIndex==3)LEDDirection=!LEDDirection;LEDIndex=(LEDIndex+1)%4;}void Mode_E(void){if(LEDDirection)LEDShow(0x5555<<LEDIndex);elseLEDShow(0xaaaa>>LEDIndex);if(LEDIndex==3)LEDDirection=!LEDDirection;LEDIndex=(LEDIndex+1)%4;}void timer0eventrun(void) //模式选择{if(RunMode==0x00) {Mode_0();}else if(RunMode==0x01) {Mode_1();}else if(RunMode==0x02) {Mode_2();}else if(RunMode==0x03) {Mode_3();}else if(RunMode==0x04) {Mode_4();}else if(RunMode==0x05) {Mode_5();}else if(RunMode==0x06) {Mode_6();}else if(RunMode==0x07) {Mode_7();}else if(RunMode==0x08) {Mode_8();}else if(RunMode==0x09) {Mode_9();}else if(RunMode==0x0a) {Mode_A();}else if(RunMode==0x0b) {Mode_b();}else if(RunMode==0x0c) {Mode_C();}else if(RunMode==0x0d) {Mode_d();}else if(RunMode==0x0e) {Mode_E();}}void Timer2(void) interrupt 5 using 3 {TF2=0;if(++Timer0Count>=SystemSpeed) {Timer0Count=0;timer0eventrun();}}unsigned char MusicIndex=0;int MUSICNUMBER=3;void KeyDispose(unsigned char Key) {if(Key&0x01){LEDDirection=1;LEDIndex=0;LEDFlag=1;RunMode=(RunMode+1)%16;Display(RunMode);if(RunMode==0x0f)TR2=0;elseTR2=1;}if(Key&0x02){if(RunMode==0x0f){MusicIndex=(MusicIndex+MUSICNUMBER-1)%MUSICNUMBER;} else{if(SystemSpeedIndex>0){--SystemSpeedIndex;SetSpeed(SystemSpeedIndex);}else{LEDFlash(6);}}}if(Key&0x04){if(RunMode==0x0f){MusicIndex=(MUSICNUMBER+1)%MUSICNUMBER;}else{if(SystemSpeedIndex<3){++SystemSpeedIndex;SetSpeed(SystemSpeedIndex);}else{LEDFlash(6);}}}}unsigned char code Music_1[]={0x16,0x03,0x17,0x03,0x17,0x03,0x17,0x03,0x18,0x03, 0x19,0x02,0x16,0x03,0x17,0x03,0x18,0x02,0x18,0x03, 0x17,0x03,0x15,0x02,0x18,0x03,0x17,0x03,0x18,0x02, 0x10,0x03,0x15,0x03,0x16,0x02,0x15,0x03,0x16,0x03, 0x17,0x02,0x17,0x03,0x18,0x03,0x19,0x02,0x1a,0x03, 0x1b,0x03,0x1f,0x03,0x1f,0x03,0x17,0x03,0x18,0x03, 0x19,0x02,0x16,0x03,0x17,0x03,0x18,0x03,0x17,0x03, 0x18,0x03,0x1f,0x03,0x1f,0x02,0x16,0x03,0x17,0x03, 0x18,0x03,0x17,0x03,0x18,0x03,0x20,0x03,0x20,0x02, 0x1f,0x03,0x1b,0x03,0x1f,0x66,0x20,0x03,0x21,0x03, 0x20,0x03,0x1f,0x03,0x1b,0x03,0x1f,0x66,0x1f,0x03, 0x1b,0x03,0x19,0x03,0x1b,0x03,0x15,0x03,0x1a,0x66, 0x1a,0x03,0x19,0x03,0x15,0x03,0x15,0x03,0x17,0x03, 0x16,0x66,0x17,0x04,0x18,0x04,0x18,0x03,0x19,0x03, 0x1f,0x03,0x1b,0x03,0x1f,0x66,0x20,0x03,0x21,0x03, 0x20,0x03,0x1f,0x03,0x1b,0x03,0x1f,0x66,0x1f,0x03, 0x1b,0x03,0x19,0x03,0x19,0x03,0x15,0x03,0x1a,0x66, 0x1a,0x03,0x19,0x03,0x19,0x03,0x1f,0x03,0x1b,0x03, 0x1f,0x00,0x1a,0x03,0x1a,0x03,0x1a,0x03,0x1b,0x03, 0x1b,0x03,0x1a,0x03,0x19,0x03,0x19,0x02,0x17,0x03, 0x15,0x17,0x15,0x03,0x16,0x03,0x17,0x03,0x18,0x03, 0x17,0x04,0x18,0x0e,0x18,0x03,0x17,0x04,0x18,0x0e, 0x18,0x66,0x17,0x03,0x18,0x03,0x17,0x03,0x18,0x03, 0x20,0x03,0x20,0x02,0x1f,0x03,0x1b,0x03,0x1f,0x66, 0x20,0x03,0x21,0x03,0x20,0x03,0x1f,0x03,0x1b,0x03, 0x1f,0x66,0x1f,0x04,0x1b,0x0e,0x1b,0x03,0x19,0x03, 0x19,0x03,0x15,0x03,0x1a,0x66,0x1a,0x03,0x19,0x03, 0x15,0x03,0x15,0x03,0x17,0x03,0x16,0x66,0x17,0x04,0x1f,0x66,0x20,0x03,0x21,0x03,0x20,0x03,0x1f,0x03, 0x1b,0x03,0x1f,0x66,0x1f,0x03,0x1b,0x03,0x19,0x03, 0x19,0x03,0x15,0x03,0x1a,0x66,0x1a,0x03,0x19,0x03, 0x19,0x03,0x1f,0x03,0x1b,0x03,0x1f,0x00,0x18,0x02, 0x18,0x03,0x1a,0x03,0x19,0x0d,0x15,0x03,0x15,0x02, 0x18,0x66,0x16,0x02,0x17,0x02,0x15,0x00,0x00,0x03}; unsigned char code Music_2[]={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,0x22,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,0x03,0x19,0x0c,0x18,0x0d,0x17,0x03, 0x16,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,0x33,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};unsigned char code Music_3[]={0x17,0x03,0x16,0x03,0x17,0x01,0x16,0x03,0x17,0x03, 0x16,0x03,0x15,0x01,0x10,0x03,0x15,0x03,0x16,0x02, 0x16,0x0d,0x17,0x03,0x16,0x03,0x15,0x03,0x10,0x03, 0x10,0x0e,0x15,0x04,0x0f,0x01,0x17,0x03,0x16,0x03, 0x17,0x01,0x16,0x03,0x17,0x03,0x16,0x03,0x15,0x01, 0x10,0x03,0x15,0x03,0x16,0x02,0x16,0x0d,0x17,0x03, 0x16,0x03,0x15,0x03,0x10,0x03,0x15,0x03,0x16,0x01, 0x17,0x03,0x16,0x03,0x17,0x01,0x16,0x03,0x17,0x03, 0x16,0x03,0x15,0x01,0x10,0x03,0x15,0x03,0x16,0x02, 0x16,0x0d,0x17,0x03,0x16,0x03,0x15,0x03,0x10,0x03, 0x10,0x0e,0x15,0x04,0x0f,0x01,0x17,0x03,0x19,0x03, 0x19,0x01,0x19,0x03,0x1a,0x03,0x19,0x03,0x17,0x01, 0x16,0x03,0x16,0x03,0x16,0x02,0x16,0x0d,0x17,0x03, 0x16,0x03,0x15,0x03,0x10,0x03,0x10,0x0d,0x15,0x00, 0x19,0x03,0x19,0x03,0x1a,0x03,0x1f,0x03,0x1b,0x03, 0x1b,0x03,0x1a,0x03,0x17,0x0d,0x16,0x03,0x16,0x03, 0x16,0x0d,0x17,0x01,0x17,0x03,0x17,0x03,0x19,0x03, 0x1a,0x02,0x1a,0x02,0x10,0x03,0x17,0x0d,0x16,0x03, 0x16,0x01,0x17,0x03,0x19,0x03,0x19,0x03,0x17,0x03, 0x19,0x02,0x1f,0x02,0x1b,0x03,0x1a,0x03,0x1a,0x0e, 0x1b,0x04,0x17,0x02,0x1a,0x03,0x1a,0x03,0x1a,0x0e, 0x1b,0x04,0x1a,0x03,0x19,0x03,0x17,0x03,0x16,0x03, 0x17,0x0d,0x16,0x03,0x17,0x03,0x19,0x01,0x19,0x03, 0x19,0x03,0x1a,0x03,0x1f,0x03,0x1b,0x03,0x1b,0x03, 0x1a,0x03,0x17,0x0d,0x16,0x03,0x16,0x03,0x16,0x03, 0x17,0x01,0x17,0x03,0x17,0x03,0x19,0x03,0x1a,0x02, 0x1a,0x02,0x10,0x03,0x17,0x0d,0x16,0x03,0x16,0x01,0x17,0x03,0x19,0x03,0x19,0x03,0x17,0x03,0x19,0x03,0x1f,0x02,0x1b,0x03,0x1a,0x03,0x1a,0x0e,0x1b,0x04,0x17,0x02,0x1a,0x03,0x1a,0x03,0x1a,0x0e,0x1b,0x04,0x17,0x16,0x1a,0x03,0x1a,0x03,0x1a,0x0e,0x1b,0x04,0x1a,0x03,0x19,0x03,0x17,0x03,0x16,0x03,0x0f,0x02,0x10,0x03,0x15,0x00,0x00,0x00};unsigned char * SelectMusic(unsigned char SoundIndex){unsigned char * MusicAddress=0;switch(SoundIndex){case 0x00:MusicAddress=&Music_1[0];break;case 0x01:MusicAddress=&Music_2[0];break;case 0x02:MusicAddress=&Music_3[0];break;case 0x03:break;case 0x04:break;case 0x05:break;default:break;}return MusicAddress;}#ifndef __SOUNDPLAY_H_REVISION_FIRST__#define __SOUNDPLAY_H_REVISION_FIRST__#define SYSTEM_OSC 12000000 //定义晶振频率#define SOUND_SPACE 4/5//定义普通音符演奏长度分率,每四分音符间隔#define MUSICNUMBER 3 //歌曲的数目sbit BeepIO=P2^6; //定义输出引脚extern void LEDShow(unsigned int LEDStatus);extern unsigned char GetKey(void);extern void KeyDispose(unsigned char Key);extern void Delay1ms(unsigned int count);extern unsigned char MusicIndex;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应装入的初值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;}void Play(unsigned char *Sound,unsigned char Signature,unsigned int 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,Key,LEDFlash,OFFSet;for(i=0;i<12;i++) //根据调号及升降8度来生成新的频率表{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分音符的长度LDiv4=LDiv0/4; //算出4分音符的长度LDiv4=LDiv4-LDiv4*SOUND_SPACE; //普通音最长间隔标准TR0=0;TR1=1;while(Point<SoundLength){SL=TONE%10; //计算出音符SM=TONE/10%10; //计算出高低音SH=TONE/100; //计算是否升半LEDFlash=SM*((SL/2)+1)+2;LEDShow(~(0xFFFE<<LEDFlash));OFFSet=2;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%256;TH0=Sound_Temp_TH0;TL0=Sound_Temp_TL0+6; //对中断延时补偿}SLen=LengthTab[Length%10]; //算出是几分音符XG=Length/10%10; //算出音符类型FD=Length/100;LDiv=LDiv0/SLen; //算出连音音符演奏的长度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--) //发规定长度的音{OFFSet=(OFFSet+1)%5;LEDShow(~(0xFFFE<<(LEDFlash+OFFSet-2)));while(TF1==0){Key=GetKey();if(Key!=0x00){KeyDispose(Key);TR0=0;TR1=0;BeepIO=0;return;}}TH1=Sound_Temp_TH1;TL1=Sound_Temp_TL1;TF1=0;}}if(LDiv2!=0){TR0=0;BeepIO=0;for(i=LDiv2;i>0;i--) //音符间的间隔{OFFSet=(OFFSet+1)%5;LEDShow(~(0xFFFE<<(LEDFlash+OFFSet-2)));while(TF1==0){Key=GetKey();if(Key!=0x00){KeyDispose(Key);TR0=0;TR1=0;BeepIO=0;return;}}TH1=Sound_Temp_TH1;TL1=Sound_Temp_TL1;TF1=0;}}Point+=2;TONE=Sound[Point];Length=Sound[Point+1];}BeepIO=0;MusicIndex=(MusicIndex+1)%MUSICNUMBER; LEDShow(0x0001);Delay1ms(300);}void PlayMusic(void){Delay1ms(200);Play(SelectMusic(MusicIndex),0,3,360);}void main(){unsigned char Key;InitialCPU();InitialSound(); InitialTimer2();while(1){Key=GetKey();if(RunMode==0x0f){PlayMusic();}if(Key!=0x00){KeyDispose(Key);} }}#endif5 结束语通过单片机课程设计,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。

相关文档
最新文档