【GD32E231 DIY】USART0使用DMA发送与接收,不点用CPU
[复制链接]
1.硬件上直接用USB转RS-232(TLL电平)TX接上PA10。RX接上PA9
2.main.c初始化
int main(void)
{
uint8_t *test="turn off LED1";
uint8_t *test1="turn on LED1";
uint8_t test2;
systick_config();
/* enable the LED1 GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* configure LED1 GPIO port */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7|GPIO_PIN_8);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7|GPIO_PIN_8);
/* reset LED1 GPIO pin */
gpio_bit_reset(GPIOA,GPIO_PIN_7|GPIO_PIN_8);
uart_init(115200);
while(1){
/* turn on LED1 */
gpio_bit_set(GPIOA,GPIO_PIN_7);gpio_bit_set(GPIOA,GPIO_PIN_8);
/* for(test2=0;test2<12;test2++)
USART0_DMA_TX_BUFFER[test2]=*(test1+test2);
USART0_DMA_TX_CNT=12;
USART0_DMA_TX_Send();*/
delay_1ms(1000);
/* turn off LED1 */
gpio_bit_reset(GPIOA,GPIO_PIN_7);gpio_bit_reset(GPIOA,GPIO_PIN_8);
/* for(test2=0;test2<13;test2++)
USART0_DMA_TX_BUFFER[test2]=*(test+test2);
USART0_DMA_TX_CNT=13;
USART0_DMA_TX_Send();*/
USART0_DMA_TX_CNT = USART0_DMA_RX_CNT;
for(test2=0;test2<USART0_DMA_TX_CNT;test2++)
{
USART0_DMA_RX_CNT=0;
USART0_DMA_TX_BUFFER[test2]=USART0_DMA_RX_BUFFER[test2];
}
USART0_DMA_TX_Send();
delay_1ms(1000);
}
}
3UsartDma实现USART——DMA工能
#include "usartdma.h"
/**
USART2_RX PD6 通道 4 DMA1数据流 5
USART2_TX PD5 通道 4 DMA1数据流 6
**/
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif /* __GNUC__ */
uint8_t USART0_DMA_RX_BUFFER[USART0_DMA_RX_BUFFER_MAXIMUM];
uint8_t USART0_DMA_TX_BUFFER[USART0_DMA_TX_BUFFER_MAXIMUM];
uint8_t USART0_DMA_RX_CNT;
uint8_t USART0_DMA_TX_CNT;
/*
* 函数名:fputc
* 描述 :重定向c库函数printf到USART1
* 输入 :无
* 输出 :无
* 调用 :由printf调用
*/
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART3 and Loop until the end of transmission */
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
usart_data_transmit(USART0, (uint8_t) ch);
return ch;
}
GETCHAR_PROTOTYPE
{
return usart_data_receive(USART0);
}
/*****************************************************************************/
//初始化IO 串口3
//bound:波特率
void uart_init(uint32_t bound)
{
dma_parameter_struct dma_init_struct;
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA);
/* initilize the com */
/* enable COM GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* connect port to USARTx_Tx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9);
/* connect port to USARTx_Rx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_10);
/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
/* enable and set EXTI interrupt */
nvic_irq_enable(USART0_IRQn, 1U);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* USART configure */
usart_deinit(USART0);
usart_baudrate_set(USART0, bound);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_interrupt_enable(USART0,USART_INT_IDLE);
usart_enable(USART0);
/* enable and set EXTI interrupt */
nvic_irq_enable(DMA_Channel1_2_IRQn, 1U);
// deinitialize DMA channel1
dma_deinit(DMA_CH1);
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_addr = (uint32_t)USART0_DMA_TX_BUFFER;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = USART0_DMA_TX_BUFFER_MAXIMUM;
dma_init_struct.periph_addr = USART0_TDATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA_CH1,&dma_init_struct);
/* configure DMA mode */
dma_circulation_disable(DMA_CH1);
dma_memory_to_memory_disable(DMA_CH1);
dma_interrupt_flag_clear(DMA_CH1,DMA_INT_FLAG_FTF);
dma_interrupt_enable(DMA_CH1,DMA_INT_FTF);
/* enable DMA channel1 */
// dma_channel_enable(DMA_CH1);
/* USART DMA enable for transmission and reception */
usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
/* deinitialize DMA channel2 */
dma_deinit(DMA_CH2);
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_addr = (uint32_t)USART0_DMA_RX_BUFFER;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = USART0_DMA_RX_BUFFER_MAXIMUM;
dma_init_struct.periph_addr = USART0_RDATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA_CH2, &dma_init_struct);
dma_circulation_disable(DMA_CH2);
dma_memory_to_memory_disable(DMA_CH2);
dma_channel_enable(DMA_CH2);
usart_dma_receive_config(USART0, USART_DENR_ENABLE);
}
void USART0_DMA_TX_Send(void)
{
if(USART0_DMA_TX_CNT != 0)
{
/* configure the number of remaining data to be transferred */
DMA_CHCNT(DMA_CH1) = (USART0_DMA_TX_CNT & DMA_CHANNEL_CNT_MASK); // 设置要发送的字节数目
USART0_DMA_TX_CNT = 0;
/* enable DMA channel1 */
dma_channel_enable(DMA_CH1);
}
}
void DMA_Channel1_2_IRQHandler(void)
{
if(dma_flag_get(DMA_CH1, DMA_FLAG_FTF))
{
dma_interrupt_flag_clear(DMA_CH1,DMA_INT_FLAG_FTF);
dma_channel_disable(DMA_CH1);
}
else
{
dma_interrupt_flag_clear(DMA_CH1,DMA_INT_FLAG_G);
}
}
//============================================================//
//DMA 接收应用源码
void USART0_IRQHandler(void)
{
if(usart_interrupt_flag_get(USART0,USART_INT_FLAG_IDLE) != RESET) // 空闲中断
{
dma_channel_disable(DMA_CH2);// 关闭DMA ,防止干扰
USART0_DMA_RX_CNT = USART0_DMA_RX_BUFFER_MAXIMUM - DMA_CHCNT(DMA_CH2);
DMA_CHCNT(DMA_CH2) = (USART0_DMA_RX_BUFFER_MAXIMUM & DMA_CHANNEL_CNT_MASK);
dma_channel_enable(DMA_CH2);
usart_interrupt_flag_clear(USART0,USART_INT_FLAG_IDLE);// Clear IDLE interrupt flag bit
}
}
USART_DMA_ok.rar
(5.37 MB, 下载次数: 238)
欢迎大家一起交流,优化
|