Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F205 SPI RX DMA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Копейкин
Контроллер STM32F205RET6.
От АЦП(режим slave) идёт поток данных пакетами по SPI.
SPI настраиваю на режим только приёма, мастер.
Пытаюсь задействовать DMA2_Stream2 Channel 3 для принятия пакета 16 байт.
Отслеживаю передачу осциллографом по линии SCK.
Наблюдаю посылку 16-ти импульсов SCK (2-байта),
при этом устанавливается флаг нормального завершения DMA трансфера.
Написал тестовый проект(во вложении) и уже голову сломал - что не так?
Возможен вообще такой режим работы SPI - мастер, только приём, DMA?
Управление CS - планируется программное, через GPIO
Среда IAR EW ARM 6.2, отлаживаю через ST-LINK в internal RAM
Подскажите, как быть, пожалуйста. laughing.gif
Нажмите для просмотра прикрепленного файла
nx6310
У вас
количество байт стоит 8 хотя вы хотите принять 16 байт
Код
DMA2_Stream2->NDTR  = 8;

вместо адресов регистров приема spi у вас записано значение этого регистра
Код
DMA2_Stream2->PAR   = SPI1->DR;

надо писать
Код
DMA2_Stream2->PAR   =&SPI1->DR;

DMA надо включать перед настройкой spi на режим приема
возможно надо настроить формат слов для приемной и передающей частей

ваш код я бы переделал вот так
Код
    SPI1->CR1           &= ~0x40; // SPI stopped
DMA2_Stream2-> CR   = 0;    // Disable & DeInit
DMA2->LIFCR         = 0x003D0000; // Clear flags for Stream2
    
    DMA2_Stream2->CR    = (3<<25)|(1<<16)|(1<<10);  // Channel3 | PriorityMedium | MemInc (Single transfer)
    DMA2_Stream2->NDTR  = 16;                        // 8 bytes transfer SPI->RAM
    DMA2_Stream2->PAR   = &SPI1->DR;
    DMA2_Stream2->M0AR  = (unsigned long)pBuffer; // buffer in RAM
    
    //DMA2_Stream2->FCR   = 0;      // Direct mode
    DMA2_Stream2->FCR   = (1<<2);      // FIFO mode
    
    DMA2_Stream2->CR    |= 1;     // Enable DMA
  
    SPI_I2S_ReceiveData(SPI1);    // Clear SPI RX buffer, if not empty
    
    SPI1->CR2           |= 1;     // Enable RX DMA channel user
    
    SPI1->CR1           |= (1<<10)|(1<<6);  // Enable SPI | RX_ONLY mode





мой код на stm32f103 для сравнения
size - количество принимаемых байт
Код
    RCC->AHBENR |=RCC_AHBENR_DMA1EN;
    DMA1_Channel4->CNDTR=size;
    DMA1_Channel4->CPAR=&spi->DR;
    DMA1_Channel4->CMAR=RxData;
    DMA1_Channel4->CCR=0x82;// incMEM? dir-read form PERIF
DMA1_Channel4->CCR|=0x01;
spi->CR1|=SPI_Direction_2Lines_RxOnly;
while(RCC->AHBENR&RCC_AHBENR_DMA1EN);__WFI();//флаг обнуляется в прерывании там же отключается тактирование и spi переводится в режим
//приемопередатчика
while(spi->SR&SPI_I2S_FLAG_BSY);
spi->CR1&=~0x0040;
spi->CR1 |= 0x0020;
RCC->APB1ENR&=~RCC_APB1ENR_SPI2EN;
CS_M_1;
Копейкин
nx6310, спасибо Вам огромное!!!
Код заработал.
Фатальная ошибка была в строке:
Код
DMA2_Stream2->PAR   = &SPI1->DR; // следует указать адрес регистра!!!

В остальном код рабочий.
Разрешать DMA можно перед разрешением SPI, работает и в Вашем и в моём варианте, я проверил.
Или я проглядел официальные требования?
Количество принимаемых байт я варьировал с горя и отчаяния, вдруг поможет,
а так да следует: DMA2_Stream2->NDTR = 16
nx6310
Когда spi переводишь в режим приема на ноге sclk генерируется сигнал. если включать dma после настройки spi, то получается некая задержка, скорее всего она несущественная, но я предпочитаю подстраховываться.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.