STM32L1的直接存储器访问RX

问题描述 投票:3回答:2

我已经尝试了一段时间,以通过USART将数据块从计算机传输到STM32L100C-DISCO。出于性能原因,将使用DMA进行此操作。但是,到目前为止,我还无法使其正常运行。由于我似乎无法弄清楚自己可能做错了什么,所以我想在这里问。

我正在使用libopencm3,但不幸的是,它们原本出色的repository of examplesSTM32L1xxx上似乎不包含DMA。我检查了一下common DMA header file中可用的配置选项是否涵盖了所有基础。

自然,我已经参考了STM32L1xxx的参考手册,其中提到了DMA1的以下请求表,使我相信通道6是我需要使用的。。

““>

[由于我不确定内存和外围设备的大小(即USART2),因此我在8位,16位和32位的所有组合上都有所不同,但无济于事。

不用多说;这是我要尝试做的最少工作(嗯,没工作..)。我觉得我正在忽略DMA配置中的某些内容,因为USART本身可以正常工作。

在这一点上,任何事情都值得赞赏。

这段代码的思想基本上是永远循环直到缓冲区中的数据被完全替换,然后将其输出。从主机,我正在发送一千个高度可识别的数据,但我得到的只是格式错误的垃圾。它[[是

写一些东西,但不是我打算写的东西。编辑:这是内存映射的图片。 USART2_BASE的计算结果为0x4000 4400,所以似乎也没问题。

“内存映射”“>

#include <libopencm3/stm32/rcc.h> #include <libopencm3/stm32/gpio.h> #include "libopencm3/stm32/usart.h" #include <libopencm3/stm32/dma.h> const int buflength = 1024; uint8_t buffer[1024]; static void clock_setup(void) { rcc_clock_setup_pll(&clock_config[CLOCK_VRANGE1_HSI_PLL_32MHZ]); rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); rcc_periph_clock_enable(RCC_DMA1); } static void gpio_setup(void) { gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO3); gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); gpio_set_af(GPIOA, GPIO_AF7, GPIO3); gpio_set_af(GPIOA, GPIO_AF7, GPIO2); } static void usart_setup(void) { usart_set_baudrate(USART2, 115200); usart_set_databits(USART2, 8); usart_set_stopbits(USART2, USART_STOPBITS_1); usart_set_mode(USART2, USART_MODE_TX_RX); usart_set_parity(USART2, USART_PARITY_NONE); usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); usart_enable(USART2); } static void dma_setup(void) { dma_channel_reset(DMA1, DMA_CHANNEL6); dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_VERY_HIGH); dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL6); dma_enable_circular_mode(DMA1, DMA_CHANNEL6); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6); dma_disable_transfer_error_interrupt(DMA1, DMA_CHANNEL6); dma_disable_half_transfer_interrupt(DMA1, DMA_CHANNEL6); dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL6); dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t) USART2_BASE); dma_set_memory_address(DMA1, DMA_CHANNEL6, (uint32_t) buffer); dma_set_number_of_data(DMA1, DMA_CHANNEL6, buflength); dma_enable_channel(DMA1, DMA_CHANNEL6); } int main(void) { int i; for (i = 0; i < buflength; i++) { buffer[i] = 65; } clock_setup(); gpio_setup(); usart_setup(); dma_setup(); usart_enable_rx_dma(USART2); char flag = 1; while (flag) { flag = 0; for (i = 0; i < buflength; i++) { if (buffer[i] == 65) { flag = 1; } } } usart_disable_rx_dma(USART2); for (i = 0; i < buflength; i++) { usart_send_blocking(USART2, buffer[i]); } usart_send_blocking(USART2, '\n'); return 0; }

我已经尝试了一段时间,以通过USART将数据块从计算机传输到STM32L100C-DISCO。出于性能原因,将使用DMA进行此操作。到目前为止,我还没有...
microcontroller stm32 dma usart libopencm3
2个回答
3
投票
我不熟悉libopencm3或STM32L系列,但是我熟悉STM32F系列。我知道外围设备有所不同,但我相信您的错误在于以下几行:

dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t) USART2_BASE);


1
投票
最后,这是我用来使其正常工作的配置。
© www.soinside.com 2019 - 2024. All rights reserved.