Febird's Sky

Search & Research & Find
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

基于DE2 与Nios II的音频录放系统的设计-软件篇

Posted on 2008-11-28 09:58  febird  阅读(1302)  评论(2编辑  收藏  举报

源码结构


设计框图


下面就Basic_io.h,Functions.h,Main.c,Functions.c作说明

basic_io.h

 

#ifndef   __basic_io_H__

#define   __basic_io_H__

 

#define BYTE    unsigned char

#define UINT16  unsigned int

#define UINT32  unsigned long

 

#include <io.h>

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include "system.h"

#include "sys/alt_irq.h"

 

//  for GPIO

#define inport(base)                                  IORD(base, 0)

#define outport(base, data)                           IOWR(base, 0, data)

#define get_pio_dir(base)                             IORD(base, 1)

#define set_pio_dir(base, data)                       IOWR(base, 1, data)

#define get_pio_irq_mask(base)                        IORD(base, 2)

#define set_pio_irq_mask(base, data)                  IOWR(base, 2, data)

#define get_pio_edge_cap(base)                        IORD(base, 3)

#define set_pio_edge_cap(base, data)                  IOWR(base, 3, data)

 

//  for SEG7 Display

#define seg7_show(base,data)                          IOWR(base, 0, data)

 

//  for Time Delay

#define msleep(msec)                                  usleep(1000*msec);

#define Sleep(sec)                                    msleep(1000*sec);

 

 

#endif

Fuctions.h

#ifndef _FUNCTIONS_H_

#define _FUNCTIONS_H_

 

#include "basic_io.h"

#include "LCD.h"

#include "Open_I2C.h"

#include "SD_Card.h"

#include <stdlib.h>

#include <string.h>

 

 

#define ITEM_NUM 3  //Audio项目总数

#define VOL_MAX 255 //Max Volume

#define MEM_NUM  3  //存储器个数

 

#define  MEM_BASE_REC 0x00000010

#define      MEM_BASE 0x00000000

#define      SRAM_MAX 0x00040000  //512K  0x00040000 * 16 Bits=512K;                                   

#define     SDRAM_MAX 0x00400000  //8M    0x00400000 * 16 bits=8M

#define CFI_FLASH_MAX 0x00200000  //4M    0x00400000 * 8  bits=4M 

 

 

/*定义七段数码管,LED默认值*/

 

#define SEG7_VALUE        0x88888888  

#define LED_GREEN_VALUE   0x1FF

#define LED_RED_VALUE     0x3FFFF

 

/*定义Button的延时以及中断Mask*/

#define BUTTON_STOP_TIME  500000        //  us

#define BUTTON_INT_MASK   0xF

 

/*设定I2C频率*/

#define I2C_FREQ          100000        //  100Khz

 

/*函数原型*/

void Init_All(void);

void LED_red(UINT32);                        

void LED_green(BYTE);

void Audio_test(void);

void Button_Irq_Init(void);

void Timer_Irq_Init(void);

int Button_Handle(void);

void Mode_Recover_Timer_Handle(void);

 

void Audio_Mode_Go(int);

void Vol_Go(int);

void Mem_Choose_Go(int);

UINT32 Get_Mem_Max(void);

char * Vol_Str(BYTE);

 

void test_sdram(void);

void test_cfi_flash(void);

 

#endif //_FUNCTIONS_H_

 

Main.C

 

#include "functions.h"

 

/*引进Functions.C文件中的全局变量*/

extern int AUDIO_MODE_INDEX;

extern int FUNC_MODE;

extern int INIT_FLAG;

extern int MEM_CHOOSE; 

extern int CODEC_TYPE; 

extern char STR_ITEM[ITEM_NUM][17];

extern char STR_DOING[ITEM_NUM][17];

extern char STR_STOPED[ITEM_NUM][17];

extern char STR_TITLE[17];                

 

/*主函数中的变量*/                  

UINT32 AUDIO_RD_ADD=MEM_BASE_REC; //读地址

UINT32 AUDIO_WR_ADD=MEM_BASE_REC; //写地址

UINT16 WR_DATA=0x0000;            //读数据

UINT16 RD_DATA=0x0000;            //写数据

 

 

int RecValid=0,RecLastValid=0;  //读有效变量,读上次有效变量(状态变化时改写)

int SpeValid=0,SpeLastValid=0;  //写有效变量,写上次有效变量(状态变化时改写)

 

/*本文件中函数原型声明*/                 

void Recording();

void Speaking();

UINT16 MemoryRead(UINT32);

void MemoryWrite(UINT32,UINT16);

void RecordMem_End(UINT32);

void ShowStatus(int);

 

/*主函数*/               

int main()

{

   Init_All(); 

 

   while(1)

   {

          if(FUNC_MODE==0) //Audio模式,主模式

          {

            /*根据模式选择功能,可扩展更多功能*/

            switch(AUDIO_MODE_INDEX)

            {

              case 0: Recording();break;                     

             

              case 1: Speaking();break;

             

              case 2: SD_Card_Player();break;

             

            }//end switch           

           

          }//end if(FUNC_MODE==0)   

   }//end while(1)

  

   /*测试部分*/

   // test_cfi_flash();  

   //test_sdram(); 

 

  

}

 

/*放音函数定义*/

void Speaking()

{

  IOWR(AUDIO_CTRL_BASE,0,0); //AUD_MOD写控制信号 0为向DAC FIFO输出

  /*判断 最后一位Switch开关  如果是开的就继续*/

  SpeValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);

 

  if(SpeLastValid!=SpeValid)

  {

    ShowStatus(SpeValid);

  }

  SpeLastValid=SpeValid; 

  

  while(SpeValid)//valid

  {             

      if(!IORD(AUDIO_FULL_BASE,0))

      {

        if(AUDIO_RD_ADD<=AUDIO_WR_ADD)

        {

            RD_DATA=MemoryRead(AUDIO_RD_ADD);

            LED_red(RD_DATA);    

            IOWR(SEG7_DISPLAY_BASE,0,AUDIO_RD_ADD++);

            IOWR(AUDIO_MOD_BASE,0,RD_DATA);   

        }

      }    

  

    SpeValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);

  }

}

 

/*录音程序定义*/

void Recording()

{

  IOWR(AUDIO_CTRL_BASE,0,1); ////AUD_MOD写控制信号 1为向ADC FIFO输出

 

 

  RecValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);

 

  if(RecLastValid!=RecValid)

  {

    ShowStatus(RecValid);

  }

  RecLastValid=RecValid; 

 

  while(RecValid)

  {

 

      

    if(!IORD(AUDIO_EMPTY_BASE,0))

    {

      if(AUDIO_WR_ADD<=Get_Mem_Max())

      {    

        WR_DATA=IORD(AUDIO_MOD_BASE,0);     

        LED_red(WR_DATA);

        MemoryWrite(AUDIO_WR_ADD,WR_DATA);     

        IOWR(SEG7_DISPLAY_BASE,0,AUDIO_WR_ADD++);

      }     

    }

   

    RecValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);

  

  }

 

}

/*向内存中写入结束地址——作为系统Init后检查的标志*/

//暂时没有用到

void RecordMem_End(UINT32 addr)

{

  UINT16 temp=0;

  temp=(UINT16)addr;

  IOWR(SRAM_0_BASE,MEM_BASE,temp);

  temp=addr>>16;

  IOWR(SRAM_0_BASE,MEM_BASE+1,temp);   

}

 

/*录音、放音状态显示--改变LCD屏幕的显示 */

//根据当前的Audio状态显示不同内容的 Runnning Stop信息

//输入1 Running 0 Stoped

void ShowStatus(int status)

{

  if(status) //running 

  {

    LCD_Show(STR_ITEM[AUDIO_MODE_INDEX],STR_DOING[AUDIO_MODE_INDEX]);

  }

  else      //stoped

  {

    LCD_Show(STR_ITEM[AUDIO_MODE_INDEX],STR_STOPED[AUDIO_MODE_INDEX]);

  }

}

 

/*写存储器,对外封装为统一接口 根据全局变量MEM_CHOOSE来选择存储器

 * 输入32位地址线,16位数据线

 * */

void MemoryWrite(UINT32 Addr,UINT16 Data)

{

  switch(MEM_CHOOSE )

  {

    case 0:{

        IOWR_16DIRECT(SRAM_0_BASE,Addr,Data);break;

    }

    case 1:{

        IOWR_16DIRECT(SDRAM_0_BASE,Addr,Data);break;

    }

    case 2:{

        IOWR_8DIRECT(CFI_FLASH_0_BASE,Addr<<1,(BYTE)Data);         //Low Bits

        IOWR_8DIRECT(CFI_FLASH_0_BASE,(Addr<<1)+1,(BYTE)(Data>>8));  //High Bits

        break;     

    }

  }

}

 

/*写存储器,对外封装为统一接口 根据全局变量MEM_CHOOSE来选择存储器

 * 输入32位地址线,16位数据线

 * */

UINT16 MemoryRead(UINT32 Addr)

{

  UINT16 readdata=0;

  switch(MEM_CHOOSE )

  {

    case 0:{

        readdata=IORD_16DIRECT(SRAM_0_BASE,Addr);break;

    }

    case 1:{

        readdata=IORD_16DIRECT(SDRAM_0_BASE,Addr);break;

    }

    case 2:{

        readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,(Addr<<1)+1); //High Bits

        readdata<<=8;

        readdata+=IORD_8DIRECT(CFI_FLASH_0_BASE,Addr<<1);    //Low Bits

    }   

  }

  return readdata;

}

Functions.C

 

#include "functions.h"

/*引进外部变量*/

extern UINT32 AUDIO_RD_ADD;

extern UINT32 AUDIO_WR_ADD;

 

/*模式说明:

 * FUNC_MOD=0 主模式(Audio模式)FUNC_MOD不为零 为其他模式(例如音量调节)

 * 当为其他模式时,如果三秒钟买有按键,则自动跳转主模式(由定时器实现)

 * */

 

 

int FUNC_MODE=0;          /*模式标号*/

int AUDIO_MODE_INDEX=0;    /*主模式中的子模式标号*/

BYTE VOL=127;              /*音量调节模式*/

int MEM_CHOOSE=0;  //0 SRAM ,1 SDRAM ,2 Flash RAM, 3 USB ,4 SD_Card

                     /* 存储器选择子模式 */

int CODEC_TYPE=0;  //0 No Compress ,1 DPM ,2 ADPM,3 MP3&Other ....

                    /* 编码方案选择子模式(待扩展) */

                   

                   

int KEY_STATUS=0;   /*按键码*/

int MENU_TIME_OUT=3000; //ms

int INIT_FLAG=0;    /*初始化标识,*/

 

/*以下是字符串常量定义*/

 

char STR_TITLE[17]="HUST AC0506 IC08";

char STR_VOL[17]="";

 

char STR_ITEM[ITEM_NUM][17]={ 

                    "Audio Recorder  ", // 0

                    "Audio Speaker   ", // 1

                    "SD Music Player "  // 2

                   }; 

                  

char STR_DOING[ITEM_NUM][17]={

                    "Recording ...   ", // 0

                    "Speaking  ...   ", // 1

                    "Music Playing..."  // 2

                   };

                  

char STR_STOPED[ITEM_NUM][17]={

                    "Recorder Stopped", // 0

                    "Speak Stopped.  ", // 1

                    "SD Music Stopped"  // 2

                   };

                  

 char STR_MEM[MEM_NUM][17]={

                    "Use 512K SRAM   ", // 0

                    "Use 8M SDRAM    ", // 1

                    "Use 4M CFI Flash"  // 2

 };

 

 

/*红色LED亮起*/

void LED_red(UINT32 num)

{

  UINT32 led_red_mask=0x0000ffff; //right 18 bits

  IOWR(LED_RED_BASE,0,led_red_mask&num);

}

/*绿色LED亮起*/

void LED_green(BYTE num)

{

  UINT16 led_green_mask=0x0ff; //right 8 bits

  IOWR(LED_GREEN_BASE,0,led_green_mask&num);

}

 

//设置按键中断函数

void Button_Irq_Init()

{

  /* Enable all 4 button interrupts. */

  set_pio_irq_mask(BUTTON_PIO_BASE, BUTTON_INT_MASK);

  /* Reset the edge capture register. */

  set_pio_edge_cap(BUTTON_PIO_BASE, 0x0);

  /* Register the interrupt handler. */

  alt_irq_register( BUTTON_PIO_IRQ, NULL, (void*)Button_Handle);

}

//设置定时器中断函数

void Timer_Irq_Init()

{ 

  IOWR(TIMER_0_BASE,0,0x0); //最低一位To 写零清中断 第二位RUN为标志位,写无效

  IOWR(TIMER_0_BASE,1,0x1); //最后四位依次为 Stop Start Cont ITO

                             //  Stop Start 置一有效,Cont 置一循环,ITO中断使能;

                             //基址是4byte为一个单位,即一个偏移量                                    

  alt_irq_register( TIMER_0_IRQ, NULL, (void*)Mode_Recover_Timer_Handle);

}

 

//定时器三秒恢复函数(切换主模式)

void Mode_Recover_Timer_Handle()

{

  if(FUNC_MODE)

  {   

    FUNC_MODE=0;

    LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);

  } 

  //printf("sorry!");

}

 

//按键事件处理函数

int Button_Handle()

{

   

  KEY_STATUS=get_pio_edge_cap(BUTTON_PIO_BASE);  //捕捉按键码

  outport(LED_GREEN_BASE,KEY_STATUS);            //亮相应的灯xxms

  set_pio_edge_cap(BUTTON_PIO_BASE,0x0);         

  usleep(BUTTON_STOP_TIME);

  outport(LED_GREEN_BASE,0);

  //do switch

 

  /*如果程序运行Running,除复位键以外无效*/

 

  if((IORD(SWITCH_PIO_BASE,0)& 0x00001)&&KEY_STATUS!=1)

  {

    return 0;   

  }

 

  //判断模式,做相应的事情

   

  switch(FUNC_MODE)

  {  

   case 0: switch(KEY_STATUS)  //菜单

     {

      case 1 :   { INIT_FLAG=1;break;}

      case 2 :   { LCD_Show(STR_TITLE,Vol_Str(VOL));FUNC_MODE+=1;break; }       //goto VOL Mode

      case 4 :   { Audio_Mode_Go(1);LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);break; }

      case 8 :   { Audio_Mode_Go(-1);LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);break; }

     };

     break;

   case 1: switch(KEY_STATUS)  // 音量

    {

      case 1 :    {INIT_FLAG=1;break;}

      case 2 :    {LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);FUNC_MODE+=1;break;} 

                                                          //goto Menu Mode

      case 4 :    {Vol_Go(1);LCD_Show(STR_TITLE,Vol_Str(VOL));break;}

      case 8 :    {Vol_Go(-1);LCD_Show(STR_TITLE,Vol_Str(VOL));break;}

    };

    break;

   case 2: switch(KEY_STATUS)  // 存储位置

    {

      case 1 :    {INIT_FLAG=1;break;}

      case 2 :    {LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);FUNC_MODE=0;break;} 

                                                          //goto Menu Mode

      case 4 :    {Mem_Choose_Go(1);LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);break;}

      case 8 :    {Mem_Choose_Go(-1);LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);break;}

    };

    break;

    default:break;

  }

 

  //Init DATA;

  /*如果初始化Flag==1 则执行初始化*/

  if(INIT_FLAG)

  {

    LCD_Show(STR_TITLE,"Init.");

    msleep(300);

    LCD_Show(STR_TITLE,"Init..");

    msleep(300);

    LCD_Show(STR_TITLE,"Init....");

    msleep(300);

    LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);

       

    INIT_FLAG=0;    

       

    Init_All();

  }

 

  //Audio状态超时自动切换到Audio状态   

   IOWR(TIMER_0_BASE,0,0x0);//清计时器中断

   return 1;

}

 

void Audio_Mode_Go(int jump)

{

  if(jump==1){ 

  AUDIO_MODE_INDEX++;

  }

  else if(jump==-1)

  {AUDIO_MODE_INDEX--;   

  }

  else{;}

 

  if(AUDIO_MODE_INDEX> ITEM_NUM-1) AUDIO_MODE_INDEX=0;

  if(AUDIO_MODE_INDEX<0) AUDIO_MODE_INDEX=ITEM_NUM-1; 

 

}

 

void Mem_Choose_Go(int jump)

{

  if(jump==1){ 

  MEM_CHOOSE++;

  }

  else if(jump==-1)

  {MEM_CHOOSE--;   

  }

  else{;}

 

  if(MEM_CHOOSE> MEM_NUM-1) MEM_CHOOSE=0;

  if(MEM_CHOOSE<0) MEM_CHOOSE=MEM_NUM-1;

 

  //do some thing

 

    AUDIO_RD_ADD=MEM_BASE_REC;

    AUDIO_WR_ADD=MEM_BASE_REC;

 

}

 

UINT32 Get_Mem_Max()

{

  switch(MEM_CHOOSE)

  {

    case 0:return SRAM_MAX;

    case 1:return SDRAM_MAX;

    case 2:return CFI_FLASH_MAX;

    default:return 0;

  }

}

 

void Vol_Go(int jump)

{

  if(jump==1&&VOL!=255){ 

  VOL+=32;

  } 

  if(jump==-1&&VOL!=31)

  {VOL-=32;   

  }

  //set Volume I2C      

  if(AUDIO_MODE_INDEX==0)

  {

  I2C_Send(0x34,0x00,VOL);

  I2C_Send(0x34,0x02,VOL);

  }

  else if(AUDIO_MODE_INDEX==1)

  {

  I2C_Send(0x34,0x04,VOL);

  I2C_Send(0x34,0x06,VOL);   

  }

 

}

 

char * Vol_Str(BYTE in)

{

  char tmp1[17]="";

  strcpy(tmp1,"Volume : ");

  char tmp2[3]="";

  tmp2[0]='0'+VOL/32;

  tmp2[1]='\0';

  strcat(tmp1,tmp2);

  return strcpy(STR_VOL,tmp1);

}

 

 

 

void Init_All()

{

 

  //Init Varibles;

   FUNC_MODE=0; 

   AUDIO_MODE_INDEX=0;

    VOL=127;

    MEM_CHOOSE=0; 

    CODEC_TYPE=0;

    AUDIO_RD_ADD=MEM_BASE_REC;

    AUDIO_WR_ADD=MEM_BASE_REC;

  //-------------------------------

 

 

  //  Refresh LED

  outport(LED_GREEN_BASE,LED_GREEN_VALUE);

  outport(LED_RED_BASE,LED_RED_VALUE);

  //  Refresh SEG7

  seg7_show(SEG7_DISPLAY_BASE,SEG7_VALUE);

 

  //  I2C Core Initial & Set Freq = 100 Khz

  I2C_Init(10000000/I2C_FREQ-1);

 

  //  Check Video Encoder on I2C Bus, Address = 0x40

  if(I2C_Send(0x40,1,1))

  printf("\nFind Video Encoder on I2C Bus, Address = 0x40.\n");

  else

  printf("\nCan't Find Video Encoder on I2C Bus.\n");

 

  //  Check Audio CODEC on I2C Bus, Address = 0x34

  if(I2C_Send(0x34,1,1))

  printf("\nFind Audio CODEC on I2C Bus, Address = 0x34.\n");

  else

  printf("\nCan't Find Audio CODEC on I2C Bus.\n");

 

  msleep(500);

 

 

  outport(LED_GREEN_BASE,0);

  outport(LED_RED_BASE,0);

  seg7_show(SEG7_DISPLAY_BASE,0);

 

  //  Show LCD Test Text

 

  LCD_Test(); 

  msleep(1000); 

  LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);

 

  //  Set Button PIO Interrupts

  Button_Irq_Init();

  //Timer_Irq_Init();

}

 

 

 

 

 

/*测试函数*/

void Audio_test()

{

  UINT16 out_temp=0x55AA;

  UINT16 in_temp=0x0000;

  IOWR(AUDIO_CTRL_BASE,0,1); //adc

   while(1)

   {

    in_temp=IORD(AUDIO_MOD_BASE,0);      

    LED_red((UINT32)in_temp);

    out_temp=~out_temp;

    IOWR(AUDIO_MOD_BASE,0,out_temp);

    usleep(125);

   }

}

 

void test_sdram()

{

  int  key=0;

 UINT16 j=0;

 UINT32 r_add=0,w_add=0;

 

  while(1)

  {

      key=IORD(SWITCH_PIO_BASE,0);

      if(key){     

        IOWR(LED_RED_BASE,0,j);

        IOWR_16DIRECT(SDRAM_0_BASE,w_add,j);

        IOWR(SEG7_DISPLAY_BASE,0,w_add);

        w_add++;

        j++;

       

     }

      else

      {

        if(r_add<=w_add){

        IOWR(SEG7_DISPLAY_BASE,0,r_add);

        IOWR(LED_RED_BASE,0,IORD_16DIRECT(SDRAM_0_BASE,r_add));

        r_add++;       

       }

     }     

      //msleep(1);     

  }  

}

 

void test_cfi_flash()

{

  int  key=0;

 UINT16  j=10;

 UINT32  temp=0;

 BYTE  t=0;

   UINT16 readdata=0;

 //BYTE readdata=0;

 UINT32 r_add=0,w_add=0;

 

  while(1)

  {

      key=IORD(SWITCH_PIO_BASE,0);

      if(key){ 

        LED_green(j);

        //IOWR_8DIRECT(CFI_FLASH_0_BASE,w_add,j);

       

        temp=(UINT32)(w_add<<1);

       

        t=j;  

        printf("t=%d",t);    

        IOWR_8DIRECT(CFI_FLASH_0_BASE,temp,255);         //Low Bits

        t=(j>>8);

        printf("t=%d\n",t);

        IOWR_8DIRECT(CFI_FLASH_0_BASE,temp+1,255);  //High Bits      

       

        msleep(500);

       

        printf("%d-",IORD_8DIRECT(CFI_FLASH_0_BASE,temp));     //Low Bits

        printf("%d=",IORD_8DIRECT(CFI_FLASH_0_BASE,temp+1));  //High Bits

       

        IOWR(SEG7_DISPLAY_BASE,0,w_add);

        printf("%d\t",j);

        //printf("%d\t",IORD_8DIRECT(CFI_FLASH_0_BASE,w_add));

        w_add++;

        j++;

       

       

       

     }

      else

      {

        if(r_add<=w_add){

        IOWR(SEG7_DISPLAY_BASE,0,r_add);

        //readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,r_add);

        readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,(r_add<<1)+1); //High Bits

        readdata<<=8;

        readdata+=IORD_8DIRECT(CFI_FLASH_0_BASE,r_add<<1);    //Low Bits

        printf("%d\t",readdata);

        LED_green(readdata);

        r_add+=1;       

       }

     }     

      msleep(1000);     

  }  

}