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

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

3天內(nèi)不再提示

使用APM32系列產(chǎn)品的經(jīng)驗總結(jié)

RTThread物聯(lián)網(wǎng)操作系統(tǒng) ? 來源:21ic論壇極海半導體專區(qū) ? 作者:21ic論壇極海半導體 ? 2022-07-11 09:48 ? 次閱讀

串口+DMA解決數(shù)據(jù)接收的難題


之前由于項目需要不停地利用串口接收數(shù)據(jù),剛開始的時候采用單字節(jié)中斷的方式接收判斷。但是用來做通信的時候需要不停的產(chǎn)生串口接收中斷,會嚴重影響主程序的運行。后來采用DMA接收的方式,但是一般情況下配置的DMA都是接收指定長度的串口數(shù)據(jù),對于未知長度的串口數(shù)據(jù)接收并不適用。后來在網(wǎng)上發(fā)現(xiàn)了一種方法可以利用串口的 空閑中斷+DMA接收的方法可解決此類問題,特別適用于不需要每個接收字節(jié)都判斷的串口數(shù)據(jù)接收,下面簡單介紹一下。

思路:采用APM32E103的串口1,并配置成空閑中斷模式且使能DMA接收,并同時設(shè)置接收緩沖區(qū)和初始化DMA。當初始化完成之后,外部給MCU發(fā)送數(shù)據(jù)的時候,假設(shè)這幀數(shù)據(jù)長度是100個字節(jié),那么在MCU中接收到一個字節(jié)的時候并不會產(chǎn)生串口中斷,而是DMA在后臺把數(shù)據(jù)全部搬運到你指定的緩沖區(qū)里面,當整幀數(shù)據(jù)發(fā)送完畢之后串口才會產(chǎn)生一次中斷,此時可以利用CurrDataCounterBegin = DMA_ReadDataNumber(DMA1_Channel6);計算出本次的數(shù)據(jù)接受長度,從而進行數(shù)據(jù)處理。

關(guān)鍵代碼分析:
#include "public.h"
#ifndef __USART_H
#define __USART_H
#include "stdio.h"

volatile uint32_t CurrDataCounterBegin = 0;
#define DMA_Rec_Len 256 //定義一個256個字節(jié)的數(shù)據(jù)緩沖區(qū)。

void uartInit(void)
{
//GPIO端口設(shè)置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;

RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_USART1)); //使能USART1,GPIOA時鐘
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1); //使能DMA傳輸
USART_DeInit(USART1);//復位串口1
//USART1_TX PA9
GPIO_InitStructure.pin = GPIO_PIN_9; //PA.9
GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
GPIO_InitStructure.mode = GPIO_MODE_AF_PP; //復用推挽輸出
GPIO_Config(GPIOA, &GPIO_InitStructure); //初始化PA9

//USART1_RXA10
GPIO_InitStructure.pin = GPIO_PIN_10;
GPIO_InitStructure.mode = GPIO_MODE_IN_FLOATING;//浮空輸入
GPIO_Config(GPIOA, &GPIO_InitStructure);//初始化PA10
//USART 初始化設(shè)置
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WORD_LEN_8B;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits = USART_STOP_BIT_1;//一個停止位
USART_InitStructure.USART_Parity = USART_PARITY_NONE;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode = USART_MODE_TX | USART_MODE_RX; //收發(fā)模式

USART_Config(USART1, &USART_InitStructure);

USART_EnableInterrupt(USART1, USART_INT_IDLE);//開啟空閑中斷

USART_EnableDMA(USART1,USART_DMA_RX); //使能串口1 DMA接收

USART_Enable(USART1); //使能串口

// NVIC 配置
NVIC_EnableIRQRequest(DMA1_Channel6_IRQn, 3, 2);


//相應的DMA配置
DMA_Reset(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;//DMA外設(shè)ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf;//DMA內(nèi)存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERAL_SRC;//數(shù)據(jù)傳輸方向,從外設(shè)讀取發(fā)送到內(nèi)存
DMA_InitStructure.DMA_BufferSize = DMA_Rec_Len;//DMA通道的DMA緩存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERAL_INC_DISABLE;//外設(shè)地址寄存器不變
DMA_InitStructure.DMA_MemoryInc = DMA_MEMORY_INC_ENABLE;//內(nèi)存地址寄存器遞增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_WOED;//數(shù)據(jù)寬度為8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORY_DATA_SIZE_WOED; //數(shù)據(jù)寬度為8位
DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;//工作在正常緩存模式
DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; //DMA通道 x擁有中優(yōu)先級
DMA_InitStructure.DMA_M2M = DMA_M2MEN_ENABLE;//DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?br /> DMA_Init(DMA1_Channel6, &DMA_InitStructure);//根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道

DMA_EnableInterrupt(DMA1_Channel6, DMA_INT_TC);
CurrDataCounterBegin = DMA_ReadDataNumber(DMA1_Channel6);

DMA_Enable(DMA1_Channel6);
}

//串口中斷函數(shù)
void USART1_IRQHandler(void) //串口1中斷服務(wù)程序
{

if(USART_ReadStatusFlag(USART1, USART_FLAG_IDLE) != RESET)//接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)
{
USART_RxData(USART1);//讀取數(shù)據(jù) 注意:這句必須要,否則不能夠清除中斷標志位。
Usart1_Rec_Cnt = DMA_Rec_Len-CurrDataCounterBegin(DMA1_Channel6); //算出接本幀數(shù)據(jù)長度

//幀數(shù)據(jù)處理函數(shù)
printf ("The lenght:%d ",Usart1_Rec_Cnt);
printf ("The data: ");
USART_TxData(DMA_Rece_Buf,Usart1_Rec_Cnt);
USART_ClearIntFlag(USART1, USART_FLAG_IDLE); //清除中斷標志
DMA_Enable(DMA1_Channel6); //恢復DMA指針,等待下一次的接收
}

原文標題:APM32芯得 EP.03 | APM32E103串口+DMA解決數(shù)據(jù)接收的困擾

文章出處:【微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:彭靜

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

    關(guān)注

    146

    文章

    17316

    瀏覽量

    352401
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    566

    瀏覽量

    100881
  • 串口數(shù)據(jù)
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    13916

原文標題:APM32芯得 EP.03 | APM32E103串口+DMA解決數(shù)據(jù)接收的困擾

文章出處:【微信號:RTThread,微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    N32G451系列產(chǎn)品簡介

    電子發(fā)燒友網(wǎng)站提供《N32G451系列產(chǎn)品簡介.pdf》資料免費下載
    發(fā)表于 01-22 15:34 ?0次下載
    N32G451<b class='flag-5'>系列產(chǎn)品</b>簡介

    上海貝嶺150V SGT MOSFET系列產(chǎn)品介紹

    上海貝嶺推出150V SGT MOSFET系列產(chǎn)品。貝嶺150V SGT系列產(chǎn)品采用業(yè)界先進工藝,使得器件具有良好的柵極漏電流IGSS性能;采用深溝槽、多層外延襯底以及多重浮空環(huán)終端結(jié)構(gòu),使得器件
    的頭像 發(fā)表于 01-03 10:19 ?277次閱讀
    上海貝嶺150V SGT MOSFET<b class='flag-5'>系列產(chǎn)品</b>介紹

    怎么用Clion開發(fā)APM32

    APM32 官方 SDK 中提供了三種開發(fā)環(huán)境:Keil、IAR 和 Eclipse。不否認這三種環(huán)境的強大,但是在 AI 時代做嵌入式開發(fā),用這三種環(huán)境就顯得有點不夠優(yōu)雅了。本篇文章主要介紹怎么用
    的頭像 發(fā)表于 12-17 09:19 ?1010次閱讀
    怎么用Clion開發(fā)<b class='flag-5'>APM32</b>

    APM32F10xx進入低功耗模式的問題分析

    近日,在學習APM32開發(fā)板關(guān)于PMU模塊的內(nèi)容,看到很多內(nèi)容都是調(diào)用WFI內(nèi)核指令進入低功耗模式,于是自己想嘗試調(diào)用WFE內(nèi)核指令進入低功耗模式,但在APM32F10xx中,我運用按鍵中斷,在中斷
    的頭像 發(fā)表于 10-18 16:13 ?372次閱讀
    <b class='flag-5'>APM</b>32F10xx進入低功耗模式的問題分析

    芯來NA系列產(chǎn)品再獲ISO 26262 ASIL-D產(chǎn)品認證證書

    近日,芯來科技NA300系列產(chǎn)品正式獲得了德國exida頒發(fā)的ISO26262 ASIL-D產(chǎn)品認證證書。
    的頭像 發(fā)表于 07-15 16:11 ?686次閱讀
    芯來NA<b class='flag-5'>系列產(chǎn)品</b>再獲ISO 26262 ASIL-D<b class='flag-5'>產(chǎn)品</b>認證證書

    凱迪正大對電纜安全檢查知識經(jīng)驗總結(jié)分享

    電纜作為電力傳輸?shù)闹匾d體,其安全穩(wěn)定運行直接關(guān)系到整個電力系統(tǒng)的可靠性。因此,電纜的安全檢查至關(guān)重要。下面給大家分享一下武漢凱迪正大電氣多年電纜故障查找總結(jié)經(jīng)驗,我們將圍繞電纜安全檢查的關(guān)鍵點,給大家分享。
    的頭像 發(fā)表于 05-27 11:33 ?438次閱讀
    凱迪正大對電纜安全檢查知識<b class='flag-5'>經(jīng)驗總結(jié)</b>分享

    知行科技iDC系列產(chǎn)品獲得奇瑞歐萌達量產(chǎn)定點

    出海布局再下一城!知行科技iDC系列產(chǎn)品獲得奇瑞歐萌達量產(chǎn)定點
    的頭像 發(fā)表于 05-07 09:39 ?411次閱讀
    知行科技iDC<b class='flag-5'>系列產(chǎn)品</b>獲得奇瑞歐萌達量產(chǎn)定點

    寬電壓時鐘振蕩器系列產(chǎn)品選型指南

    寬電壓時鐘振蕩器系列產(chǎn)品選型指南
    的頭像 發(fā)表于 04-22 14:53 ?612次閱讀
    寬電壓時鐘振蕩器<b class='flag-5'>系列產(chǎn)品</b>選型指南

    奧拓電子SW系列產(chǎn)品斬獲2024年度德國紅點獎

    近日,奧拓電子SW系列產(chǎn)品從來自全球各地的優(yōu)秀作品中脫穎而出,獲得了2024年度德國紅點獎,這是繼3月份CV-MIP系列產(chǎn)品榮獲德國iF設(shè)計大獎之后,公司獲得的又一項重量級國際設(shè)計大獎。
    的頭像 發(fā)表于 04-08 14:09 ?1003次閱讀

    APM32下載了APM專屬的HEX例程后識別不了芯片怎么解決?

    之前焊了一塊,可以識別芯片,下載了APM專屬的HEX例程后反而識別不了了,非常痛苦。ARM內(nèi)核仍然存在,Keil里面也下載不了了……不是板子鎖死的問題
    發(fā)表于 03-28 06:20

    工業(yè)數(shù)顯壓力測量系列產(chǎn)品介紹

    電子發(fā)燒友網(wǎng)站提供《工業(yè)數(shù)顯壓力測量系列產(chǎn)品介紹》資料免費下載
    發(fā)表于 03-11 14:04 ?0次下載

    油田泥漿壓力測量系列產(chǎn)品介紹

    電子發(fā)燒友網(wǎng)站提供《油田泥漿壓力測量系列產(chǎn)品介紹》資料免費下載
    發(fā)表于 03-11 14:01 ?0次下載

    Nexperia發(fā)布全新模擬開關(guān)系列產(chǎn)品

    全球基礎(chǔ)半導體器件領(lǐng)域的領(lǐng)軍企業(yè)Nexperia(安世半導體)最近發(fā)布了全新的專用于監(jiān)測和保護1.8V電子系統(tǒng)的4通道和8通道模擬開關(guān)系列產(chǎn)品。這一創(chuàng)新系列產(chǎn)品的推出,旨在滿足汽車、消費類電子產(chǎn)品及工業(yè)應用等多樣化領(lǐng)域?qū)Ω咝阅苣?/div>
    的頭像 發(fā)表于 03-11 10:08 ?762次閱讀

    AMD推出Spartan UltraScale+ FPGA系列產(chǎn)品

    AMD公司,全球知名的芯片巨頭,近日宣布推出全新的AMD Spartan UltraScale+ FPGA系列產(chǎn)品組合。這一新系列作為AMD成本優(yōu)化型FPGA、自適應SoC產(chǎn)品家族的最新成員,特別針對成本敏感型邊緣應用進行了優(yōu)化
    的頭像 發(fā)表于 03-07 10:15 ?762次閱讀

    HOLTEK新推出HT66R00x A/D OTP MCU系列產(chǎn)品

    Holtek新推出A/D型OTP MCU - HT66R00x系列產(chǎn)品,提供客戶具有高性價比的卓越解決方案,整系列功能涵蓋面廣,可滿足客戶多元化產(chǎn)品需求
    的頭像 發(fā)表于 02-19 14:25 ?1634次閱讀