基于STM32F103--I2S2、I2S3的“伪全双工”音频接口初始化

        stm32f103的芯片是半双工的I2S,但有两路I2S,所以可以同时将一路配置为主接收(录音),另外一路配置为主发送(播放)。

        需要注意的是,启用I2S3,需要先失能jtag。以下是代码部分:

.h

#include "sys.h" 
#include <stdio.h>

extern u8 I2S_RX;
extern u8 I2S_TX;

extern uint32_t I2S2_Rx_Cnt ;
extern uint32_t I2S3_Tx_Cnt ;
extern uint8_t I2S2_Buffer_Rx[Rx_Len];
extern uint8_t I2S3_Buffer_Tx[Tx_Len];

void STM32F10X_I2S_Init(void);

.c

#include "bsp_i2s.h"

#define Rx_Len  1024*24
#define Tx_Len  1024*24

uint32_t I2S2_Rx_Cnt = 0;
uint32_t I2S3_Tx_Cnt = 0;

uint8_t I2S2_Buffer_Rx[Rx_Len];
uint8_t I2S3_Buffer_Tx[Tx_Len];

/*
**************************************************************************
*	函 数 名: I2S_NVIC_Config
*	功能说明: 配置I2S NVIC通道(中断模式)。
*	形    参:  无
*	返 回 值: 无
**************************************************************************
*/
static void I2S_NVIC_Config(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  /* SPI2 IRQ Channel configuration */
  NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* SPI3 IRQ channel configuration */
  NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_Init(&NVIC_InitStructure);
}
 /*
*************************************************************************
*	函 数 名: STM32F10X_I2S_Init
*	功能说明: 配置I2S
*	形    参: 无
*	返 回 值: 无
*************************************************************************
*/
void STM32F10X_I2S_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	I2S_InitTypeDef I2S_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

	/* SPI2 and SPI3 clocks enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB1Periph_SPI3, ENABLE);

	/* Disable the JTAG interface and enable the SWJ interface */
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

	/* Configure SPI2 pins: CK, WS and SD --------------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
		
	/* Configure I2S2 pins: MCK ------------------------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/* Configure SPI3 pins: CK and SD ------------------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/* Configure SPI3 pins: WS -------------------------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure I2S3 pins: MCK ------------------------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
		
	/* I2S peripheral configuration */
	I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
	I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;//extended
	I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
	I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_16k;
	I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;

	/* I2S2 Master Transmitter to I2S3 Slave Receiver communication ------------*/
	/* I2S2 configuration */
	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
	I2S_Init(SPI2, &I2S_InitStructure);

	/* I2S3 configuration */
	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
	I2S_Init(SPI3, &I2S_InitStructure);

	/* Enable the I2S2 RxNE interrupt */
	SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

	/* Enable the I2S3 TxE interrupt */
	SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);

//	/* Enable the I2S2 */
	I2S_Cmd(SPI2, ENABLE);

//	/* Enable the I2S3 */
	I2S_Cmd(SPI3, ENABLE);

	I2S_NVIC_Config();
}


void SPI2_IRQHandler()
{
  if (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
	{	
		2S2_Buffer_Rx[I2S2_Rx_Cnt++] = SPI_I2S_ReceiveData(SPI2);
    }
			
}

void SPI3_IRQHandler()
{
	if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET)
	{
		/* Send a data from I2S2 */
		SPI_I2S_SendData(SPI3, I2S3_Buffer_Tx[I2S3_Tx_Cnt++]);
	}

	/* Check the end of buffer transfer */
	if (I2S3_Tx_Cnt == Tx_Len)
	{
		/* Disable the I2S2 TXE interrupt to end the communication */
		SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE);
		I2S3_Tx_Cnt = 0;
	}
}

### CentOS 镜像中 README 文件的作用 README 文件通常作为文档的一部分,在操作系统或软件包的分发过程中起到指导和说明的作用。对于 CentOS 的镜像而言,其 README 文件的主要意义在于提供关于该版本的操作系统的关键信息以及安装指南。 #### 1. 提供版本信息 README 文件会明确指出当前镜像是哪个具体版本的 CentOS,例如 `CentOS Linux release 7.9.2009 (Core)`[^1]。这有助于用户确认所下载的是正确的发行版,并了解与其兼容的硬件和软件环境。 #### 2. 描述安装前准备事项 在实际部署之前,用户可能需要完成一些必要的准备工作,比如安装工具 Git 或者其他依赖项。这些内容往往会在 README 中有所提及,帮助新手快速上手。 #### 3. 解决常见问题 针对可能出现的问题,如文件上传验证通过后的反馈机制——返回文件名表示成功[^2];或者如何正确配置服务端口映射等复杂场景下的解决方案也可能被记录下来以便查阅。 #### 4. 列举第三方库源地址 有时为了扩展功能,官方文档还会给出获取额外资源的方法论实例:“`wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz`” 就是用来示范怎样从外部站点拉取所需组件的例子之一[^3]。 #### 5. 展示高级设置教程 除了基本操作外,更深入的技术细节也会包含其中,例如为了让 NVM 成为全局变量而修改特定路径下的脚本文件 `/etc/profile.d/nvm.sh` [^4] ,或者是利用 FTP 协议传输大容量数据时推荐采用 Binary Mode 来保持文件完整性[^5]。 综上所述,README 不仅是一个简单的介绍性文本,更是连接开发者与最终用户的桥梁,它承载着丰富的背景资料和技术支持,使得整个安装过程更加顺畅高效。 ```bash # 示例命令展示如何查看本地是否存在类似的 readme 文档 ls /path/to/your/downloaded/image/*.txt | grep -i "readme" cat /path/to/found/readme.txt ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值