CH32V307 uart dma
时间: 2024-05-15 22:10:26 浏览: 14
CH32V307是一款基于8051内核的超低功耗微控制器,它内置了多个UART和DMA控制器,其中UART和DMA控制器可以协同工作,实现高效率的数据传输。在这款芯片中,UART和DMA控制器相互配合,可以实现无需CPU干预的数据传输。
其中,UART(Universal Asynchronous Receiver/Transmitter)是一种通用的异步收发器,常用于串口通讯。而DMA(Direct Memory Access)则是直接内存访问技术,它可以在不经过CPU的情况下进行数据传输。这两种技术结合在一起,可以实现高效的串口数据传输。
在CH32V307芯片中,DMA控制器可以通过配置相应的寄存器,实现对UART数据收发缓冲区的直接读写,而不需要CPU的干预,这样可以极大地减少CPU的负担,提高系统效率。同时,由于DMA控制器本身就是硬件级别的实现,因此可以提高数据传输的可靠性和稳定性。
相关问题
gd32 uart dma
GD32 UART DMA是一种通过DMA(直接内存访问)方式实现UART数据传输的方法。相比于CPU直接操作UART,使用DMA可以减轻CPU的负担,提高数据传输效率。下面是GD32 UART DMA的实现步骤:
1. 配置UART和DMA通道,使它们能够正常工作。
2. 配置DMA通道的传输方向、传输数据长度、传输数据地址等参数。
3. 使能DMA通道和UART的DMA传输功能。
4. 在DMA传输完成后,通过DMA传输完成中断或者查询方式获取传输状态。
下面是一个GD32 UART DMA的例子:
```c
#include "gd32f10x.h"
#define USART0_DR_ADDRESS ((uint32_t)0x40013804)
#define BUFFER_SIZE 32
uint8_t tx_buffer[BUFFER_SIZE] = "GD32 UART DMA test\r\n";
uint8_t rx_buffer[BUFFER_SIZE];
void dma_config(void)
{
dma_parameter_struct dma_init_struct;
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA0);
/* initialize DMA channel 2 */
dma_deinit(DMA0, DMA_CH2);
dma_struct_para_init(&dma_init_struct);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_addr = (uint32_t)tx_buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INC_ENABLE;
dma_init_struct.periph_addr = USART0_DR_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INC_DISABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init_struct.number = BUFFER_SIZE;
dma_init(DMA0, DMA_CH2, &dma_init_struct);
/* enable DMA channel 2 */
dma_channel_enable(DMA0, DMA_CH2);
}
void usart_config(void)
{
usart_parameter_struct usart_init_struct;
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* initialize USART */
usart_deinit(USART0);
usart_struct_para_init(&usart_init_struct);
usart_init_struct.baud_rate = 115200;
usart_init_struct.word_length = USART_WL_8BIT;
usart_init_struct.stop_bits = USART_STB_1BIT;
usart_init_struct.parity = USART_PM_NONE;
usart_init_struct.flow_control = USART_FC_NONE;
usart_init_struct.mode = USART_MODE_TX_RX;
usart_init(USART0, &usart_init_struct);
/* enable USART DMA TX */
usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
/* enable USART */
usart_enable(USART0);
}
int main(void)
{
dma_config();
usart_config();
/* wait DMA transmit complete */
while(!dma_flag_get(DMA0, DMA_CH2, DMA_FLAG_FTF));
/* clear DMA transmit complete flag */
dma_flag_clear(DMA0, DMA_CH2, DMA_FLAG_FTF);
/* enable DMA channel 3 */
dma_channel_enable(DMA0, DMA_CH3);
/* wait DMA receive complete */
while(!dma_flag_get(DMA0, DMA_CH3, DMA_FLAG_FTF));
/* clear DMA receive complete flag */
dma_flag_clear(DMA0, DMA_CH3, DMA_FLAG_FTF);
/* disable DMA channel 3 */
dma_channel_disable(DMA0, DMA_CH3);
/* disable USART */
usart_disable(USART0);
while(1);
}
```
GD32F303 UART DMA例程、
以下是一个基于GD32F303的UART DMA例程,可用于向UART发送数据:
```
#include "gd32f30x.h"
#define USART0_DMA_TX_CH DMA_CH3
uint8_t tx_buffer[] = "Hello, World!\r\n";
uint32_t buffer_size = sizeof(tx_buffer);
int main(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable USART0 clock */
rcu_periph_clock_enable(RCU_USART0);
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA);
/* configure USART0 GPIO */
gpio_mode_set(GPIOA, GPIO_MODE_AF_PP, GPIO_PUPD_PULLUP, GPIO_PIN_9);
gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
/* configure USART0 */
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
/* configure DMA */
dma_deinit(DMA0);
dma_channel_disable(DMA0, USART0_DMA_TX_CH);
dma_periph_address_config(DMA0, USART0_DMA_TX_CH, (uint32_t)&USART_DATA(USART0));
dma_memory_address_config(DMA0, USART0_DMA_TX_CH, (uint32_t)tx_buffer);
dma_transfer_direction_config(DMA0, USART0_DMA_TX_CH, DMA_MEMORY_TO_PERIPHERAL);
dma_memory_data_size_config(DMA0, USART0_DMA_TX_CH, DMA_MEMORY_WIDTH_8BIT);
dma_periph_data_size_config(DMA0, USART0_DMA_TX_CH, DMA_PERIPHERAL_WIDTH_8BIT);
dma_transfer_number_config(DMA0, USART0_DMA_TX_CH, buffer_size);
dma_channel_priority_config(DMA0, USART0_DMA_TX_CH, DMA_PRIORITY_HIGH);
dma_circulation_enable(DMA0, USART0_DMA_TX_CH);
dma_memory_increment_enable(DMA0, USART0_DMA_TX_CH);
dma_periph_increment_disable(DMA0, USART0_DMA_TX_CH);
/* enable DMA channel */
dma_channel_enable(DMA0, USART0_DMA_TX_CH);
/* start DMA transfer */
usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
while (1);
}
```
该例程使用了USART0和DMA通道3来发送数据。在主函数中,我们首先使能了GPIO、USART0和DMA的时钟。然后,我们配置了USART0的GPIO引脚,包括TX引脚(PA9)和RX引脚(PA10)。接下来,我们配置了USART0的波特率、数据位数、停止位数、校验位等参数,并启用了接收和发送功能。最后,我们配置了DMA通道3以将数据从内存传输到USART0,启用了循环传输和内存地址自增功能,并启用了DMA通道。最后,我们通过调用`usart_dma_transmit_config()`函数启动了DMA传输。
在上述例程中,我们发送了一个字符串“Hello, World!\r\n”。我们可以通过修改`tx_buffer`和`buffer_size`变量来发送不同的数据。如果需要接收数据,我们可以使用类似的方法配置USART0的接收功能,并使用DMA通道来接收数据。