精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

淺析新塘031 串口PDMA通信

Q4MP_gh_c472c21 ? 來源:嵌入式ARM ? 作者:吶咯密密 ? 2021-07-06 17:16 ? 次閱讀

環境搭建這里就跳過了,沒啥用,我還是用KEIL 5 開發,自行下載個PACK包安裝就好了。點此前往新塘官網。搜索自己的MCU型號,打開頁面,在資源中有文檔和軟件。

在文檔中下載數據手冊等文檔,在軟件中下載例程和工具,軟件中最實用的是以下幾個軟件:

從上到下依次是:官方例程庫,Nu_link驅動,外設引腳配置軟件,時鐘配置軟件。

外設引腳配置軟件用于快速配置引腳以及復用,該軟件只能配置引腳及其功能,不能配置外設等功能呢,例如串口的相關配置,這些事實現不了的。

時鐘配置軟件僅用于配置系統時鐘以及各外設時鐘。這兩個軟件支持導出.c代碼??蓮椭普迟N到自己的工程。

這兩個軟件都是非常簡單的,這里就不贅述了。

但是有一個時鐘配置軟件有BUG,以我用的M031SE3AE為例,外部時鐘最大可使用32M,但是軟件中最大只支持24M,希望官方可以修復。

開始代碼

下載官方的例程,固件庫代碼在文件夾:D:M031_Series_BSP_CMSIS_V3.03.000SampleCodeStdDriver,寄存器代碼在D:M031_Series_BSP_CMSIS_V3.03.000SampleCodeRegBased

這里采用固件庫的方式開發,方便快捷。

時鐘初始化:

void SYS_Init(void){

/*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Unlock protected registers */ SYS_UnlockReg();

/* Enable HIRC clock (Internal RC 48MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

/* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

/* Select HCLK clock source as HIRC and HCLK source divider as 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

/* Set both PCLK0 and PCLK1 as HCLK */ CLK-》PCLKDIV = CLK_PCLKDIV_APB0DIV_DIV1 | CLK_PCLKDIV_APB1DIV_DIV1;

/* Select IP clock source */ /* Select UART0 clock source is HIRC */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1)); /* Select UART1 clock source is HIRC */ CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HIRC, CLK_CLKDIV0_UART1(1));

/* Enable UART0 peripheral clock */ CLK_EnableModuleClock(UART0_MODULE); /* Enable UART1 peripheral clock */ CLK_EnableModuleClock(UART1_MODULE); /* Enable PDMA module clock */ CLK_EnableModuleClock(PDMA_MODULE);

/* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */ SystemCoreClockUpdate();

/*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/

/* Set PB multi-function pins for UART0 RXD=PB.12 and TXD=PB.13 */ SYS-》GPB_MFPH = (SYS-》GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) | (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

/* Set PB multi-function pins for UART1 RXD(PB.2) and TXD(PB.3) */ SYS-》GPB_MFPL = (SYS-》GPB_MFPL & ~(SYS_GPB_MFPL_PB2MFP_Msk | SYS_GPB_MFPL_PB3MFP_Msk)) | (SYS_GPB_MFPL_PB2MFP_UART1_RXD | SYS_GPB_MFPL_PB3MFP_UART1_TXD);

/* Lock protected registers */ SYS_LockReg();}

在初始化時鐘之前需要確認自己的外部晶振的頻率,然后在system_M031Series.h文件的第38行修改宏定義。

be35f37e-d9a0-11eb-9e57-12bb97331649.png

在初始化時鐘時會將需要的外設時鐘一起初始化,這里初始化了UART0和UART1的時鐘以及PDMA的時鐘。

初始化UART

由于時鐘已經配置,在初始化UART的配置時會顯得特別簡單。如果你的UART沒有特殊要求,兩行代碼即可完成UART的初始化。

void UART0_Init(){ /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ /* Reset UART0 */ SYS_ResetModule(UART0_RST);

/* Configure UART0 and set UART0 baud rate */ UART_Open(UART0, 115200);}

void UART1_Init(){ /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ /* Reset UART1 */ SYS_ResetModule(UART1_RST);

/* Configure UART1 and set UART1 Baudrate */ UART_Open(UART1, 2500000); /* Enable Interrupt and install the call back function */ NVIC_EnableIRQ(UART13_IRQn); UART_EnableInt(UART1, UART_INTEN_RDAIEN_Msk); }

串口0用于printf的調試。串口1 是我需要與其他串口設備通信接口。除了我在串口1設置了串口接收中斷以外,初始化一個串口僅僅需要兩個函數,非常方便,這里使用的串口默認配置:一個停止位,無校驗位,8位數據,如果需要修改可自行進入函數修改。

在配置串口1的接收中斷時遇到了問題:調用NVIC_EnableIRQ()函數初始化中斷線時,參數我填的是UART1_IRQn,無報錯,編譯可通過,但是測試沒現象,于是進入debug頁面,發現中斷函數并未被編譯。

be81c966-d9a0-11eb-9e57-12bb97331649.png

嘗試了很多方法都不能進行編譯,后來去看UART1_IRQn的定義,發現這個宏定義下面還有一個UART13_IRQn。于是明白過來了,

UART0和UART2共用一個中斷函數UART02_IRQHandler(),UART1和3共用中斷函數UART13_IRQHandler()這里區別于其他家的庫,不能用UART1_IRQn,需要用UART13_IRQn。

beaff2be-d9a0-11eb-9e57-12bb97331649.png

PDMA配置

void PDMA_UART_TxTest(void){ /* UART Tx PDMA channel configuration */ /* Set transfer width (8 bits) and transfer count */ PDMA_SetTransferCnt(PDMA, UART_TX_DMA_CH, PDMA_WIDTH_8, UART_TEST_LENGTH);

/* Set source/destination address and attributes */ PDMA_SetTransferAddr(PDMA, UART_TX_DMA_CH, (uint32_t)SrcArray, PDMA_SAR_INC, (uint32_t)&UART1-》DAT, PDMA_DAR_FIX);

/* Set request source; set basic mode. */ PDMA_SetTransferMode(PDMA, UART_TX_DMA_CH, PDMA_UART1_TX, FALSE, 0);

/* Single request type */ PDMA_SetBurstType(PDMA, UART_TX_DMA_CH, PDMA_REQ_SINGLE, 0);

/* Disable table interrupt */ PDMA_DisableInt(PDMA,UART_TX_DMA_CH, PDMA_INT_TEMPTY );}

這里有幾個需要自行修改的地方,PDMA_SetTransferCnt(PDMA, UART_TX_DMA_CH, PDMA_WIDTH_8, UART_TEST_LENGTH);修改PDMA_WIDTH_8為修改數據寬度,這里默認8位,UART_TEST_LENGTH為發送長度,我這里設置為11個。PDMA_SetTransferAddr(PDMA, UART_TX_DMA_CH, (uint32_t)SrcArray, PDMA_SAR_INC, (uint32_t)&UART1-》DAT, PDMA_DAR_FIX); SrcArray為數組的地址。因為我是發送的DMA,這里配置為內存到外設,如果是接收DMA則做以下設置: PDMA_SetTransferAddr(PDMA, UART_RX_DMA_CH, (uint32_t)&UART1-》DAT, PDMA_SAR_FIX, (uint32_t)DestArray, PDMA_DAR_INC);

配置完后再主函數打開DMA:

SYS_ResetModule(PDMA_RST);

PDMA_Open(PDMA, (1 《《 UART_TX_DMA_CH));

中斷函數配置及啟動DMA

void UART13_IRQHandler(void){ uint8_t res;// uint32_t u32IntSts = UART1-》ISR; PB1 = 0;

res = UART_READ(UART1);//讀UART_DAT寄存器自動清除中斷標志 if(res == 0x1A) { UART_DISABLE_INT(UART1, UART_INTEN_TXPDMAEN_Msk); PDMA_UART_TxTest(); UART_ENABLE_INT(UART1, UART_INTEN_TXPDMAEN_Msk); while (PDMA-》DSCT[UART_TX_DMA_CH].CTL & PDMA_DSCT_CTL_TXCNT_Msk) ; } PB1 = 1;}

在M031中,區別于我之前用過的其他MCU,在進入中斷函數之后,只要讀取串口接收寄存器UART_DAT中的值,便可自動清除中斷標志,并不需要去操作其他寄存器。非常好用。

DMA的啟動和其他的MCU類似,[size=14.6667px]需重新配置傳輸個數,[size=14.6667px]RAM[size=14.6667px]地址等,再調用一次初始化函數就行。然后利用[size=14.6667px]while (PDMA-》DSCT[UART_TX_DMA_CH].CTL & PDMA_DSCT_CTL_TXCNT_Msk) ;判斷數據是否發送完成,實際上就是等待傳輸個數計數器為0。

這里插一句PB1的作用,PBI就是gpio PB1口。初始化就一句話GPIO_SetMode(PB, BIT1, GPIO_MODE_OUTPUT);這里方便示波器觀察時間。在使用庫函數初始化PWM時,因為每一次的啟動都要調用該函數,庫函數的操作很費時間,在觸發串口接收中斷后將PB1拉低,發送完拉高,在示波器觀察到從觸發接收中斷到第一個串口數據發送出去,也就是DMA啟動完成,大約耗時8us,效率低下。于是我將DMA初始化改用寄存器的方式,時間縮小到2.8us,好用!

void PDMA_UART_TxTest(void){ /* UART Tx PDMA channel configuration */ PDMA-》DSCT[UART_TX_DMA_CH].CTL = (UART_TEST_LENGTH - 1) 《《 PDMA_DSCT_CTL_TXCNT_Pos | /* Transfer count */ PDMA_WIDTH_8 | /* Transfer width 8 bits */ PDMA_DAR_FIX | /* Fixed destination address */ PDMA_SAR_INC | /* Increment source address */ PDMA_DSCT_CTL_TBINTDIS_Msk | /* Table interrupt disabled */ PDMA_REQ_SINGLE | /* Single request type */ PDMA_OP_BASIC; /* Basic mode */ PDMA-》DSCT[UART_TX_DMA_CH].SA = (uint32_t)SrcArray; /* Source address */ PDMA-》DSCT[UART_TX_DMA_CH].DA = (uint32_t)&UART1-》DAT; /* Destination address */

/* Request source selection */ PDMA-》REQSEL0_3 = (PDMA-》REQSEL0_3 & (~PDMA_REQSEL0_3_REQSRC1_Msk)) | (PDMA_UART1_TX 《《 PDMA_REQSEL0_3_REQSRC1_Pos);}

END

本文為21ic論壇藍V作者吶咯密密原創撰寫

編輯:jq

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

    關注

    146

    文章

    16993

    瀏覽量

    350318
  • 函數
    +關注

    關注

    3

    文章

    4307

    瀏覽量

    62432
  • 代碼
    +關注

    關注

    30

    文章

    4748

    瀏覽量

    68357
  • BUG
    BUG
    +關注

    關注

    0

    文章

    155

    瀏覽量

    15653
  • pack
    +關注

    關注

    14

    文章

    74

    瀏覽量

    9612

原文標題:缺貨下,又換MCU了:新塘031 串口PDMA通信。

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    串口通信的開發環境配置

    串口通信的開發環境配置涉及多個方面,包括選擇編程語言、安裝必要的庫或驅動程序、配置串口參數等。以下是一個基于Python的串口通信開發環境配
    的頭像 發表于 11-22 09:21 ?170次閱讀

    使用Python進行串口通信的案例

    當然!以下是一個使用Python進行串口通信的簡單示例。這個示例展示了如何配置串口、發送數據以及接收數據。我們將使用 pyserial 庫,這是一個非常流行的用于串口
    的頭像 發表于 11-22 09:11 ?68次閱讀

    串口通信與并口通信的區別

    在計算機和電子設備的數據傳輸領域,串口通信(Serial Communication)和并口通信(Parallel Communication)是兩種基本的通信方式。它們各自有著獨特的
    的頭像 發表于 11-22 09:04 ?209次閱讀

    串口通信協議解析 串口通信應用實例

    串口通信協議解析 串口通信協議是指規定了數據包的內容,內容包含了起始位、主體數據、校驗位及停止位,雙方需要約定一致的數據包格式才能正常收發數據的有關規范。以下是
    的頭像 發表于 11-21 17:03 ?289次閱讀

    為什么通信要使用虛擬串口串口助手?

    串口助手和虛擬串口是什么?串口助手和虛擬串口串口通信中很常見。
    的頭像 發表于 11-15 01:04 ?411次閱讀
    為什么<b class='flag-5'>通信</b>要使用虛擬<b class='flag-5'>串口</b>和<b class='flag-5'>串口</b>助手?

    AFE031電力線通信模擬前端數據表

    電子發燒友網站提供《AFE031電力線通信模擬前端數據表.pdf》資料免費下載
    發表于 06-15 09:52 ?1次下載
    AFE<b class='flag-5'>031</b>電力線<b class='flag-5'>通信</b>模擬前端數據表

    什么是串口通信?它有哪些特點和應用?

    在現代電子通信和計算機領域中,串口通信(Serial Communications)扮演著至關重要的角色。它是一種按位(bit)發送和接收字節的通信方式,能夠實現數據的遠距離傳輸和高效
    的頭像 發表于 05-23 16:23 ?2184次閱讀

    STM32G031k8t6串口發送為什么會進入硬件中斷?

    STM32G031k8t6串口發送進入硬件中斷
    發表于 03-13 07:59

    PDMA接收串口數據時有沒有超時中斷?

    我有一個疑問,在設置PDMA接收串口數據的時候,要設置傳輸數據的長度計數,只有當計數為零,產生DMA傳輸完成中斷。 但是在實際應用中,比如定義傳輸長度為40字節,但對方發過來的數據是70個,在接收
    發表于 01-17 06:14

    串口PDMA,M480的PDMA-集散模式,移植到M467的PDMA需要注意什么嗎?

    請問一下,串口PDMA,M480的PDMA-集散模式,移植到M467的PDMA需要注意什么嗎? 我在M480上面,可以運行。 移植到M467,無法接收到數據。 這個問題,可以指點一
    發表于 01-16 07:37

    M451RG6AE如何用PDMA實現多個串口收發?

    M451RG6AE想用PDMA實現多個串口收發。不論怎樣設置,只有一個串口能工作。哪位老師有經驗希望指點一下,謝謝
    發表于 01-16 06:58

    請問怎么使用SPI的PDMA功能作為主設備接收數據?

    因為時鐘要由主設備送出,如果開啟PDMA功能,想要接收數據,是不是要開啟兩個PDMA通道,一個通道用于內存-->SPI_TX,目的是送出時鐘信號給從設備;另一個通道用于SPI_RX-->內存,真正用于接收數據?
    發表于 01-16 06:53

    QT串口通信的簡單使用

    QT串口通信是上位機和下位機通信常用的通信方式, 也是學習QT必須學會的基礎知識, 這篇就簡單介紹一下QT串口
    的頭像 發表于 01-15 09:27 ?1824次閱讀
    QT<b class='flag-5'>串口</b><b class='flag-5'>通信</b>的簡單使用

    請問PDMA每次傳送都要重新設定嗎?

    Nuvoton 范例 M031_Series_BSP_CMSIS_V3.05.000 SPI_PDMA_LoopTest main() .......已經宣告 PDMA
    發表于 01-15 08:33

    基于CW32W031射頻芯片的AT指令無線串口模塊

    1.模塊介紹 1.1實物圖片 外接天線 模塊正面 1.2模塊概述 該模塊是基于武漢芯源半導體 CW32W031 射頻芯片研發的AT 指令無線串口模塊??墒褂?b class='flag-5'>串口進行數據收發,降低無線應用門檻;可配
    的頭像 發表于 12-28 11:57 ?1524次閱讀
    基于CW32W<b class='flag-5'>031</b>射頻芯片的AT指令無線<b class='flag-5'>串口</b>模塊