gd32 串口DMA发送&双缓冲接收不定长数据例程
创始人
2024-11-13 16:07:28
0

main.c

/*!     \file    main.c     \brief   running LED      \version 2023-03-31, V1.0.0, firmware for GD32H7xx */  /*     Copyright (c) 2023, GigaDevice Semiconductor Inc.      Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:      1. Redistributions of source code must retain the above copyright notice, this        list of conditions and the following disclaimer.     2. Redistributions in binary form must reproduce the above copyright notice,        this list of conditions and the following disclaimer in the documentation        and/or other materials provided with the distribution.     3. Neither the name of the copyright holder nor the names of its contributors        may be used to endorse or promote products derived from this software without        specific prior written permission.      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */  #include "gd32h7xx.h" #include "systick.h"  #include "string.h" #include "stdio.h" #include "circular_buffer.h"   #define USART_DMA_TRANSFER_SIZE 4096  __attribute__ ((aligned(32))) uint8_t usart_rx_buff0[USART_DMA_TRANSFER_SIZE] = {0}; __attribute__ ((aligned(32))) uint8_t usart_rx_buff1[USART_DMA_TRANSFER_SIZE] = {0}; __attribute__ ((aligned(32))) uint8_t circular_buffer_data[USART_DMA_TRANSFER_SIZE] = {0};   struct circular_buffer_t circular_buffer;   volatile static int rx_buff_select = 0;  uint8_t* get_rx_buff() {     if (rx_buff_select) return usart_rx_buff0;     else return usart_rx_buff1; }  uint8_t* get_next_rx_buff() {     rx_buff_select = !rx_buff_select;     return get_rx_buff(); }   /*!     \brief      enable the CPU Chache     \param[in]  none     \param[out] none     \retval     none */ static void cache_enable(void) {     /* Enable I-Cache */     SCB_EnableICache();      /* Enable D-Cache */ //    SCB_EnableDCache(); }  void led_config() {     rcu_periph_clock_enable(RCU_GPIOJ);      gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);     gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);      gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9);     gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9);      gpio_bit_set(GPIOJ, GPIO_PIN_8);     gpio_bit_set(GPIOJ, GPIO_PIN_9);  }  void clock_config() {     rcu_system_clock_source_config(RCU_CKSYSSRC_IRC64MDIV);     rcu_deinit();      rcu_osci_on(RCU_HXTAL); //开启外部时钟     rcu_osci_stab_wait(RCU_HXTAL); //等待外部时钟稳定 25MHZ      rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV2); //AHB 300MHz     rcu_apb1_clock_config(RCU_APB1_CKAHB_DIV2); //APB1 150MHz     rcu_apb2_clock_config(RCU_APB2_CKAHB_DIV1); //APB2 300MHz     rcu_apb3_clock_config(RCU_APB3_CKAHB_DIV2); //APB3 150MHz     rcu_apb4_clock_config(RCU_APB4_CKAHB_DIV2); //APB4 150MHz      rcu_pll_source_config(RCU_PLLSRC_HXTAL); //选择外部高速时钟源 25MHz      rcu_pll0_config(1, 24, 1, 1, 1); //PLL0P 600MHz     rcu_pll_clock_output_enable(RCU_PLL0P | RCU_PLL0Q | RCU_PLL0R); //PLL0输出使能      RCU_CTL |= RCU_CTL_PLL0EN; //PLL0 使能      rcu_osci_stab_wait(RCU_PLL0_CK); //等待PLL0稳定      rcu_system_clock_source_config(RCU_CKSYSSRC_PLL0P); //CK_SYS 600MHz     SystemCoreClock = 600 * 1000 * 1000; //600MHz }  void usart_config() {     rcu_periph_clock_enable(RCU_GPIOB);     rcu_periph_clock_enable(RCU_USART0);      nvic_irq_enable(USART0_IRQn, 2, 2);      gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6);     gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7);      gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);      gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);      usart_deinit(USART0);     usart_word_length_set(USART0, USART_WL_8BIT);     usart_stop_bit_set(USART0, USART_STB_1BIT);     usart_parity_config(USART0, USART_PM_NONE);     usart_baudrate_set(USART0, 921600U);     usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);     usart_receive_config(USART0, USART_RECEIVE_ENABLE);     usart_interrupt_enable(USART0, USART_INT_IDLE);     usart_enable(USART0); }  void usart_transmit(char* buff, int size) {     for (int i = 0; i < size; ++i) {         usart_data_transmit(USART0, buff[i]);         while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {}     } }   void usart_transmit_dma(char* buff, int size) {     dma_memory_address_config(DMA0, DMA_CH0, DMA_MEMORY_0, buff);     dma_transfer_number_config(DMA0, DMA_CH0, size);     dma_channel_enable(DMA0, DMA_CH0); }   void dma_config() {     rcu_periph_clock_enable(RCU_DMA0);     rcu_periph_clock_enable(RCU_DMAMUX);     nvic_irq_enable(DMA0_Channel0_IRQn, 2, 1);     nvic_irq_enable(DMA0_Channel1_IRQn, 2, 0);      dma_single_data_parameter_struct dma_init_struct;      //TX     dma_deinit(DMA0, DMA_CH0);     dma_single_data_para_struct_init(&dma_init_struct);     dma_init_struct.request      = DMA_REQUEST_USART0_TX;     dma_init_struct.direction    = DMA_MEMORY_TO_PERIPH;     dma_init_struct.memory0_addr  = (uint32_t)0;     dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;     dma_init_struct.number       = 0;     dma_init_struct.periph_addr  = (uint32_t)(&USART_TDATA(USART0));     dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;     dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;     dma_single_data_mode_init(DMA0, DMA_CH0, &dma_init_struct);      dma_circulation_disable(DMA0, DMA_CH0);     usart_dma_transmit_config(USART0, USART_TRANSMIT_DMA_ENABLE);     dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF); //    dma_channel_enable(DMA0, DMA_CH0);      //RX     dma_deinit(DMA0, DMA_CH1);     dma_single_data_para_struct_init(&dma_init_struct);     dma_init_struct.request      = DMA_REQUEST_USART0_RX;     dma_init_struct.direction    = DMA_PERIPH_TO_MEMORY;     dma_init_struct.memory0_addr  = (uint32_t)get_next_rx_buff();     dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;     dma_init_struct.number       = USART_DMA_TRANSFER_SIZE;     dma_init_struct.periph_addr  = (uint32_t)(&USART_RDATA(USART0));     dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;     dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;     dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);      dma_circulation_disable(DMA0, DMA_CH1);     usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);     dma_interrupt_enable(DMA0, DMA_CH1, DMA_INT_FTF);     dma_channel_enable(DMA0, DMA_CH1); }  void DMA0_Channel0_IRQHandler() {     if (RESET != dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF)) {         dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_FTF);           gpio_bit_toggle(GPIOJ, GPIO_PIN_8);     } }  void DMA0_Channel1_IRQHandler() {     if (RESET != dma_interrupt_flag_get(DMA0, DMA_CH1, DMA_INT_FLAG_FTF)) { //传输完成         dma_interrupt_flag_clear(DMA0, DMA_CH1, DMA_INT_FLAG_FTF);          uint8_t* rx_buff = get_rx_buff();          dma_single_data_parameter_struct dma_init_struct;         dma_deinit(DMA0, DMA_CH1);         dma_single_data_para_struct_init(&dma_init_struct);         dma_init_struct.request      = DMA_REQUEST_USART0_RX;         dma_init_struct.direction    = DMA_PERIPH_TO_MEMORY;         dma_init_struct.memory0_addr  = (uint32_t)get_next_rx_buff();         dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;         dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;         dma_init_struct.number       = USART_DMA_TRANSFER_SIZE;         dma_init_struct.periph_addr  = (uint32_t)(&USART_RDATA(USART0));         dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;         dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;         dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);          dma_circulation_disable(DMA0, DMA_CH1);         usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);         dma_interrupt_enable(DMA0, DMA_CH1, DMA_INT_FTF);         dma_channel_enable(DMA0, DMA_CH1);          for (int i = 0; i < USART_DMA_TRANSFER_SIZE; ++i) circular_buffer_push_back(&circular_buffer, rx_buff[i]);          gpio_bit_toggle(GPIOJ, GPIO_PIN_9);     } }  void USART0_IRQHandler() {     if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) {         usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);           uint32_t size = USART_DMA_TRANSFER_SIZE - dma_transfer_number_get(DMA0, DMA_CH1);         uint8_t* rx_buff = get_rx_buff();          dma_single_data_parameter_struct dma_init_struct;         dma_deinit(DMA0, DMA_CH1);         dma_single_data_para_struct_init(&dma_init_struct);         dma_init_struct.request      = DMA_REQUEST_USART0_RX;         dma_init_struct.direction    = DMA_PERIPH_TO_MEMORY;         dma_init_struct.memory0_addr  = (uint32_t)get_next_rx_buff();         dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;         dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;         dma_init_struct.number       = USART_DMA_TRANSFER_SIZE;         dma_init_struct.periph_addr  = (uint32_t)(&USART_RDATA(USART0));         dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;         dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;         dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);          dma_circulation_disable(DMA0, DMA_CH1);         usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);         dma_interrupt_enable(DMA0, DMA_CH1, DMA_INT_FTF);         dma_channel_enable(DMA0, DMA_CH1);          for (int i = 0; i < size; ++i) circular_buffer_push_back(&circular_buffer, rx_buff[i]);          gpio_bit_toggle(GPIOJ, GPIO_PIN_9);     } }  /*!     \brief      main function     \param[in]  none     \param[out] none     \retval     none */ int main(void) {     /* enable the CPU Cache */     cache_enable();      clock_config(); //使用外部时钟      /* configure systick */     systick_config();      create_circular_buffer(&circular_buffer, circular_buffer_data, USART_DMA_TRANSFER_SIZE);      led_config();     usart_config();     dma_config();       char msg[] = "Hello World\r\n";     usart_transmit_dma(msg, strlen(msg));       while(1) {         while (circular_buffer_available(&circular_buffer)) {             char ch;             circular_buffer_pop_front(&circular_buffer, &ch);             usart_transmit(&ch, 1);         }         delay_1ms(1);     } }   

相关内容

热门资讯

透视智能!wpk辅助插件(透视... 透视智能!wpk辅助插件(透视)开挂辅助器(切实是有挂)-哔哩哔哩进入游戏-大厅左侧-新手福利-激活...
透视辅助!wepoker怎么设... 透视辅助!wepoker怎么设置房间,impoker辅助,妙计教程(真是真的是有挂)-哔哩哔哩1、实...
透视后台!wepokerh5破... 透视后台!wepokerh5破解(透视)开挂辅助挂(总是是有挂)-哔哩哔哩wepokerh5破解辅助...
据报道!雀神广东麻雀智能科技贴... 据报道!雀神广东麻雀智能科技贴吧,微信边锋辅助下载,黑科技教程(好像是真的挂)-哔哩哔哩1、雀神广东...
透视玄学!佛手大菠萝13道挂哪... 透视玄学!佛手大菠萝13道挂哪里,agpoker辅助,绝活教程(原来存在有挂)-哔哩哔哩1、每一步都...
透视代打ai!wejoker辅... 透视代打ai!wejoker辅助软件价格(透视)开挂辅助脚本(果然是有挂)-哔哩哔哩1、打开软件启动...
事发当天!闲来辅助器免费,微友... 事发当天!闲来辅助器免费,微友联盟辅助下载,第三方教程(都是存在有挂)-哔哩哔哩1、超多福利:超高返...
透视必胜!德州透视hhpoke... 透视必胜!德州透视hhpoker(透视)开挂辅助挂(总是存在有挂)-哔哩哔哩所有人都在同一条线上,像...
透视中牌率!aapoker破解... 透视中牌率!aapoker破解侠是真的吗,wepoker私人局怎么玩,指引教程(一贯是真的挂)-哔哩...
透视数据!来玩app 德州 辅... 透视数据!来玩app 德州 辅助(透视)开挂辅助挂(本来有挂)-哔哩哔哩;来玩app 德州 辅助辅助...