⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2s.c

📁 WAV 数字输出播放器
💻 C
字号:
#include <p33FJ64GP306.h>
#include "I2S.h"
#include "integer.h"

// This source handles I2S transmitter.
// it runs as automatic data flow from 2 page DMA memory to I2S

//DMA Memory page 1 and 2
WORD dci1TxBuffA[512] __attribute__((space(dma)));
WORD dci1TxBuffB[512] __attribute__((space(dma)));

//Interrupt notice Flag in main.c
extern BYTE DMA_Flag_A;

// BY Microchip Sample source code
void i2s_Init (void)
{
/*
In this section we will set up the DCI module for I2S operation to interface 
with a stereo audio codec sampling data at 44.1 KHz. The timing diagram is 
provided in Fig 1 below:
                                  FIGURE 1
       _______________________________
      |		 	    	              |	                              |
COFS: |	  	     	                  |_______________________________|
       _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _    
CSCK:_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
          |<--------Left Channel Data---->|<----Right Channel Data------->|
          |<---------32 bits------------->|<---------32 bits------------->|
          |<---TXBUF0---->|<----TXBUF1--->|<---TXBUF2---->|<----TXBUF3--->|
          |<--TimeSlot0-->|<--TimeSlot1-->|<--TimeSlot0-->|<--TimeSlot1-->|
          |<--------------------1/Fs = 22.7 microseconds----------------->|
*/

	//DCI Control Register DCICON1 Initialization
	DCICON1 = 0;
	DCICON1bits.CSCKD = 0;	// Serial Bit Clock (CSCK pin) is output	
	DCICON1bits.CSCKE = 1;	// Data changes on falling edge, sampled on rising edge of CSCK
	DCICON1bits.COFSD = 0;	// Frame Sync Signal is output	
	DCICON1bits.UNFM = 0;	// Transmit 0 on a transmit underflow
	DCICON1bits.CSDOM = 0;	// CSDO pin drives 0 during disabled transmit time slots
	DCICON1bits.DJST = 0;	// Data TX/RX is begun one serial clock cycle after frame sync pulse
	DCICON1bits.COFSM = 1;	// Frame Sync Signal set up for I2S mode 

	// DCI Control Register DCICON2 Initialization
	DCICON2 = 0;
	DCICON2bits.BLEN = 0;	// One data word will be buffered between interrupts	
	DCICON2bits.COFSG = 1;	// Data frame has 2 words  viz., LEFT & RIGHT samples
	DCICON2bits.WS = 15;	// Data word size is 16 bits

	// DCI Control Register DCICON3 Initialization
	DCICON3 = BCG_VAL;	    // Set up CSCK Bit Clock Frequency

	// Transmit Slot Control Register Initialization
	TSCONbits.TSE0 = 1;	    // Transmit on Time Slot 0	
	TSCONbits.TSE1 = 1;	    // Transmit on Time Slot 1	

	// Disable DCI Interrupt and Enable DCI module
	IFS3bits.DCIIF=0;
    IEC3bits.DCIIE=0; //Disable since DMA is used

}



/*=============================================================================
_DMA0Init(): Initialise DMA0 for DCI Data Transmission 
=============================================================================*/
// DMA0 configuration
// Direction: Read from DMA RAM and write to peripheral address 0x298 (TXBUF0 register)
// AMODE: Register Indirect with Post-Increment mode
// MODE: Continuous, Ping-Pong Enabled
// IRQ: DCI
void dma0_Init(void)
{
	DMA0CONbits.CHEN = 0;		//Disable
	DMA0CONbits.SIZE = 0;		//Word
	DMA0CONbits.DIR = 1;		//Read From DPSRAM, write to peripheral
	DMA0CONbits.HALF = 0;		//Block Transfer Int is caused at FULL moved
	DMA0CONbits.NULLW = 0;		//Null write to peripheral
	DMA0CONbits.AMODE = 0;		//Register indirect with Post-Increment
	DMA0CONbits.MODE = 0x02;	//Continuous, ping-pong mode enabled

	DMA0CNT = 511;				//Transfer count, Frame - 1		
	
	DMA0REQbits.FORCE = 0;		//Register indirect with Post-Increment

	DMA0REQbits.IRQSEL = 0x003C;	//Select DCI Codec		

	DMA0PAD = 0x0298;	//Periferal Address = DCI TXBUF 0
	
	DMA0STA= __builtin_dmaoffset(dci1TxBuffA);	//Page A buffer address
	DMA0STB= __builtin_dmaoffset(dci1TxBuffB);	//Page B buffer address
}


void dma0_start(void)
{	
	IFS0bits.DMA0IF  = 0;			// Clear DMA interrupt
	IEC0bits.DMA0IE  = 1;			// Enable DMA interrupt
	DMA0CONbits.CHEN = 1;			// Enable DMA Channel	
}


//Enable I2S
void i2s_start(void)
{
	DCICON1bits.DCIEN = 1; 
}


//Stop I2S
void i2s_stop(void)
{
	DCICON1bits.DCIEN = 0; 
}


//This interrupt will happen every 2.9ms (128 samples in 512 word, 44.1kHz)
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
		DMA_Flag_A = 1;				//notice to main.c
		
        IFS0bits.DMA0IF = 0;		//Clear the DMA0 Interrupt Flag
}

// Initialise I2S Transmit Buffer
void initI2sBuff(void)
{
	unsigned int i;
    
	for(i=0;i<512;i++) 
	{
		dci1TxBuffA[i]= 0x0000;	
		dci1TxBuffB[i]= 0x0000;	
	}
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -