📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2004-09-16
** Last Version: 1.0
** Descriptions: The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by: Litiantian
** Created date: 2007-01-10
** Version: 1.0
** Descriptions: I2S音频输入输出演示
**------------------------------------------------------------------------------------------------------
** Modified by: Caiqinglong
** Modified date: 2007-09-03
** Descriptions: 对代码风格和注释进行规范、校对。
**
** Rechecked by: Litiantian
********************************************************************************************************/
#include "config.h"
#define I2S_INT 31
#define BUFSIZE 0x20
#define RXFIFO_EMPTY 0
#define TXFIFO_FULL 8
volatile uint8 I2STXBuffer[BUFSIZE];
volatile uint8 I2SRXBuffer[BUFSIZE];
volatile uint32 I2SReadLength = 0; // 已读入内存的FIFO数据个数
volatile uint32 I2SWriteLength = 0;
volatile uint32 I2SRXDone = 0, I2STXDone = 0; // I2SRXDone为1时表明接收处理完毕,I2STXDone为1时表明发送处理完毕
/*********************************************************************************************************
** 函数名称 :I2SIRQISR
** 函数功能 :接收中断
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void __irq I2SIRQISR(void)
{
uint32 RxCount = 0; // 计数RX_FIFO里还需接收的数据个数
if ((I2SSTATE & 0x01) == 0x01) // 接收中断标志位置位
{
RxCount = (I2SSTATE >> 8) & 0xFF; // I2SSTATE的15:8位段为接收FIFO所接收到的字符数
while (1)
{
if ((RxCount != RXFIFO_EMPTY) && (I2SRXDone == 0))
{
if (I2SReadLength == BUFSIZE)
{
I2SDAI |= ((0x01 << 3) | (0x01 << 4)); // 音频输入通道停止
I2SIRQ &= ~(0x01 << 0); // 禁止接收中断
I2SRXDone = 1;
}
else
{
I2SRXBuffer[I2SReadLength++] = I2SRXFIFO;
RxCount--;
}
}
else
{
break;
}
}
}
VICVectAddr = 0;
}
/*********************************************************************************************************
** 函数名称 :I2SInit
** 函数功能 :初始化I2S接口
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void I2SInit(void)
{
uint32 DAIValue, DAOValue;
PCONP |= 1 << 27; // 在PCONP中使能I2S接口
/* 初始化P0.6-P0.9、P0.23、P0.24为I2S接口引脚 */
PINSEL0 = 0x00055000;
PINSEL1 = 0x00028000;
/* I2S接口的位速率I2S_BitRate = 采样率Sample rate * 声音的通道数 CHn * 所产生声音数据的位数BITn */
/* 在本例中,设置I2S_BitRate = 48khz * 2 * 16 =1.536Mhz */
I2STXRATE = 0x13; // I2S接口的发送位速率I2S_BitSndRate = Fpclk / (TXRATE+1)
I2SRXRATE = 0x13; // I2S接口的接收位速率I2S_BitRcvRate = Fpclk / (RXRATE+1)
/* 设置音频通道的工作模式 */
DAOValue = I2SDAO;
DAOValue &= ~((0x01 << 5) | (0x01 << 15)); // 设置输出通道为主模式,不使用静音模式,发送数据宽度、数据格式、WS周期皆为上电复位时的默认值
I2SDAO = (0x01 << 4) | (0x01 << 3) | DAOValue; // 异步复位音频输出通道和FIFO,禁止访问FIFO,同时将输出通道置于静音模式
DAIValue = I2SDAI; // 设置输入通道为从模式,发送数据宽度、数据格式、WS周期皆为上电复位时的默认值
/* 完成工作模式设置的同时进行复位 */
I2SDAI = (0x01 << 4) | (0x01 << 3) | DAIValue; // 异步复位音频输入通道和FIFO
/* 配置中断 */
VICIntEnClr |= ((uint32)1 << I2S_INT);
VICVectPri31 = 0x05;
VICVectAddr31 = (uint32)I2SIRQISR;
VICIntEnable |= ((uint32)1 << I2S_INT);
IRQEnable();
/* 设置音频通道的工作模式后,复位 */
DAOValue = I2SDAO;
DAIValue = I2SDAI;
I2SDAO = DAOValue & (~((0x01 << 4) | (0x01 << 3))); // 停止复位,使能发送FIFO,不使用静音模式
I2SDAI = DAIValue & (~((0x01 << 4) | (0x01 << 3))); // 停止复位,使能接收FIFO
/* RX FIFO 触发深度为8,使能接收中断 */
I2SIRQ = (8 << 8) | (0x01 << 0);
}
/*********************************************************************************************************
** 函数名称 :I2S_BufInit
** 函数功能 :初始化I2S的发送和接收Buffer
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************/
void I2S_BufInit(void)
{
uint32 i = 0;
/* 初始化缓存 */
for (i = 0; i < BUFSIZE; i++)
{
I2STXBuffer[i] = i;
I2SRXBuffer[i] = 0;
}
}
/*********************************************************************************************************
** 函数名称 :I2S_FIFOTX
** 函数功能 :将I2S的发送BUFFER里的数据通过FIFO发送出去
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************/
void I2S_FIFOTX(void)
{
/* 若数据尚未发送完,则继续发送 */
while (I2SWriteLength < BUFSIZE)
{
while (((I2SSTATE >> 16) & 0xFF) == TXFIFO_FULL); // I2SSTATE里的23~16位段存储发送FIFO现有的数据个数
I2STXFIFO = I2STXBuffer[I2SWriteLength++];
}
I2STXDone = 1;
}
/*********************************************************************************************************
** 函数名称 :I2S_TXRXCOMP
** 函数功能 :比较发送和接收的内容。若不相等则进入死循环
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************/
void I2S_TXRXCOMP(void)
{
uint32 i = 0;
/* 开始比较 */
for (i = 1; i < BUFSIZE; i++)
{
if (I2SRXBuffer[i] != I2STXBuffer[i - 1])
{
while (1); // 一旦校验出错,则死循环
}
}
}
/*********************************************************************************************************
** 函数名称 :main
** 函数功能 :直接连接I2S的发送通道和接收通道,完成通讯实验
** 入口参数 :无
** 出口参数 :无
** 调试说明 :本实验是将TX通道和RX通道之间的CLK, WS, SDA线直接相连.DAO作为主机, DAI作为从机.由于同步的问题
** ,TX通道在RX通道尚未就绪时会发送一些MUTE数据0,所以在RX FIFO里可能存在一些无效的MUTE数据0,所以
** 在比较TX和RX FIFO里的数据之前,需要先将RX里的头一小部分数据丢弃
*********************************************************************************************************/
int main(void)
{
I2SReadLength = 0;
I2SWriteLength = 0;
I2SRXDone = 0;
I2STXDone = 0;
I2SSTATE = 0;
I2S_BufInit(); // 初始化I2S发送缓存的初值,清零I2S接收缓存
I2SInit();
I2S_FIFOTX(); // I2STXBuffer内的数据发送完毕
while (!I2SRXDone || !I2STXDone); // 等待发送和接收都处理完毕
I2S_TXRXCOMP(); // 比较发送和接收的内容,若不相同,则进入死循环
while (1);
return (0);
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -