📄 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: Chenmingji
** Created date: 2004-09-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Litiantian
** Modified date: 2007-01-10
** Version:
** Descriptions: I2S音频输出通信实验。
********************************************************************************************************/
#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,DebugVal = 0; // I2SRXDone为1时表明接收处理完毕,I2STXDone为1时表明发送处理完毕
/*********************************************************************************************************
** 函数名称 :I2SIRQISR
** 函数功能 :接收中断
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void __irq I2SIRQISR (void)
{
uint32 RxCount = 0; // 计数RX_FIFO里接收的数据个数,初始化为0
if ( (I2SSTATE & 0x01) == 0x01 ) // 如果接收中断标志位置位了
{
RxCount = (I2SSTATE >> 8) & 0xFF; // I2SSTATE的15:8位段为接收FIFO所接收到的字符数
if ( (RxCount != RXFIFO_EMPTY) && (I2SRXDone == 0) )// 如果RX FIFO接收到了新数据,并且整个接收过程尚未结束则处理RX FIFO
{
if ( I2SReadLength == BUFSIZE ) // 接收完了所有需发送数据
{
I2SDAI |= ((0x01 << 3) | (0x01 << 4)); // 令音频输入通道停止
I2SIRQ &= ~(0x01 << 0); // 清除接收中断标志以返回
I2SRXDone = 1; // 接收完毕
}
else
I2SRXBuffer[I2SReadLength++] = I2SRXFIFO; // 将I2SFIFO里的数据全部转存
RxCount = 0;
}
}
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 / I2STXRATE里的分频值TXRATE
I2SRXRATE = 0x13; // I2S接口的接收位速率I2S_BitRcvRate = Fpclk / I2SRXRATE里的分频值RXRATE
/* 初始化音频输出通道,先复位 */
DAOValue = I2SDAO;
DAOValue &= ~((0x01 << 5)|(0x01 << 15)); // 设置音频输出通道为主机,且取消静音功能,为主机,发送数据为16位,其它值不变
I2SDAO = (0x01 << 4) | (0x01 << 3) | DAOValue; // 异步复位音频输出通道和FIFO,禁用FIFO,同时将输出通道置于静音模式
/* 初始化音频输入通道,先复位 */
DAIValue = I2SDAI;
DAIValue &= ~(0x01 << 15);
I2SDAI = (0x01 << 4) | (0x01 << 3) | DAIValue; // 异步复位音频输出通道和FIFO,禁用FIFO,同时将输出通道置于静音模式
/* 配置中断 */
VICIntEnClr |= ((uint32)1 << I2S_INT); // 禁止本中断
VICVectPri31 = 0x05; // 设置串口中断优先级为5
VICVectAddr31 = (uint32)I2SIRQISR; // 装入串口中断服务程序地址
VICIntEnable |=((uint32)1 << I2S_INT); // 使能本中断
IRQEnable(); // 使能IRQ中断
/* 音频输出通道开始按设定的模式工作 */
/* 16 位声音数据, 立体声, 主模式,不使用静音功能 */
DAOValue = I2SDAO;
DAIValue = I2SDAI;
I2SDAO = DAOValue & (~((0x01 << 4)|(0x01 <<3))); // 停止复位,使能FIFO,不使用静音模式
/* 音频输入通道开始按设定的模式工作 */
/* 16 位声音数据, 立体声, 从模式,不使用静音功能 */
I2SDAI = DAIValue & (~((0x01 << 4)|(0x01 <<3))); // 停止复位,使能FIFO,不使用静音模式
/* RX FIFO 触发深度为1, TX FIFO 触发深度为8,使能接收中断. */
I2SIRQ = (8 << 16) | (1 << 8) | (0x01 << 0);
DebugVal = 1; // 设置DebugVal变量为1.
}
/*********************************************************************************************************
** 函数名称 :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++]; // 待发送数据移至TX_FIFO
}
I2STXDone = 1; // I2S发送完毕
}
/*********************************************************************************************************
** 函数名称 :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; // 用以指示已读入到内存的FIFO数据个数
I2SWriteLength = 0;
I2SRXDone = 0;
I2STXDone = 0; // I2SRXDone为1时表明接收处理完毕,I2STXDone为1时表明发送处理完毕
I2SSTATE = 0;
IRQEnable();
I2S_BufInit(); // 初始化I2S发送缓存的初值,清0I2S接收缓存
I2SInit(); // 按照设定值初始化I2S接口,产生接收中断
DebugVal = 0; // 执行完初始化后,立即将DebugVal清0
I2S_FIFOTX(); // I2STXBuffer内的数据通过FIFO发送完毕
while ( !I2SRXDone || !I2STXDone ); // 等待发送和接收都处理完毕
I2S_TXRXCOMP(); // 比较发送和接收的内容,若不相同,则进入死循环
while(1);
return 0;
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -