<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      GD32F470II的UART+DMA方式的使用筆記

      GD32官方給的DEMO真的是屎一樣的存在,僅展示最基本簡單的應用案例,拿到實際工程中參考性非常低,也就基本的配置過程具有有限的參考性。

      在這種環境下,使用UART+DMA的方式完全是瞎用,感覺能用的函數都給用上。

      UART & DMA配置如下:

       1 /*!
       2     \brief      configure USART DMA
       3     \param[in]  none
       4     \param[out] none
       5     \retval     none
       6 */
       7 void usart_dma_config(void)
       8 {
       9     dma_single_data_parameter_struct dma_init_struct;
      10     /* enable DMA1 */
      11     rcu_periph_clock_enable(RCU_DMA1);
      12     /* deinitialize DMA channel7(USART0 TX) */
      13     dma_deinit(DMA1, DMA_CH7);
      14     dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
      15     dma_init_struct.memory0_addr = (uint32_t)Uart0_tx_buffer;
      16     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
      17     dma_init_struct.number = HITPAD_DATA_SEND_NUM;//9/42
      18     dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
      19     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
      20     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
      21     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
      22     dma_single_data_mode_init(DMA1, DMA_CH7, &dma_init_struct);
      23     dma_channel_subperipheral_select(DMA1, DMA_CH7, DMA_SUBPERI4);
      24     /* configure DMA mode */
      25     dma_circulation_disable(DMA1, DMA_CH7);
      26 
      27     dma_interrupt_enable(DMA1, DMA_CH7, DMA_CHXCTL_FTFIE);
      28     
      29     /* deinitialize DMA channel2(USART0 RX) */
      30     dma_deinit(DMA1, DMA_CH5);
      31     dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
      32     dma_init_struct.memory0_addr = (uint32_t)Uart0_rx_buffer;
      33     dma_single_data_mode_init(DMA1, DMA_CH5, &dma_init_struct);
      34     dma_channel_subperipheral_select(DMA1, DMA_CH5, DMA_SUBPERI4);
      35     /* configure DMA mode */
      36     dma_circulation_disable(DMA1, DMA_CH5);
      37 }
      38 
      39 void Uart0Tx_init_DMA(UINT32 * Addr, UINT32 number)
      40 {
      41     dma_single_data_parameter_struct dma_init_struct;
      42     
      43     dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
      44     dma_init_struct.memory0_addr = (uint32_t)Addr;
      45     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
      46     dma_init_struct.number = (uint32_t)number;
      47     dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
      48     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
      49     dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
      50     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
      51     dma_single_data_mode_init(DMA1, DMA_CH7, &dma_init_struct);
      52     dma_channel_subperipheral_select(DMA1, DMA_CH7, DMA_SUBPERI4);
      53     /* configure DMA mode */
      54     dma_circulation_disable(DMA1, DMA_CH7);
      55 }
      56 
      57 void Usart_init()    //
      58 {//c12-tx/d2-rx
      59 
      60     uint32_t com = USART0;
      61         
      62     rcu_periph_clock_enable(RCU_GPIOA);
      63     rcu_periph_clock_enable(RCU_USART0);
      64 
      65     UINT32 gpio = GPIO_PIN_9 | GPIO_PIN_10;
      66 
      67     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, gpio);        
      68     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gpio);
      69     gpio_af_set(GPIOA, GPIO_AF_7, gpio);
      70 
      71     /* USART interrupt configuration */
      72     nvic_irq_enable(USART0_IRQn, USART0_IRQ_LEVEL, 0);
      73 
      74     usart_deinit(com);
      75     usart_baudrate_set(com,UART0_BAUDRATE);
      76     usart_receive_config(com, USART_RECEIVE_ENABLE);
      77     usart_transmit_config(com, USART_TRANSMIT_ENABLE);
      78     usart_enable(com);
      79 
      80     /*enable transmission complete interrupt*/
      81     usart_interrupt_enable(com, USART_INT_TC);
      82     usart_flag_clear(com,USART_FLAG_TC);
      83 
      84     usart_dma_config();
      85 
      86     /* enable USART0 DMA channel transmission and reception */
      87     /*TX*/
      88     dma_channel_enable(DMA1, DMA_CH7);
      89     /*RX*/
      90     dma_channel_enable(DMA1, DMA_CH5);
      91     
      92     /* USART DMA enable for transmission and reception */
      93     usart_dma_transmit_config(com, USART_DENT_DISABLE);
      94     usart_dma_receive_config(com, USART_DENR_DISABLE);
      95 
      96     HAL_UART0_Config();
      97 
      98 }

      這里僅用到了串口發送,接收沒用,因此發送函數如下:

       1 void Usart0DataSend(UINT8* data, UINT32 len)
       2 {
       3     if(Uart0_Tx_Flag)
       4     {
       5         Uart0_Tx_Flag = FALSE;
       6 
       7         dma_channel_enable(DMA1, DMA_CH7);
       8         
       9         usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
      10     }
      11 
      12 }

      上層應用:

       1 void Uart0TransmitFunc(void)
       2 {
       3     if(Uart0_Tx_Flag) 
       4     {
       5         while(GCommon_BufNotEmptyCheck((WR_RD_BUF *)g_HAL_UART_TxBuf))
       6         {
       7             for(UINT32 i=0; i<HITPAD_DATA_SEND_NUM; i++)
       8             {
       9                 Uart0_tx_buffer[i] = GCommon_RdDataFromBuf((WR_RD_BUF *)g_HAL_UART_TxBuf);
      10             }
      11             
      12             Usart0DataSend(Uart0_tx_buffer, HITPAD_DATA_SEND_NUM);
      13 
      14             break;
      15         }
      16     }
      17 }

      串口中斷:

       1 void USART0_IRQHandler(void)
       2 {
       3 
       4     if(usart_flag_get(USART0,USART_FLAG_TC)!= RESET)
       5     {
       6         usart_flag_clear(USART0,USART_FLAG_TC);//中斷標記清除
       7 
       8         Uart0_Tx_Flag = TRUE;
       9 
      10 //        /*disable TX*/
      11         usart_dma_transmit_config(USART0, USART_DENT_DISABLE);
      12         dma_channel_disable(DMA1, DMA_CH7);         
      13         dma_flag_clear(DMA1, DMA_CH7,DMA_INTF_FTFIF);
      14     }
      15 
      16 }

      原理也很簡單。

      DMA配置成DMA_MEMORY_TO_PERIPH,串口發送的時候開啟下相應的通道開關,DMA會自動搬運配置好的數據量到串口的發送緩沖,串口全部發送完成后觸發中斷。中斷里再做下相應的FLAG清除工作即可。

      坑就坑在上面在開啟發送和中斷里清理工作上有不需要干的事情。

       

      • 在重新給專用于顯示的GD32F470II的其中一個串口增加DMA功能的時候,發現串口運行一段時間后就停止工作了,簡單查看DMA + UART寄存器也看不出來哪里有問題。
      • 通過測試發現停止傳輸的時候執行一下這段話就又正常了
      dma_flag_clear(DMA1, DMA_CH7,DMA_INTF_FTFIF);

       不知道為什么,然后查看手冊

       這就是原因了。在一次開啟DMA傳輸后,此次DMA傳輸發生了FIFO錯誤/總線錯誤/寄存器訪問錯誤,導致傳輸停止,串口未進中斷清理DMA的FTFIFx標志,DMA就無法繼續使用了

      正確的(應該說更精煉)使用配置如下:

       1 1、串口初始化里串口DMA開關要直接打開
       2   usart_dma_transmit_config(com, USART_DENT_ENABLE);
      3 2、發送接口里只需要使能DMA通道即可 4 void Usart0DataSend(UINT8* data, UINT32 len) 5 { 6 if(Uart0_Tx_Flag) 7 { 8 Uart0_Tx_Flag = FALSE; 9 dma_flag_clear(DMA1, DMA_CH7,DMA_INTF_FTFIF); 10 dma_channel_enable(DMA1, DMA_CH7); 11 } 13 } 14 3、串口中斷里僅需清理下DMA通道的發送完成標志 15 void USART0_IRQHandler(void) 16 { 17 if(usart_flag_get(USART0,USART_FLAG_TC)!= RESET) 18 { 19 usart_flag_clear(USART0,USART_FLAG_TC);//中斷標記清除 20 21 Uart0_Tx_Flag = TRUE; 24 } 27 }

       

      這里解釋下為什么這樣改可以

      用戶手冊里DMA 的DMA_CHxCTL寄存器0bit CHEN這樣介紹

       所以,不需要手動禁止DMA通道,在其傳輸完成的時候會自動清0,實際仿真查看也的確如此。

      串口的DMA發送開關也沒必要來回開關,僅控制DMA就夠了。

       

      posted @ 2024-04-10 16:04  xjxcxjx  閱讀(2493)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av乱码一区二区| 确山县| 1区2区3区4区产品不卡码网站| 久99久热免费视频播放| 国产精品久久人人做人人爽| 南开区| 国产精品一码二码三码四码| 日本中文一二区有码在线| 少妇高潮太爽了在线视频| 高清偷拍一区二区三区| 四虎永久在线精品无码视频| 西西人体大胆444WWW| 凸凹人妻人人澡人人添| 亚洲全乱码精品一区二区| 宫西光有码视频中文字幕| 一二三四中文字幕日韩乱码| 99久久国产福利自产拍| 无套内谢极品少妇视频| 无码成a毛片免费| 中文字幕丰满伦子无码ab| 人人澡人摸人人添| 2021亚洲国产精品无码| 亚洲最大天堂在线看视频| 伊人久久大香线蕉成人| 91福利一区福利二区| 高级艳妇交换俱乐部小说| 六十路老熟妇乱子伦视频| 五河县| 国产精品毛片一区视频播| 国内精品久久人妻无码网站| 四虎永久精品免费视频| 国产精品午夜福利导航导| 亚洲三级香港三级久久| 亚洲狠狠婷婷综合久久久| 亚洲国产综合精品2020| 日本边吃奶边摸边做在线视频| 欧美色欧美亚洲高清在线视频| 自拍偷拍视频一区二区三区 | 亚洲一区二区三区小蜜桃| 欧美肥老太wbwbwbb| 亚洲熟女精品一区二区|