本题目为音乐流水灯的设计,目的是熟练掌握DSP定时器的控制、中断系统的应用以及程序的编写调试。
1、让DSP发出不同的音乐音调;
2、存储一个简单音乐(自选);
3、音乐的音调对应不同的灯
4、启动开关按下时,音乐流水灯开始运行,在播放音乐的同时,LED灯根据不同音调点亮;
5、按要求编写课程设计报告书,正确、完整的阐述设计和实验结果。
我们单片机的发声是通过蜂鸣器发出的,所以我们先了解一下蜂鸣器:
1.蜂鸣器介绍
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
压电式蜂鸣器主要由多谐振荡器、 压电蜂鸣片、 阻抗匹配器及共鸣箱、 外壳等组成。 多谐振荡器由晶体管或集成电路构成, 当接通电源后( 1.5~15V 直流工作电压),多谐振荡器起振,输出 1.5~5kHZ 的音频信号, 阻抗匹配器推动压电蜂鸣片发声。(无源蜂鸣器)
所以要使蜂鸣器发声,只需要频率在1.5到5khz之间即可
下面我们通过一个实验使DSP芯片发声:
打开ccs软件
1.新建一个项目:在我之前的博客写过
2.项目中的文件如下:(采用的是模块化编程),每个模块写好之后具有移植性

leds.c
#include "leds.h"
/*******************************************************************************
* 函 数 名         : LED_Init
* 函数功能         : LED初始化函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void LED_Init(void)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 开启GPIO时钟
    //LED1端口配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;//设置为通用GPIO功能
    GpioCtrlRegs.GPCDIR.bit.GPIO68=1;//设置GPIO方向为输出
    GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻
    //LED2端口配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO67=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO67=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO67=0;
    //LED3端口配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO66=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO66=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO66=0;
    //LED4端口配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO65=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO65=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO65=0;
    //LED5端口配置
    GpioCtrlRegs.GPCMUX1.bit.GPIO64=0;
    GpioCtrlRegs.GPCDIR.bit.GPIO64=1;
    GpioCtrlRegs.GPCPUD.bit.GPIO64=0;
    //LED6端口配置
    GpioCtrlRegs.GPAMUX1.bit.GPIO10=0;
    GpioCtrlRegs.GPADIR.bit.GPIO10=1;
    GpioCtrlRegs.GPAPUD.bit.GPIO10=0;
    //LED7端口配置
    GpioCtrlRegs.GPAMUX1.bit.GPIO11=0;
    GpioCtrlRegs.GPADIR.bit.GPIO11=1;
    GpioCtrlRegs.GPAPUD.bit.GPIO11=0;
    GpioDataRegs.GPCSET.bit.GPIO68=1;
    GpioDataRegs.GPCSET.bit.GPIO67=1;
    GpioDataRegs.GPCSET.bit.GPIO66=1;
    GpioDataRegs.GPCSET.bit.GPIO65=1;
    GpioDataRegs.GPCSET.bit.GPIO64=1;
    GpioDataRegs.GPASET.bit.GPIO10=1;
    GpioDataRegs.GPASET.bit.GPIO11=1;
    EDIS;
}
leds.h
#ifndef _LEDS_H_
#define _LEDS_H_
#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件
#define LED1_OFF        (GpioDataRegs.GPCSET.bit.GPIO68=1)
#define LED1_ON         (GpioDataRegs.GPCCLEAR.bit.GPIO68=1)
#define LED1_TOGGLE     (GpioDataRegs.GPCTOGGLE.bit.GPIO68=1)
#define LED2_OFF        (GpioDataRegs.GPCSET.bit.GPIO67=1)
#define LED2_ON         (GpioDataRegs.GPCCLEAR.bit.GPIO67=1)
#define LED2_TOGGLE     (GpioDataRegs.GPCTOGGLE.bit.GPIO67=1)
#define LED3_OFF        (GpioDataRegs.GPCSET.bit.GPIO66=1)
#define LED3_ON         (GpioDataRegs.GPCCLEAR.bit.GPIO66=1)
#define LED3_TOGGLE     (GpioDataRegs.GPCTOGGLE.bit.GPIO66=1)
#define LED4_OFF        (GpioDataRegs.GPCSET.bit.GPIO65=1)
#define LED4_ON         (GpioDataRegs.GPCCLEAR.bit.GPIO65=1)
#define LED4_TOGGLE     (GpioDataRegs.GPCTOGGLE.bit.GPIO65=1)
#define LED5_OFF        (GpioDataRegs.GPCSET.bit.GPIO64=1)
#define LED5_ON         (GpioDataRegs.GPCCLEAR.bit.GPIO64=1)
#define LED5_TOGGLE     (GpioDataRegs.GPCTOGGLE.bit.GPIO64=1)
#define LED6_OFF        (GpioDataRegs.GPASET.bit.GPIO10=1)
#define LED6_ON         (GpioDataRegs.GPACLEAR.bit.GPIO10=1)
#define LED6_TOGGLE     (GpioDataRegs.GPATOGGLE.bit.GPIO10=1)
#define LED7_OFF        (GpioDataRegs.GPASET.bit.GPIO11=1)
#define LED7_ON         (GpioDataRegs.GPACLEAR.bit.GPIO11=1)
#define LED7_TOGGLE     (GpioDataRegs.GPATOGGLE.bit.GPIO11=1)
void LED_Init(void);
#endif /* LED_H_ */
beep.c
#include "beep.h"
void BEEP_Init(void)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK=1;//开启GPIO时钟
    //BEEP端口配置
    GpioCtrlRegs.GPAMUX1.bit.GPIO6=0;
    GpioCtrlRegs.GPADIR.bit.GPIO6=1;
    GpioCtrlRegs.GPAPUD.bit.GPIO6=0;
    EDIS;
    GpioDataRegs.GPACLEAR.bit.GPIO6=1;
}beep.h
#ifndef BEEP_H_
#define BEEP_H_
#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件
#define BEEP_ON         (GpioDataRegs.GPASET.bit.GPIO6=1)
#define BEEP_OFF        (GpioDataRegs.GPACLEAR.bit.GPIO6=1)
#define BEEP_TOGGLE     (GpioDataRegs.GPATOGGLE.bit.GPIO6=1)
void BEEP_Init(void);
#endif /* BEEP_H_ */我们先了解一下音乐与单片机如何结合在一起的原理


 

通过这些频率取倒数,得到周期,再除以2,即得到一个音调高电平持续的时间。
下面是一些表格计算的周期时间:

 有了这些数据,我们便可以使用数组来存储这些值。
 有了这些数据,我们便可以使用数组来存储这些值。

 有关音乐的知识在这里就不再写了,大家可以百度上去查看,
最重要的是 音调加节奏
节奏就是一个音持续多长时间,这里我可以先简单说一下,
4分音符 8分音符 16分音符 2分音符
一般我们是以4分音符为标准,假如让它的时值为1,
那么2分音符就是它的时值的两倍。
8分音符的时值就是它的1/2。
16分音符的时值就是它的1/4.
这样每个音持续的时间我们也可以用一个1数组存起来。
下面我们以一闪一闪亮晶晶这首歌为例子

4/4表示的是以四份音符为一拍,每小节四拍
比如 1 1 5 5 都是四分音符,刚好四个合在一起为4拍。
—表示的声音的延长,如果与5结合的话,表示的是两拍。所以我们把四分音符定义为2的速度的··话,5-表示的四
下图所示即我们的音乐
Uint16 Song[]={1,1,5,5,6,6,5,4,4,3,3,2,2,1,5,5,4,4,3,3,2,5,5,4,4,3,3,2,22}; //一闪一闪亮晶晶
 Uint16 DT[]  ={2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4};      //节拍
我们课设的第三个任务是音乐的音调对应不同的灯,我们又写了一个函数,LEDx_TOGGLE表示的是LED翻转,我们通过a来控制
void ledSelect(int a)
{
    switch(a)
    {
        case 0: LED1_TOGGLE; break;
        case 1: LED2_TOGGLE; break;
        case 2: LED3_TOGGLE; break;
        case 3: LED4_TOGGLE; break;
        case 4: LED5_TOGGLE; break;
        case 5: LED6_TOGGLE; break;
        case 6: LED7_TOGGLE; break;
    }
}最后是与这句话连接在一起的,song是我们前面创建的歌曲的音调数组,addr从0开始,比如song[0]=1, 1+1=2, 2%7=2, 2-对应第三盏LED灯亮 也就是
do--3
re--4
mi--5
fa--6
sol-7
la--1
xi--2
ledSelect((Song[addr]+1) % 7);
addr++;main.c如下
#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "leds.h"
#include "key.h"
/*******************************************************************************
* 函 数 名         : main
* 函数功能         : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "leds.h"
#include "beep.h"
Uint16 Musi[23]={       //单位us,不同频率下,不同声调的声音
                0,      //静止符
                3816,   //L_do
                3496,   //L_re
                3215,   //L_mi
                2865,   //L_fa
                2551,   //L_so
                2272,   //L_la
                2024,   //L_xi
                1912,   //do
                1703,   //re
                1517,   //mi
                1432,   //fa
                1275,   //so
                1136,   //la
                1013,   //xi
                956,    //H_do
                851,    //H_re
                758,    //H_mi
                716,    //H_fa
                638,    //H_so
                568,    //H_la
                506,    //H_xi
                0xFF    //STOP
                };
//Uint16 Song[]={1,1,5,5,6,6,5,4,4,3,3,2,2,1,5,5,4,4,3,3,2,5,5,4,4,3,3,2,22}; //一闪一闪亮晶晶
//Uint16 DT[]  ={2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4};      //节拍
//Uint16 Song[]={5,5,6,5,8,7,5,5,6,5,8,7,5,5,5,10,8,7,6,11,10,8,9,8,22};    //祝你生日快乐
//Uint16 DT[]  ={2,2,5,4,6,8,2,2,5,6,6,9,4,2,5,4,6,12,2,2,5,6,8,12 };           //节拍
Uint16 Song[]={15,16,13,15,12,19,21,20,19,17,19,16,16,17,14,13,
               12,13,15,16,10,15,13,12,13,15,12,17,19,14,16,13,
               15,12,10,12,10,12,13,14,16,13,12,13,15,16,19,17,
               16,17,16,15,13,12,10,10,15,13,15,13,12,10,12,13,
               15,12,22};                                                   //梁祝
Uint16 DT[]  ={3,1,1,1,2,3,1,1,1,1,1,4,3,1,2,2,
               3,1,2,2,2,2,1,1,1,1,4,3,1,2,2,1,
               1,4,1,2,2,1,1,1,1,4,1,1,3,1,2,2,
               2,1,1,2,1,1,2,4,4,3,1,1,1,1,1,1,
               1,4};                                                        //节拍
Uint32 gain = 600000;//以600ms为一个四分音符的节拍,
void ledSelect(int a)
{
    switch(a)
    {
        case 0: LED1_TOGGLE; break;
        case 1: LED2_TOGGLE; break;
        case 2: LED3_TOGGLE; break;
        case 3: LED4_TOGGLE; break;
        case 4: LED5_TOGGLE; break;
        case 5: LED6_TOGGLE; break;
        case 6: LED7_TOGGLE; break;
    }
}
/*******************************************************************************
* 函 数 名         : main
* 函数功能         : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
    InitSysCtrl();
    LED_Init();
    BEEP_Init();
    KEY_Init();
    while(1)
    {
        Uint16 addr = 0;
        while(1)
        {
            if(Musi[Song[addr]] == 0xFF)//如果music到了停止符,
            {
                break;//跳出循环,停止播放音乐
            }
            else
            {
                Uint32 countTime = 0;//countTime来计算时间
                ledSelect((Song[addr]+1) % 7);
                while(countTime < gain * DT[addr])//
                {
                    if(countTime % Musi[Song[addr]] == 0)
                    BEEP_TOGGLE;//蜂鸣器响
                    countTime++;
                }
                ledSelect((Song[addr]+1) % 7);
                Uint32 i = 0;
                for(i = 0;i < gain; i++);
                addr++;
            }
        }
    }
}




![[深度学习]--分类问题的排查错误的流程](https://img-blog.csdnimg.cn/direct/9634d13b7f4340c5ba0e2579162b97e4.png)













