天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術熱線: 4007-888-234

技術支持

QLdsPIC3]音頻編碼解碼[C30+dsPIC30F6014A]

更新時間: 2019-03-23

深圳市英銳恩科技有限公司:臺灣麥肯單片機(Micon MDT單片機)亞太地區A級代理商

QLdsPIC3]音頻編碼解碼[C30+dsPIC30F6014A]
//實驗功能:熟悉dsPIC芯片的DC1模塊功能和音頻編解碼芯片SI3000的使用
//軟件規劃:
//          1。音頻信號從J10(MIC IN)進去,編碼后送dsPIC控制器,dsPIC接收直接送回SI3000解碼從J11(SPK OUT)輸出
//          2。DCI采用中斷接收數據
//          3。SI3000工作在SLAVE從模式(由dsPIC提供SCK)
//硬件規劃:
//          1。撥碼開關S10全部置ON
//          2。跳線J9全部跳到SLAVE邊
//          3。音頻輸入接到J10(MIC IN)
//          4。音頻輸出接到J11(SPK OUT)

#include             //dsPIC30F6014標準頭文件
  _FOSC(0x0ffe5);                 //4倍頻晶振,Failsafe 時鐘關閉
  _FWDT(WDT_OFF);                 //關閉看門狗定時器
  _FBORPOR(PBOR_OFF & MCLR_EN);   //掉電復位禁止,MCLR復位使能。
  _FGS(CODE_PROT_OFF);            //代碼保護禁止


#define SAMPLE_RATE    7200L
#define FRAMECLKRATE  (SAMPLE_RATE*256L)   //SCK頻率使用1.8432M
#define CLOCK_FREQ  (1L*10000000L)   // 采用 4x PLL..PIC 指令頻率 (Fosc*4/4)


#define CMD_STAGE0 0 //正常模式
#define CMD_STAGE1 1 //設置lsb告訴解碼器下一個控制字是命令
#define CMD_STAGE2 2 //把帶命令的字節放到輸出緩沖
#define CMD_STAGE3 3 //設置幀模式
#define CMD_STAGE4 4 //回復正常幀模式

#define PROC_BLOCK_SIZE 144 //數據處理塊大小
#define QUEUE_SIZE (PROC_BLOCK_SIZE*2) //Rx和Tx隊列的大小,必須為處理緩沖大小的2倍

unsigned int* pActiveRxBuf;
unsigned int* pActiveTxBuf;

unsigned char  __attribute__((address(0x900))) CmdStage;
static volatile unsigned int CodecCmd;
static volatile char ClkAdjTrig;

static int TxQue[QUEUE_SIZE];
static int RxQue[QUEUE_SIZE];
static volatile unsigned int TxQTail;
static volatile unsigned int RxQHead;


void InitCodec(void);
void WriteCodecCtrl( unsigned char adr, unsigned char parm );
void AdjustClock( char shift );
unsigned char ReadCodecCtrl( unsigned char adr );

//***************延時程序***************************
void TimeDelay(unsigned char x)
{
 unsigned char i;
    for(i=0;i<x;i++);
}


//************把數據放到接收緩沖的子程序************
inline void PutRxQue(int data)
{
 RxQue[RxQHead++] = data;
 if(RxQHead==QUEUE_SIZE) RxQHead = 0;
}

//***********從接收緩沖獲取數據的子程序***************
inline int GetTxQue(void)
{
static int tmp;  
    tmp = RxQue[TxQTail++]&0xFFFE;     //接收到數據送回解碼輸出
 if(TxQTail==QUEUE_SIZE) TxQTail = 0;
 return tmp;
}

//DCI中斷服務子程序
void __attribute__((__interrupt__)) _DCIInterrupt(void)
{
int tmp;
 switch( CmdStage )
 {
  case CMD_STAGE0:            
   TXBUF0 = GetTxQue();
    TXBUF1 = GetTxQue();
   TXBUF2 = GetTxQue();
   TXBUF3 = GetTxQue();
   PutRxQue(RXBUF0);
   PutRxQue(RXBUF1);
   PutRxQue(RXBUF2);
   tmp = RXBUF3;   //調整時鐘的相位
   if(ClkAdjTrig > 0)  //如果需要插入采樣
    PutRxQue(tmp);
   if(ClkAdjTrig >= 0)  //如果不須,則跳過
    PutRxQue(tmp);
   ClkAdjTrig = 0;
   break;
  case CMD_STAGE1:
   TXBUF0 = GetTxQue();
   TXBUF1 = GetTxQue();
   TXBUF2 = GetTxQue();
   TXBUF3 = GetTxQue() | 1; //告訴編碼解碼器下一個值是命令
   PutRxQue(RXBUF0);
   PutRxQue(RXBUF1);
   PutRxQue(RXBUF2);
   PutRxQue(RXBUF3);
   CmdStage = CMD_STAGE2;
   break;
  case CMD_STAGE2:
   TXBUF0 = CodecCmd;      //插入編碼解碼器命令
   TXBUF1 = GetTxQue(); //取采樣數據
   TXBUF2 = 0x0000;    //寫虛擬值
   TXBUF3 = 0x0000;    //寫虛擬值
   PutRxQue(RXBUF0);
   PutRxQue(RXBUF1);
   PutRxQue(RXBUF2);
   PutRxQue(RXBUF3);
   CmdStage = CMD_STAGE3;
   break;
  case CMD_STAGE3:
   TXBUF0 = GetTxQue();
   TXBUF1 = GetTxQue();
   TXBUF2 = GetTxQue();
   TXBUF3 = GetTxQue();
   PutRxQue(RXBUF0);
   PutRxQue(RXBUF1);
   PutRxQue(RXBUF2);
   PutRxQue(RXBUF3);
   
            DCICON2=0XF6FF;        //設置DCI緩沖長度為2
   CmdStage = CMD_STAGE4;
   break;
  case CMD_STAGE4:
   TXBUF0 = GetTxQue();
   TXBUF1 = GetTxQue();
   TXBUF2 = GetTxQue();
   TXBUF3 = GetTxQue();
   CodecCmd = RXBUF0;
   PutRxQue(RXBUF1);
   
            DCICON2=0XFFFF;      //設置DCI緩沖長度為4
   CmdStage = CMD_STAGE0;
   break;
 }
 IFS2bits.DCIIF = 0; // 清DCI中斷標志
}

//**************初始化DCI和編碼解碼器*******************
void InitCodec(void)
{
int i;
 for(i=0; i {
  RxQue[i] = 0;
  TxQue[i] = 0xffff;
 }
 TxQTail = 0;
 RxQHead = 0;
 CmdStage = CMD_STAGE0;
 CodecCmd = 0;
 ClkAdjTrig = 0;
 TRISFbits.TRISF6 = 1; //編碼解碼器(Codec)引腳為輸入
    IFS2bits.DCIIF = 0;
    IEC2bits.DCIIE=1;
    IPC10bits.DCIIP=7;
 
    DCICON1=0X8040;         // 配置DCI模塊用于傳送16位數據且工作在多通道模式
    DCICON2=0XFFFF;
    DCICON3=( CLOCK_FREQ / ( 2 * FRAMECLKRATE) ) - 1;
    TSCON=1;
    RSCON=1;
 LATFbits.LATF6 = 0; //復位編碼解碼器
 TRISFbits.TRISF6 = 0;
 TimeDelay(200);
 TRISFbits.TRISF6 = 1; //編碼解碼器設為輸入
 TimeDelay(1);

 WriteCodecCtrl( 3, 0);  //SI3000寄存器3
 WriteCodecCtrl( 4, 19);     //SI3000寄存器4
    WriteCodecCtrl( 1,0X18 );   //SI3000寄存器1
 WriteCodecCtrl( 2, 0);     //SI3000寄存器2
    WriteCodecCtrl( 5, 2);      //SI3000寄存器5
    WriteCodecCtrl( 6, 0X5E );  //SI3000寄存器6
    WriteCodecCtrl( 7, 0X5F );  //SI3000寄存器7
    WriteCodecCtrl( 9, 0);      //SI3000寄存器9
}

//*************寫命令到編碼解碼器子程序**********************
void WriteCodecCtrl( unsigned char adr, unsigned char parm )
{
 CodecCmd = (unsigned int)adr;
 CodecCmd = (CodecCmd<<8) & 0x1F00;     //SI3000寄存器的5位地址
 CodecCmd += (unsigned int)parm;        //待寫入的數據
 CmdStage = CMD_STAGE1;
 while( CmdStage != CMD_STAGE0 ){}
}

//*************從編碼解碼器讀命令子程序**********************
unsigned char ReadCodecCtrl( unsigned char adr )
{
 CodecCmd = (unsigned int)adr;
 CodecCmd = (CodecCmd<<8) & 0x1F00;
 CodecCmd |=  0x2000;                  //讀功能
 CmdStage = CMD_STAGE1;
 while( CmdStage != CMD_STAGE0 ){}
 return CodecCmd&0x00FF;
}

//**********************主函數*******************************
int main(void)
{
    TRISG=0X1000;
 InitCodec();
    while(1);
}

404
返回首頁 |  返回上一頁
联系我们: 阳新县| 衡东县| 海阳市| 静安区| 济宁市| 福泉市| 罗江县| 蒙山县| 乐业县| 句容市| 上虞市| 平定县| 衡水市| 信阳市| 蓬莱市| 梨树县| 安龙县| 搜索| 顺昌县| 昂仁县| 保定市| 龙州县| 吉安市| 马鞍山市| 柯坪县| 合山市| 鹤峰县| 清新县| 高雄市| 太原市| 崇阳县| 海门市| 桐柏县| 绵阳市| 平定县| 东山县| 陆良县| 贺兰县| 呼图壁县| 阿荣旗| 苏尼特右旗|