在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

GD32F303固件庫開發(9)----USART通過DMA收發

嵌入式單片機MCU開發 ? 來源:嵌入式單片機MCU開發 ? 作者:嵌入式單片機MC ? 2022-11-29 16:23 ? 次閱讀

概述

本章主要配置printf進行打印。 查閱手冊可以得知,PA9、PA10為串口0的輸出和輸入口。需要GD樣片的可以加群申請:615061293。

在這里插入圖片描述

硬件準備

這里準備了1塊開發板進行驗證,分別是GD32303C_START開發板。

在這里插入圖片描述

DMA

DMA 控制器提供了一種硬件的方式在外設和存儲器之間或者存儲器和存儲器之間傳輸數據,而無需 CPU 的介入,從而使 CPU 可以專注在處理其他系統功能上。DMA 控制器有 12 個通道(DMA0 有 7 個通道,DMA1 有 5 個通道)。每個通道都是專門用來處理一個或多個外設的存儲器訪問請求的。DMA 控制器內部實現了一個仲裁器,用來仲裁多個 DMA 請求的優先級。 DMA 控制器和 Cortex?-M4 內核共享系統總線。當 DMA 和 CPU 訪問同樣的地址空間時,DMA 訪問可能會阻擋 CPU 訪問系統總線幾個總線周期。總線矩陣中實現了循環仲裁算法來分配 DMA 與 CPU 的訪問權,它可以確保 CPU 得到至少一半的系統總線帶寬。 主要特性:

  1. 傳輸數據長度可編程配置,最大到 65536;
  2. 12 個通道,并且每個通道都可配置(DMA0 有 7 個通道,DMA1 有 5 個通道);
  3. AHB 和 APB 外設,片上閃存和 SRAM 都可以作為訪問的源端和目的端;
  4. 每個通道連接固定的硬件 DMA 請求;
  5. 支持軟件優先級(低、中、高、極高)和硬件優先級(通道號越低,優先級越高);
  6. 存儲器和外設的數據傳輸寬度可配置:字節,半字,字;
  7. 存儲器和外設的數據傳輸支持固定尋址和增量式尋址;
  8. 支持循環傳輸模式;
  9. 支持外設到存儲器,存儲器到外設,存儲器到存儲器的數據傳輸;
  10. 每個通道有 3 種類型的事件標志和獨立的中斷;
  11. 支持中斷的使能和清除。

在這里插入圖片描述

DMA0對應通道。
在這里插入圖片描述

DMA1對應通道。

在這里插入圖片描述

keil配置

microlib 進行了高度優化以使代碼變得很小。 它的功能比缺省 C 庫少,并且根本不具備某些 ISO C 特性。 某些庫函數的運行速度也比較慢,如果要使用printf(),必須開啟。

在這里插入圖片描述

定義發送數據

#define ARRAYNUM(arr_nanme)      (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
uint8_t txbuffer1[] = "

USART DMA transmit example

";

使能串口

/* 使能GPI0A,用PA9、PA10為串口 */
    rcu_periph_clock_enable(RCU_GPIOA);

    /*使能串口0的時鐘 */
    rcu_periph_clock_enable(RCU_USART0);

    /*配置USARTx_Tx(PA9)為復用推挽輸出*/
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

    /*配置USARTx_RxPA9)為浮空輸入 */
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    /* USART 配置 */
    usart_deinit(USART0);//重置串口0
    usart_baudrate_set(USART0, 115200U);//設置串口0的波特率為115200
    usart_word_length_set(USART0, USART_WL_8BIT);          // 幀數據字長
        usart_stop_bit_set(USART0, USART_STB_1BIT);               // 停止位1位
    usart_parity_config(USART0, USART_PM_NONE);           // 無奇偶校驗位
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);//使能接收器
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//使能發送器
    usart_enable(USART0);//使能USART

串口重定向

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}

串口重定向后就可以使用printf進行打印。

發送DMA初始化

在DMA初始化的時候,可以將需要發送的數據填充在memory_addr中,注意需要填上長度number。

/*DMA初始化*/
    dma_parameter_struct dma_init_struct;
    // 時鐘開啟
    rcu_periph_clock_enable(RCU_DMA0);
        dma_deinit(DMA0, DMA_CH3);//dma寄存器初始化
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;//傳輸模式,存儲到外設(發送)
    dma_init_struct.memory_addr = (uint32_t)txbuffer1;//dma內存地址
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //內存地址增量模式
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;//dma外設寬度8位
    dma_init_struct.number = ARRAYNUM(txbuffer1)-1; //長度
    dma_init_struct.periph_addr =(uint32_t)(&USART_DATA(USART0));//外設基地址( (uint32_t)USART_DATA(USART0) )
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;//外設地址增量禁用
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_HIGH; //優先級高
    dma_init(DMA0, DMA_CH3 , &dma_init_struct);

    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH3);//循環模式禁用
    dma_memory_to_memory_disable(DMA0, DMA_CH3);//通道3   USART0_TX

使能DMA發送

開啟DMA0_3通道,這個通道位串口0的TX。

/* enable USART0 DMA channel transmission and reception */
    dma_channel_enable(DMA0, DMA_CH3);
    /* USART DMA enable for transmission and reception */
    usart_dma_transmit_config(USART0, USART_DENT_ENABLE);    //發送 

    /* wait until USART0 TX DMA0 channel transfer complete */
    while(RESET == dma_flag_get(DMA0, DMA_CH3, DMA_INTF_FTFIF)){
    }

dma_flag_get()函數說明

dma_flag_get()函數功能是獲取DMAx通道y標志位狀態。 主要的輸入參數有4個。

在這里插入圖片描述

在GD303固件庫中,使用DMA_INTF_FTFIF和DMA_FLAG_FTF是一樣的。

在這里插入圖片描述

DMA發送測試代碼

while(1)
{

    uint8_t txbuffer22[] = "123456";
    dma_channel_disable(DMA0, DMA_CH3);//使能DMA0_CH3
    dma_flag_clear(DMA0, DMA_CH3, DMA_FLAG_FTF);//清除DMA通道傳輸完成標志
    dma_memory_address_config(DMA0, DMA_CH3,  (uint32_t)txbuffer22);//配置存儲器基地址
    dma_transfer_number_config(DMA0, DMA_CH3,  ARRAYNUM(txbuffer22)-1);
    dma_channel_enable(DMA0, DMA_CH3);
    /* wait until USART0 TX DMA0 channel transfer complete */
    while(RESET == dma_flag_get(DMA0, DMA_CH3, DMA_INTF_FTFIF)){
    }
    delay_1ms(1000);


}

DMA發送測試結果

在這里插入圖片描述

DMA循環發送

修改代碼。

dma_circulation_disable(DMA0, DMA_CH3);

修改為。

dma_circulation_enable(DMA0, DMA_CH3);

結果如下。

在這里插入圖片描述

定義接收數組

/* DMA接收緩沖區 */
uint8_t dma_buffer[10];

/* 待處理數據個數:大于1為有數據待處理,0為沒有數據待處理*/
uint32_t USART_RX_NUM = 0;

接收DMA初始化

在DMA初始化的時候,可以將需要接收的數據填充在memory_addr中,注意需要填上長度number。

/* USART0 DMA 接收配置*/
    dma_deinit(DMA0, DMA_CH4);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;        /* 外設到內存 */
    dma_init_struct.memory_addr = (uint32_t)dma_buffer;            /* 設置內存接收基地址 */
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;    /* 內存地址遞增 */
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;        /* 8位內存數據 */
    dma_init_struct.number = sizeof(dma_buffer);
    dma_init_struct.periph_addr = ((uint32_t)0x40013804);        /* 外設基地址,USART數據寄存器地址 */
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;    /* 外設地址不遞增 */
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;    /* 8位外設數據 */
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;            /* 最高DMA通道優先級 */
    dma_init(DMA0, DMA_CH4, &dma_init_struct);                     /* 按照結構體的配置初始化DMA */  


    dma_circulation_disable(DMA0, DMA_CH4);            /* 關閉DMA循環模式 */
    dma_memory_to_memory_disable(DMA0, DMA_CH4);    /* DMA內存到內存模式不開啟 */
        dma_channel_enable(DMA0, DMA_CH4);                /* 使能DMA傳輸 */

        usart_dma_receive_config(USART0, USART_DENR_ENABLE);    /* USART0 DMA接收模式開啟 */

使能串口空閑中斷

當接收完數據之后,會進入空閑中斷。

nvic_irq_enable(USART0_IRQn, 0, 0);        /* USART中斷設置,搶占優先級0,子優先級0 */
    usart_interrupt_enable(USART0, USART_INT_IDLE);            /* 使能USART0空閑中斷 */

USART0_IRQHandler()函數

定義串口的中斷服務函數,當DMA接收完畢會進入。

/* 串口0中斷服務程序 */
void USART0_IRQHandler(void)    
{
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) //空閑中斷
    {
        usart_interrupt_flag_clear(USART0,USART_INT_FLAG_IDLE);    /* 清除空閑中斷標志位 */
        usart_data_receive(USART0);                                /* 清除接收完成標志位 */
        dma_channel_disable(DMA0, DMA_CH4);                        /* 關閉DMA傳輸 */
        USART_RX_NUM = sizeof(dma_buffer) - dma_transfer_number_get(DMA0,DMA_CH4);
        printf("RECV %d date:%s
", USART_RX_NUM, dma_buffer);
        memset(&dma_buffer ,'',sizeof(dma_buffer));        
        /* 重新設置DMA傳輸 */
        dma_memory_address_config(DMA0,DMA_CH4,(uint32_t)dma_buffer);
        dma_transfer_number_config(DMA0,DMA_CH4,sizeof(dma_buffer));
        dma_channel_enable(DMA0, DMA_CH4);        /* 開啟DMA傳輸 */
    }
}

DMA接收測試結果

在這里插入圖片描述

由于不是循環接收,當接收長度超過數組的長度,就會照成數據混亂。 解決辦法可以增加接受數組的長度或者設用循環接收,但是循環接收會覆蓋之前接收到的數據。

DMA循環接收

修改代碼。

dma_circulation_disable(DMA0, DMA_CH4);

修改為

dma_circulation_enable(DMA0, DMA_CH4);

結果如下。

在這里插入圖片描述

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 串口
    +關注

    關注

    14

    文章

    1586

    瀏覽量

    78928
  • dma
    dma
    +關注

    關注

    3

    文章

    573

    瀏覽量

    102404
  • USART
    +關注

    關注

    1

    文章

    200

    瀏覽量

    31665
  • 固件庫
    +關注

    關注

    2

    文章

    97

    瀏覽量

    15210
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    STM32CUBEMX開發GD32F303(8)----USART收發配置

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進行開發,同時通過GD32303C_START
    的頭像 發表于 11-29 10:40 ?3704次閱讀
    STM32CUBEMX<b class='flag-5'>開發</b><b class='flag-5'>GD32F303</b>(8)----<b class='flag-5'>USART</b><b class='flag-5'>收發</b>配置

    STM32CUBEMX開發GD32F3039)----USART通過DMA收發

    概述 本章STM32CUBEMX配置STM32F103,并且在GD32F303中進行開發,同時通過GD32303C_START
    的頭像 發表于 11-29 11:15 ?2605次閱讀
    STM32CUBEMX<b class='flag-5'>開發</b><b class='flag-5'>GD32F303</b>(<b class='flag-5'>9</b>)----<b class='flag-5'>USART</b><b class='flag-5'>通過</b><b class='flag-5'>DMA</b><b class='flag-5'>收發</b>

    GD32F303固件開發(14)----IIC之配置OLED

    本章配置GD32F303使用IIC進行驅動SSD1306的12864OLED。
    的頭像 發表于 07-26 08:55 ?4517次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(14)----IIC之配置OLED

    GD32F303】星空派介紹

    GD32官方資料的基礎上,提供GD32F303的庫函數開發資料、例程講解、視頻課程等。同時還提供RT-Thread相關的驅動開發、應用開發
    發表于 09-11 17:55

    【星空派GD32F303開發板試用體驗】開箱+環境搭建

    完全,APM32F0xx_SDK解包,到星空派GD32F303開發板\03 例程\Project\04_USART_printf\MDK-ARM目錄打開
    發表于 11-02 15:36

    GD32F30x系列固件

    GD32F30x系列固件包含GD32F303GD32F305、GD32F307三個系列的最新
    發表于 08-21 09:00 ?166次下載

    GD32F303固件開發(1)----前期準備與燒錄

    在這使用STM32CUBEMX進行配置STM32F103,移植到兆易創新GD32F303,然后進行測試。需要樣片的可以加Qun申請:615061293。
    的頭像 發表于 11-23 11:15 ?3548次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(1)----前期準備與燒錄

    GD32F303固件開發(3)----使用固件點亮LED

    概述 在GD的官網中有許多的DEMO文件,可以使用開發板的案例或者對應的MCU標準固件。需要樣片的可以加群申請:6_15061293。 下圖是GD
    的頭像 發表于 11-23 17:36 ?3541次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(3)----使用<b class='flag-5'>固件</b><b class='flag-5'>庫</b>點亮LED

    GD32F303固件開發(5)----GPIO輸出模式,速率測試、開漏和輸出說明

    以STM32CUBEMX創建STM32F103工程,同時移植在GD32F303中,同時通過GD32303C_START開發板內進行驗證。
    的頭像 發表于 11-25 15:32 ?3654次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(5)----GPIO輸出模式,速率測試、開漏和輸出說明

    STM32CUBEMX開發GD32F303(11)----ADC在DMA模式下掃描多個通道

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進行開發,同時通過GD32303C_START
    的頭像 發表于 11-30 10:59 ?3213次閱讀
    STM32CUBEMX<b class='flag-5'>開發</b><b class='flag-5'>GD32F303</b>(11)----ADC在<b class='flag-5'>DMA</b>模式下掃描多個通道

    GD32F303固件開發(12)----輸出PWM及修改PWM頻率與占空比

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進行開發,同時通過開發板內進行驗證。 本章主要配置定時器輸出PWM
    的頭像 發表于 11-30 15:36 ?1.1w次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(12)----輸出PWM及修改PWM頻率與占空比

    STM32CUBEMX開發GD32F303(14)----IIC之配置OLED

    本章STM32CUBEMX配置STM32F103,并且在GD32F303中進行開發,同時通過開發板內進行驗證。
    的頭像 發表于 07-26 13:52 ?2642次閱讀
    STM32CUBEMX<b class='flag-5'>開發</b><b class='flag-5'>GD32F303</b>(14)----IIC之配置OLED

    GD32F303固件開發(15)----外部中斷EXTI

    本章配置GD32F303使用EXTI進行驅動LED。
    的頭像 發表于 07-26 15:56 ?2139次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>(15)----外部中斷EXTI

    GD32F303固件開發

    的可以加群申請:615061293 。 GD32F303固件開發(1)----前期準備與燒錄 使用GDLINK、jlink、串口下載程序到GD
    的頭像 發表于 07-27 09:27 ?1657次閱讀
    <b class='flag-5'>GD32F303</b><b class='flag-5'>固件</b><b class='flag-5'>庫</b><b class='flag-5'>開發</b>

    GD32F303紅楓派開發板使用手冊】第十六講 USART-DMA串口收發實驗

    在前面ADC章節中,我們介紹了DMA的工作原理,這里就不多做介紹。從GD32F303用戶手冊中可以查到,各串口的TX和RX分別對應DMA的不同通道,比如USART0的TX對應
    的頭像 發表于 06-15 09:54 ?1800次閱讀
    【<b class='flag-5'>GD32F303</b>紅楓派<b class='flag-5'>開發</b>板使用手冊】第十六講 <b class='flag-5'>USART-DMA</b>串口<b class='flag-5'>收發</b>實驗
    主站蜘蛛池模板: 欧美日韩一区二区视频图片 | 72种姿势欧美久久久久大黄蕉 | 午夜影网 | 精品四虎免费观看国产高清午夜 | 四虎在线最新永久免费 | 日本免费人成黄页网观看视频 | 四虎tv在线观看884aa | 网友偷自拍原创区 | 中文字幕成人乱码在线电影 | 2020夜夜操| 色噜噜人体337p人体 | 爱啪网站 | 美女张开腿露出尿口让男人桶 | 国产午夜精品福利久久 | 视频h在线观看 | 在线视频免费观看 | 激情五月婷婷网 | 欧美久操 | 午夜影视啪啪免费体验区入口 | 免费人成网站 | 色五月丁香五月综合五月 | 18免费视频 | 月夜免费观看高清在线完整 | 在线视频观看一区 | 深夜免费在线视频 | 亚洲一区二区三区电影 | 人人射人人草 | 国产亚洲papapa| 色综合天天综一个色天天综合网 | 精品视频在线视频 | 深爱五月激情五月 | 国产亚洲精品久久久极品美女 | 日本免费一级 | 欧美性视频一区二区三区 | 精品久久久久久中文字幕欧美 | 日本爱爱片 | 免费看国产片 | 全部免费特黄特色大片农村 | 狠狠色丁香久久综合五月 | l欧美18一19sex性 | 成人午夜免费视频毛片 |