//实验功能:熟悉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 <p30f6014.h> //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<QUEUE_SIZE ;i++)
{
RxQue[i] = 0;
TxQue[i] = 0xffff;
}
TxQTail = 0;
[1] [2] 下一页
本文关键字:暂无联系方式PIC单片机,单片机-工控设备 - PIC单片机