嵌入式课程设计报告

福州大学

课程设计任务书

    课    程:         嵌入式课程设计                  

    题    目:           简易电子琴                              

    姓    名:             李仁煌                      

学    号:           011000610                         

系    别:           电机电器                  

专    业:        电气工程与自动化              

年    级:              20##                    

   起讫日期:       2013.6.10-2013.7.4            

指导教师:             王武                       

                

  

1、课程设计目的............................................................................... 2

2、课程设计题目和实现目标............................................................ 2

3、设计方案.............................................................................................................. 2

4、程序流程图................................................................................... 3

5、实物图.......................................................................................... 4

6、程序代码..............................................................................................4

7、设计心得体会......................................................................................4

8、附录.....................................................................................................5

 

1、   课程设计目的

嵌入式系统设计课程设计是与嵌入式系统设计课程相配套的实践教学环节。嵌入式系统设计是一门实践性很强的专业基础课,通过课程设计,达到进一步理解单片机的硬件、软件和综合应用方面的知识,培养实践能力和综合应用能力,开拓学习积极性、主动性,学会灵活运用已经学过的知识,并能不断接受新的知识。培养大胆发明创造的设计理念,为今后就业打下良好的基础。此次单片机课设为了培养我们对单片机应用系统总体方案的设计,硬件的设计,软件程序的设计以及对单片机的调试能力的培养。

    

2、课程设计题目和实现目标 

课程设计的题目为电子琴。实现目标是设计出来的电子琴具有14个能播放14个音调的按键。

3、设计方案

1 按键扫描模块 

   电子琴设有16个按键作为音符输入。14个按键分别代表14个音符,包括低音和中音段的全部音符。通过软硬件设计,使系统不断扫描按键接入的对应的引脚电平的高低,扫描结束时,以变量形式存放扫描结果,当变量显示为有按钮跳转,转入不同情况的程序段中。

2 播放模块

 当系统扫描到播放按钮时,如果判断为播放功能而不是停止播放功能,则启动定时器,通过计时器中断来设置输出PWM波的频率,即可改变蜂鸣器的音调,同时还在中断程序中改变定时器的计数值,从而使定时时间发生改变,在蜂鸣器上表现为发声时间长短。当扫描到的是停止播放功能时,则使定时器停止计数,PWM关闭蜂鸣器停止播放。播放模块是由蜂鸣器和PWM构成,PWM输出一定频率的方波,驱动蜂鸣器发声,蜂鸣器几乎不存在噪声,音响效果较好,而且由于所需驱动功率较小,且价格低廉,所以,被广泛应用。

4、程序流程图

5、实物图

6、调试总结

在调试过程中,首先要做好硬件调试,然后再进行软硬件共同调试。所以第一步需要检查各硬件的完好性,其次检测各芯片的电源线和地线是否接触良好,接好电源后用万用表检测各电源端、地端的状态是否正常。检查无误后通过烧写工作程序,根据显示现象调试程序直至成功。 

在编写程序前,首先应该将各部分硬件原理全部理解,尤其重要的是要掌握各元件的使能方式,是低电平使能还是高电平使能。当这些基础问题都不再出错的时候,然后才能逐步编写程序

7、设计心得体会

     

我从本次嵌入式综合设计中学到了很多,对于嵌入式系统有了更深入的了解与应用。通过模块化的设计过程我对F28027芯片的知识有了了解,并且能在原始程序的基础上做小的改动,使其更适用于简易电子琴系统,对于课本知识也有了实战性操作,在此过程中我的应用知识能力、设计能力、调试能力以及报告撰写能力等方面有了显著提高。

8附录

#include "DSP28x_Project.h"

#include "f2802x_common/include/clk.h"

#include "f2802x_common/include/flash.h"

#include "f2802x_common/include/gpio.h"

#include "f2802x_common/include/pie.h"

#include "f2802x_common/include/pll.h"

#include "f2802x_common/include/pwm.h"

#include "f2802x_common/include/cap.h"

#include "f2802x_common/include/timer.h"

#include "f2802x_common/include/wdog.h"

// Prototype statements for functions found within this file.

void InitEPwm1();

void InitECapture();

void InitTime0();

void scanning();

void yindiao();

interrupt void cpu_timer0_isr(void);

interrupt void ecap1_isr(void);

//Global variables used in this project:

int     play=0;//play flag

int     record=0;//record flag

int     f[100];

int     k=0;

int     l=0;

int     flag=0;

int     flag1=0;

uint32_t   rhy[202];

uint32_t   scan=0;//the scanning data

uint32_t   scan1,scan2,scan3,scan4;

enum    yin{A=3822,B=3405,C=3034,D=2863,E=2551,F=2273,G=2025,A1=1911,B1=1702,C1=1516,D1=1431,E1=1275,F1=1136,G1=1012};

CAP_Handle myCap;

CLK_Handle myClk;

FLASH_Handle myFlash;

GPIO_Handle myGpio;

PIE_Handle myPie;

PWM_Handle myPwm1;

TIMER_Handle myTimer;

void main(void)

{

    CPU_Handle myCpu;

    PLL_Handle myPll;

    WDOG_Handle myWDog;

    // Initialize all the handles needed for this application

    myCap = CAP_init((void *)CAPA_BASE_ADDR, sizeof(CAP_Obj));

    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));

    myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));

    myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));

    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));

    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));

    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));

    myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj));

    myTimer = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));

    myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    // Perform basic system initialization

    WDOG_disable(myWDog);

    //Select the internal oscillator 1 as the clock source

    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

    // Setup the PLL for x1 /1 which will yield 10Mhz = 10Mhz * 1 / 1

    PLL_setup(myPll, PLL_Multiplier_1, PLL_DivideSelect_ClkIn_by_1);

    // Disable the PIE and all interrupts

    PIE_disable(myPie);

    PIE_disableAllInts(myPie);

    CPU_disableGlobalInts(myCpu);

    CPU_clearIntFlags(myCpu);

    // If running from flash copy RAM only functions to RAM

#ifdef _FLASH

    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

#endif

    // Initalize GPIO

    GPIO_setMode (myGpio, GPIO_Number_4, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_2, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_3, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_6, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_7, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_16, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_17, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_18, GPIO_0_Mode_GeneralPurpose);

    GPIO_setMode (myGpio, GPIO_Number_19, GPIO_0_Mode_GeneralPurpose);

    GPIO_setDirection(myGpio, GPIO_Number_4, GPIO_Direction_Output);

    GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Input);

    GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Input);

    GPIO_setDirection(myGpio, GPIO_Number_6, GPIO_Direction_Input);

    GPIO_setDirection(myGpio, GPIO_Number_7, GPIO_Direction_Input);

    GPIO_setDirection(myGpio, GPIO_Number_16, GPIO_Direction_Output);

    GPIO_setDirection(myGpio, GPIO_Number_17, GPIO_Direction_Output);

    GPIO_setDirection(myGpio, GPIO_Number_18, GPIO_Direction_Output);

    GPIO_setDirection(myGpio, GPIO_Number_19, GPIO_Direction_Output);

    GPIO_setLow(myGpio, GPIO_Number_4);

    GPIO_setHigh(myGpio, GPIO_Number_16 );

    GPIO_setHigh(myGpio, GPIO_Number_17 );

    GPIO_setHigh(myGpio, GPIO_Number_18 );

    GPIO_setHigh(myGpio, GPIO_Number_19 );

    GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Enable);

    GPIO_setPullUp(myGpio, GPIO_Number_3, GPIO_PullUp_Enable);

    GPIO_setPullUp(myGpio, GPIO_Number_6, GPIO_PullUp_Enable);

    GPIO_setPullUp(myGpio, GPIO_Number_7, GPIO_PullUp_Enable);

    GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable);

    GPIO_setPullUp(myGpio, GPIO_Number_1, GPIO_PullUp_Disable);

    GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A);

    GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_EPWM1B);

    GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Enable);

    GPIO_setQualification(myGpio, GPIO_Number_5, GPIO_Qual_Sync);

    GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_ECAP1);

    PIE_enable(myPie);

    // Register interrupt handlers

    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap1_isr);

    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_7, (intVec_t)&cpu_timer0_isr);

    CLK_disableTbClockSync(myClk);

    InitTime0();

    InitEPwm1();

    InitECapture();

    CLK_enableTbClockSync(myClk);

    PIE_enableTimer0Int(myPie);

    PIE_enableCaptureInt(myPie);

    // Enable global Interrupts and higher priority real-time debug events:

    CPU_enableGlobalInts(myCpu);

    CPU_enableDebugInt(myCpu);

    CPU_enableInt(myCpu, CPU_IntNumber_1);

    CPU_enableInt(myCpu, CPU_IntNumber_4);

    for(;;)

    {

         scanning();

         if(scan==0XFFFF) //停止响应按键音乐

                 GPIO_setLow (myGpio, GPIO_Number_4 );

         else if(scan==0XBFFF)//录音

          {

             uint32_t j;

            for(j=100000;j>0;j--);//延时(防止按钮抖动)

           if(record==0)//录音标志跳变

              {

               record=1;

               k=0;

               l=0;

               int q=0;

               for(q=0;q<202;q++)

                      rhy[q]=0;

               for(q=0;q<100;q++)

                      f[q]=0;

              }

            else

              record=0;

           }

         else if(scan==0X7FFF)//播放

           {

                uint32_t  j;

            for(j=100000;j>0;j--);//延时(防止按钮抖动)

             if(play==0)//播放标志跳变

               play=1;

             else

               play=0;

             if(play==1)

               {

                    k=0;

                    l=1;

                    flag1=0;

                    TIMER_setPeriod(myTimer,rhy[l]);

                    TIMER_start(myTimer);

               }

             else

             {

                    PWM_setPeriod(myPwm1, 0);

                    TIMER_stop(myTimer);

             }

            }

         else      //即时响应按键音乐

          {

             yindiao();

             GPIO_setHigh (myGpio, GPIO_Number_4 );

          }

     }

}

void InitTime0()//定时器初始化

{

    TIMER_stop(myTimer);

    TIMER_setPeriod(myTimer,30000);

    TIMER_setPreScaler(myTimer, 0);

    TIMER_reload(myTimer);

    TIMER_setEmulationMode(myTimer, TIMER_EmulationMode_StopAfterNextDecrement);

    TIMER_enableInt(myTimer);

}

void InitEPwm1()//PWM初始化

{

    CLK_enablePwmClock(myClk, PWM_Number_1);

    // Setup TBCLK

    PWM_setCounterMode(myPwm1, PWM_CounterMode_Up); // Count up

    PWM_setPeriod(myPwm1, 0);   // Set  period

    PWM_setCount(myPwm1, 0x0000);               // Clear counter

    PWM_setHighSpeedClkDiv(myPwm1, PWM_HspClkDiv_by_1); // Clock ratio to SYSCLKOUT

    PWM_setClkDiv(myPwm1, PWM_ClkDiv_by_1);

   // Setup shadowing

    PWM_setShadowMode_CmpA(myPwm1, PWM_ShadowMode_Shadow);

    PWM_setShadowMode_CmpB(myPwm1, PWM_ShadowMode_Shadow);

    PWM_setLoadMode_CmpA(myPwm1, PWM_LoadMode_Zero);

    PWM_setLoadMode_CmpB(myPwm1, PWM_LoadMode_Zero);

    // Set Compare values

    PWM_setCmpA(myPwm1,100);    // Set compare A value

    PWM_setCmpB(myPwm1,100);    // Set Compare B value

    // Set actions

    PWM_setActionQual_Zero_PwmA(myPwm1, PWM_ActionQual_Set);

            // Set PWM1A on Zero

    PWM_setActionQual_CntUp_CmpA_PwmA(myPwm1, PWM_ActionQual_Clear);

             // Clear PWM1A on event A, up count

}

void InitECapture()//CAP初始化

{

    CLK_enableEcap1Clock(myClk);

    CAP_disableInt(myCap, CAP_Int_Type_All);    // Disable all capture interrupts

    CAP_clearInt(myCap, CAP_Int_Type_All);      // Clear all CAP interrupt flags

    CAP_disableCaptureLoad(myCap);              // Disable CAP1-CAP4 register loads

    CAP_disableTimestampCounter(myCap);      // Make sure the counter is stopped

    // Configure peripheral registers

    CAP_setCapEvtPolarity(myCap, CAP_Event_1, CAP_Polarity_Rising);    // Falling edge

    CAP_setCapEvtPolarity(myCap, CAP_Event_2, CAP_Polarity_Falling);     // Rising edge

    CAP_setCapEvtPolarity(myCap, CAP_Event_3, CAP_Polarity_Rising);    // Falling edge

    CAP_setCapEvtPolarity(myCap, CAP_Event_4, CAP_Polarity_Falling);     // Rising edge

    CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Enable);   // Difference operation

    CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Enable);   // Difference operation

    CAP_setCapEvtReset(myCap, CAP_Event_3, CAP_Reset_Enable);   // Difference operation

    CAP_setCapEvtReset(myCap, CAP_Event_4, CAP_Reset_Enable);

    CAP_enableSyncIn(myCap);                    // Enable sync in

    CAP_setSyncOut(myCap, CAP_SyncOut_SyncIn);  // Pass through

    CAP_enableCaptureLoad(myCap);

    CAP_enableTimestampCounter(myCap);          // Start Counter

    CAP_rearm(myCap);                           // arm one-shot

    CAP_enableCaptureLoad(myCap);          // Enable CAP1-CAP4 register loads

    CAP_enableInt(myCap, CAP_Int_Type_CEVT1);   // 1 events = interrupt

    CAP_enableInt(myCap, CAP_Int_Type_CEVT2);   // 2 events = interrupt

    CAP_enableInt(myCap, CAP_Int_Type_CEVT3);   // 3 events = interrupt

    CAP_enableInt(myCap, CAP_Int_Type_CEVT4);   // 4 events = interrupt

}

interrupt void ecap1_isr(void)//CAP中断

{

    if( flag==0)

       {

          PWM_setPeriod(myPwm1,10*f[k]);   //Set  period

          PWM_setCmpA(myPwm1, 5*f[k]);    // Set compare A value

          if(record==1)

                rhy[l]=CAP_getCap1(myCap);

        CAP_clearInt(myCap, CAP_Int_Type_CEVT1);

       }

    if(flag==1)

    {   PWM_setPeriod(myPwm1, 0);   // Set period

                  if(record==1)

                  {

                         rhy[l]=CAP_getCap2(myCap);

                      if(k<99)

                       k++;

                      else

                       k=0;

                  }

            CAP_clearInt(myCap, CAP_Int_Type_CEVT2);

    }

    if(flag==2)

    {

                  PWM_setPeriod(myPwm1,10*f[k]);   // Set period

                  PWM_setCmpA(myPwm1, 5*f[k]);    // Set compare A value

                  if(record==1)

                      rhy[l]=CAP_getCap3(myCap);

               CAP_clearInt(myCap, CAP_Int_Type_CEVT3);

    }

    if(flag==3)

    {

             PWM_setPeriod(myPwm1, 0);   // Set period

                  if(record==1)

                   {

                         rhy[l]=CAP_getCap4(myCap);

                          if(k<99)

                           k++;

                          else

                           k=0;

                   }

           CAP_rearm(myCap);

           CAP_clearInt(myCap, CAP_Int_Type_CEVT4);

    }

    if(flag<3)

           flag++;

    else

        flag=0;

    if(record==1)

      {

           if(l<201)

                  l++;

        else

               l=0;

      }

    CAP_clearInt(myCap, CAP_Int_Type_Global);

    // Acknowledge this interrupt to receive more interrupts from group 4

    PIE_clearInt(myPie, PIE_GroupNumber_4);

}

interrupt void cpu_timer0_isr(void)//定时器中断

{

    if(flag1==0)

           flag1=1;

    else

        flag1=0;

    if(flag1==1)

    {

           PWM_setPeriod(myPwm1,10*f[k]);   // Set timer period 801 TBCLKs

           PWM_setCmpA(myPwm1, 5*f[k]);    // Set compare A value

           PWM_setCmpB(myPwm1, 5*f[k]);    // Set Compare B value

           if(k<99)

           k++;

           else

           k=0;

    }

    if(flag1==0)

    {

        PWM_setPeriod(myPwm1, 0);

    }

    if(l<200)

        l++;

    else

        l=1;

    if(rhy[l]>0)

        TIMER_setPeriod(myTimer, rhy[l]);

    else

        TIMER_setPeriod(myTimer, 50000);

    PIE_clearInt(myPie, PIE_GroupNumber_1);

}

void yindiao()//赋频率值

{

 if(scan==0XFFFE)

  f[k]=A;

 if(scan==0XFFFD)

   f[k]=B;

 if(scan==0XFFFB)

   f[k]=C;

  if(scan==0XFFF7)

    f[k]=D;

  if(scan==0XFFEF)

    f[k]=E;

  if(scan==0XFFDF)

    f[k]=F;

  if(scan==0XFFBF)

     f[k]=G;

  if(scan==0XFF7F)

          f[k]=A1;

   if(scan==0XFEFF)

     f[k]=B1;

   if(scan==0XFDFF)

     f[k]=C1;

   if(scan==0XFBFF)

     f[k]=D1;

   if(scan==0XF7FF)

     f[k]=E1;

   if(scan==0XEFFF)

     f[k]=F1;

   if(scan==0XDFFF)

     f[k]=G1;

}

void scanning()//扫描赋值

{

    GPIO_toggle(myGpio, GPIO_Number_16 );

    scan1=GPIO_getPortData(myGpio,GPIO_Port_A);

    scan1=((scan1/64)*4+(scan1/4)%4);

    GPIO_toggle(myGpio, GPIO_Number_16);

    GPIO_toggle(myGpio, GPIO_Number_17);

    scan2=GPIO_getPortData(myGpio,GPIO_Port_A);

    scan2=((scan2/64)*4+(scan2/4)%4);

    GPIO_toggle(myGpio, GPIO_Number_17);

    GPIO_toggle(myGpio, GPIO_Number_18 );

    scan3=GPIO_getPortData(myGpio,GPIO_Port_A);

    scan3=((scan3/64)*4+(scan3/4)%4);

    GPIO_toggle(myGpio, GPIO_Number_18 );

    GPIO_toggle(myGpio, GPIO_Number_19 );

    scan4=GPIO_getPortData(myGpio,GPIO_Port_A);

    scan4=((scan4/64)*4+(scan4/4)%4);

    GPIO_toggle(myGpio, GPIO_Number_19 );

    scan=scan1+16*scan2+256*scan3+4096*scan4;

}

相关推荐