INMP441 кто с ним работал?

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Встал на лапы
Сообщения: 99
Зарегистрирован: Пт ноя 19, 2010 21:08:56
Откуда: РБ-->Мозырь

Сообщение Jebocom »

Доброго времени суток.
Пытался повторить проект с микрофоном INMP441 с ютуба со ссылкой на код на гитхабе. Проект сделан на HAL. У меня китайская плата на процессоре stm32f407zgt6. Вроде сходу начало писать информацию, но при прослушивании в audacity абсолютная ерунда. Даже не слышу что-то похожее на голос, хотя громко включал ютуб передачи на телефоне и подносил к микрофону.
У меня есть еще плата stm32f3discovery. Попробовал на ней и результат тот же. Пробовал второй микрофон и такая же ерунда.

Тогда я запарился и переделал проект на CMSIS и в результате...пишет такую же какафонию с каким-то писком. Я сделал на stm32f3discovery slave-передатчик, а на китайской мастер-приемник и все прекрасно работает. Но не с микрофоном.

Я выложу свой код здесь, может кто сталкивался и сможет чего подсказать. Принцип простейший. Значащие первые 3 байта (24 бита на 32-битное слово). Сначала принимаю информацию от микрофона по I2S в буфер(64 слова 16-битных). От первого слова беру 2 байта, а от второго 1 первый байт и заполняю буфер на отправку в UART. Как заполнится - отправляю.
Пробовал отправлять первые 2 байта (типа 16 бит на 32 разрядное слово) - без толку тоже.

main.c:
Спойлер

Код: Выделить всё

#include "main.h"
#include "dma.h"
#include "i2s.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

uint16_t BUF_I2S[64];
uint8_t transmit_UART4[12];

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

void SPI2_DMA_sets(void);
void I2S_set(void);
void UART4_DMA_sets(void);
void USART4_sets(void);

/* USER CODE END PTD */

void SystemClock_Config(void);

int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();


  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  I2S_set();
  SPI2_DMA_sets();
  USART4_sets();
  UART4_DMA_sets();

  while((GPIOA->IDR&0x1)!=0x1)
  	  {;}

  SPI2->I2SCFGR	|= 1<<10;		// включаем I2S2
  DMA1_Stream3->CR |= 1;		// включаем DMA

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/* USER CODE BEGIN 4 */
void I2S_set(void)
  {
	RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;		// тактирование I2S2
	SPI2->I2SPR |= 0x31; 	                                // ODE = 0, DIV = 0x31

	SPI2->I2SCFGR |= 1<<11;	// I2SMOD: Enable (1)
	SPI2->I2SCFGR |= 3<<8;	// 1 1(9 8) - master recive
	SPI2->I2SCFGR |= 1<<1;	// DATLEN - 01(24 bit)
	SPI2->I2SCFGR |= 1;		// CHLEN - 01(32 bit)

	SPI2->I2SCFGR |= 1<<3;	// polarity high
	SPI2->CR2 |= 1;			// RXDMAEN: Rx buffer DMA enable

	GPIO_InitTypeDef GPIO_InitStruct = {0};
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

	  /* USER CODE BEGIN SPI2_MspInit 0 */

	  /* USER CODE END SPI2_MspInit 0 */
	  /** Initializes the peripherals clock
	  */
	    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
	    PeriphClkInitStruct.PLLI2S.PLLI2SN = 50;
	    PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
	    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
	    {
	      Error_Handler();
	    }
  }

void SPI2_DMA_sets(void)
  {
	RCC->AHB1ENR|=RCC_AHB1ENR_DMA1EN;				// включаем тактирование DMA1

	DMA1_Stream3->PAR=(volatile uint32_t)(&(SPI2->DR));		// (volatile uint32_t)
	DMA1_Stream3->M0AR=(volatile uint32_t)BUF_I2S;			//tmp;//send_spi;
	DMA1_Stream3->NDTR=64;
	DMA1_Stream3->CR |= 1<<16;								// PL:	 	 0 1: Medium priority
	DMA1_Stream3->CR |= 1<<10;								// MINC:	 1: Enabled
	DMA1_Stream3->CR |= 0<<4;								// DIR:	 0: Read from peripheria
	DMA1_Stream3->CR |= 1<<13;								// 16 - bit пакет (msize)
	DMA1_Stream3->CR |= 1<<11;								// 16 - bit пакет (psize)
	DMA1_Stream3->CR |= 1<<8;								// CIRC: Circular mode - Enable (1)

	DMA1_Stream3->CR |= 1<<3; // включаем прерывание по приему половины пакета данных
	DMA1_Stream3->CR |= 1<<4; // включаем прерывание по приему полного пакета данных данных

//	Настройка порта "B"
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;	// включить тактирование порта "B"

	GPIOB->MODER |= 0x280000;			//	Включаем PB9, PB10 - альтернативная функция
	GPIOB->AFR[1] |= 0x550;				//	включаем альтернативную функцию для AF5 для PB9, PB10

//	Настройка порта "C"
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;	// включить тактирование порта "C"

	GPIOC->MODER |= 0x80;					//	Включаем PC3 - альтернативная функция
	GPIOC->AFR[0] |= 0x5000;				//	включаем альтернативную функцию для AF5 для PC3
	GPIOC->OSPEEDR |= 0xC0;					//	скорость порта 11: Very high speed

	NVIC_EnableIRQ(DMA1_Stream3_IRQn);		// разрешение прерывания DMA1_Stream3 в регистре прерываний
	NVIC_SetPriority(DMA1_Stream3_IRQn, 1);	// установка приоритета прерывания в регистре прерываний
  }

void USART4_sets(void)
  {
		RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;	// включить тактирование порта "C"
		GPIOC->MODER |= 0x200000;				// включаем на порту PC10 режим "альтернативная функция" AF8
		GPIOC->AFR[1] |= 0x800;					// включаем альтернативную функцию для AF8 (Tx) для PC10

		RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;	// включить тактирование порта "A"
		GPIOA->MODER |= 0x8;					// включаем на порту PA1 режим "альтернативная функция" AF8
		GPIOA->AFR[0] |= 0x80;					// включаем альтернативную функцию для AF8 (Rx) для PA1

		RCC->APB1ENR |=RCC_APB1ENR_UART4EN;

		UART4->BRR =0x9C;	 // 230400  // 0x4E;	460800	//0x138; 115200 (скорость обмена)	//

		UART4->CR1 |= 1<<7;						//  включаем	TXEIE
		UART4->CR1 |= 1<<3;						// Transmitter enable

		UART4->CR1 |= 1<<13;					// включаем UART
  }

void UART4_DMA_sets(void)
  {
	RCC->AHB1ENR|=RCC_AHB1ENR_DMA1EN;						// включаем тактирование DMA1
	DMA1_Stream4->CR |= 1<<27;								// выбираем канал 4
	DMA1_Stream4->PAR = (volatile uint32_t)&(UART4->DR);
	DMA1_Stream4->M0AR = (volatile uint32_t)transmit_UART4;
	DMA1_Stream4->NDTR = 8;			//	12;
	DMA1_Stream4->CR |= 1<<16;								// PL:	  0 1: Medium priority
	DMA1_Stream4->CR |= 1<<10;								// MINC:	1: Enabled
	DMA1_Stream4->CR |= 1<<6;								// DIR:	(7 6) 0 1: Read from memory to periph

	DMA1_Stream4->CR |= 1<<4; 			// включаем прерывание по приему полного пакета данных данных

	UART4->SR &= ~0x40;

	NVIC_EnableIRQ(DMA1_Stream4_IRQn);		// разрешение прерывания DMA1_Stream3 в регистре прерываний
	NVIC_SetPriority(DMA1_Stream4_IRQn, 1);	// установка приоритета прерывания в регистре прерываний
  }
/* USER CODE END 4 */
_it.c(только мои функции):
Спойлер

Код: Выделить всё

/* USER CODE BEGIN TD */
extern uint16_t BUF_I2S[64];
extern uint8_t transmit_UART4[12];					// [12];
/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint8_t tmp=0;
uint8_t c=0;
volatile uint16_t cnt=0;	// volatile
/* USER CODE END PD */

void DMA1_Stream3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */

	if((DMA1->LISR&0x8000000)==0x8000000)
			{
				DMA1->LIFCR |= 0x8000000;

				uint8_t i,j;
					for(i=0,j=0;i<16;i=i+4,j=j+3)
					  {
						transmit_UART4[j] = (uint8_t)((BUF_I2S[i+32]&0xFF00)>>8);
						transmit_UART4[j+1] = (uint8_t)(BUF_I2S[i+32]&0x00FF);
						transmit_UART4[j+2] = (uint8_t)((BUF_I2S[i+33]&0xFF00)>>8);
					  }

					DMA1_Stream4->NDTR = 12;			         // 12;

					DMA1_Stream4->CR |= 1;					// включаем DMA

					UART4->CR3 |= 1<<7;						// DMAT: DMA enable transmitter
			}

	if((DMA1->LISR&0x4000000)==0x4000000)
		{

			DMA1->LIFCR |= 0x4000000;
			uint8_t i,j;
				for(i=0,j=0;i<16;i=i+4,j=j+3)
				  {
					transmit_UART4[j] = (uint8_t)((BUF_I2S[i]&0xFF00)>>8);
					transmit_UART4[j+1] = (uint8_t)(BUF_I2S[i]&0x00FF);
					transmit_UART4[j+2] = (uint8_t)((BUF_I2S[i+1]&0xFF00)>>8);
				  }

				DMA1_Stream4->NDTR = 12;			// 12;

				DMA1_Stream4->CR |= 1;					// включаем DMA

				UART4->CR3 |= 1<<7;						// DMAT: DMA enable transmitter

		}
}

void DMA1_Stream4_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
	if((DMA1->HISR&0x20)==0x20)
	  {
		UART4->CR3 &= ~0x80;			// DMAT: DMA disable transmitter
		DMA1_Stream4->CR &= ~1;			// выключаем DMA
	  }
	DMA1->HIFCR |= 0x30;
}
Реклама
Ответить

Вернуться в «ARM»