RM新时代网站-首页

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

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

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

三種串口接受不定長數(shù)據(jù)方法詳解

電子工程師 ? 作者:工程師a ? 2018-06-03 04:15 ? 次閱讀

方法1:串口接受數(shù)據(jù),定時(shí)器來判斷超時(shí)是否接受數(shù)據(jù)完成。

方法2:DMA接受+IDLE中斷

實(shí)現(xiàn)思路:采用STM32F103的串口1,并配置成空閑中斷IDLE模式且使能DMA接收,并同時(shí)設(shè)置接收緩沖區(qū)和初始化DMA。那么初始化完成之后,當(dāng)外部給單片機(jī)發(fā)送數(shù)據(jù)的時(shí)候,假設(shè)這幀數(shù)據(jù)長度是200個(gè)字節(jié),那么在單片機(jī)接收到一個(gè)字節(jié)的時(shí)候并不會產(chǎn)生串口中斷,而是DMA在后臺把數(shù)據(jù)默默地搬運(yùn)到你指定的緩沖區(qū)里面。當(dāng)整幀數(shù)據(jù)發(fā)送完畢之后串口才會產(chǎn)生一次中斷,此時(shí)可以利用DMA_GetCurrDataCounter();函數(shù)計(jì)算出本次的數(shù)據(jù)接受長度,從而進(jìn)行數(shù)據(jù)處理。

應(yīng)用對象:適用于各種串口相關(guān)的通信協(xié)議,如:MODBUS,PPI ;還有類似于GPS數(shù)據(jù)接收解析,串口WIFI的數(shù)據(jù)接收等,都是很好的應(yīng)用對象。

關(guān)鍵代碼分析:

void uart_init(u32 bound);

void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);

#endif

usart.C

//初始化IO 串口1

//bound:波特率

void uart_init(u32 bound)

{

//GPIO端口設(shè)置

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE); //使能USART1,GPIOA時(shí)鐘

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA傳輸

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2時(shí)鐘

USART_DeInit(USART1); //復(fù)位串口1

//USART1_TX PA.9

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出

GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9

//USART1_RX PA.10

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入

GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10

//Usart1 NVIC 配置

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級3

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級3

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器

//USART 初始化設(shè)置

USART_InitStructure.USART_BaudRate = bound;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位數(shù)據(jù)格式

USART_InitStructure.USART_StopBits = USART_StopBits_1;//一個(gè)停止位

USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗(yàn)位

USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式

USART_Init(USART1, &USART_InitStructure); //初始化串口

USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//開啟空閑中斷

USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口1 DMA接收

USART_Cmd(USART1, ENABLE); //使能串口

//相應(yīng)的DMA配置

DMA_DeInit(DMA1_Channel5); //將DMA的通道5寄存器重設(shè)為缺省值 串口1對應(yīng)的是DMA通道5

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA外設(shè)usart基地址

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf; //DMA內(nèi)存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //數(shù)據(jù)傳輸方向,從外設(shè)讀取發(fā)送到內(nèi)存

DMA_InitStructure.DMA_BufferSize = DMA_Rec_Len; //DMA通道的DMA緩存的大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)地址寄存器不變

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存地址寄存器遞增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //數(shù)據(jù)寬度為8位

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數(shù)據(jù)寬度為8位

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常緩存模式

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x擁有中優(yōu)先級

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x沒有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏?/p>

DMA_Init(DMA1_Channel5, &DMA_InitStructure); //根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMA的通道

DMA_Cmd(DMA1_Channel5, ENABLE); //正式驅(qū)動DMA傳輸

}

//重新恢復(fù)DMA指針

void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)

{

DMA_Cmd(DMA_CHx, DISABLE ); //關(guān)閉USART1 TX DMA1所指示的通道

DMA_SetCurrDataCounter(DMA_CHx,DMA_Rec_Len);//DMA通道的DMA緩存的大小

DMA_Cmd(DMA_CHx, ENABLE); //打開USART1 TX DMA1所指示的通道

}

//發(fā)送len個(gè)字節(jié)

//buf:發(fā)送區(qū)首地址

//len:發(fā)送的字節(jié)數(shù)

void Usart1_Send(u8 *buf,u8 len)

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

    關(guān)注

    14

    文章

    1551

    瀏覽量

    76421
  • STM32F103
    +關(guān)注

    關(guān)注

    33

    文章

    477

    瀏覽量

    63600
收藏 人收藏

    評論

    相關(guān)推薦

    FreeRTOS串口DMA收發(fā)不定長數(shù)據(jù)

    FreeRTOS例程,介紹串口DMA收發(fā)不定長數(shù)據(jù)
    的頭像 發(fā)表于 09-26 09:08 ?4615次閱讀
    FreeRTOS<b class='flag-5'>串口</b>DMA收發(fā)<b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>

    FreeRTOS串口中斷接收不定長數(shù)據(jù)與二值信號量的使用

    FreeRTOS例程,使用串口中斷接收不定長數(shù)據(jù),以及二值信號量的使用
    的頭像 發(fā)表于 09-26 09:02 ?4167次閱讀
    FreeRTOS<b class='flag-5'>串口</b>中斷接收<b class='flag-5'>不定長</b>的<b class='flag-5'>數(shù)據(jù)</b>與二值信號量的使用

    不定長數(shù)據(jù)接收的原理是什么?怎么實(shí)現(xiàn)串口數(shù)據(jù)不定長接收?

    不定長數(shù)據(jù)接收的原理是什么?怎么實(shí)現(xiàn)串口數(shù)據(jù)不定長接收?
    發(fā)表于 11-16 08:11

    有什么方法可以實(shí)現(xiàn)stm32串口接受不定長數(shù)據(jù)

    有什么方法可以實(shí)現(xiàn)stm32串口接受不定長數(shù)據(jù)呢?有哪幾種方法?
    發(fā)表于 12-08 06:59

    STM32串口接收不定長數(shù)據(jù)的實(shí)現(xiàn)方法

    STM32串口接收不定長數(shù)據(jù)的實(shí)現(xiàn)方法
    發(fā)表于 12-09 06:17

    如何用stm32串口接受Arduino發(fā)送的一個(gè)不定長數(shù)據(jù)

    如何用stm32串口接受Arduino發(fā)送的一個(gè)不定長數(shù)據(jù)呢?如何對其進(jìn)行解析呢?
    發(fā)表于 12-13 06:00

    HAL庫下串口接收不定長數(shù)據(jù)方法

    STM32單片機(jī)HAL庫下串口接收不定長數(shù)據(jù)HAL庫下的串口接收不定長數(shù)據(jù)CubeMX配置過程代
    發(fā)表于 01-19 06:55

    STM32串口接收不定長數(shù)據(jù)的程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STM32串口接收不定長數(shù)據(jù)的程序免費(fèi)下載。
    發(fā)表于 08-26 08:00 ?62次下載
    STM32<b class='flag-5'>串口</b>接收<b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>的程序免費(fèi)下載

    stm32 串口接收不定長度數(shù)據(jù)及黏包處理 + 串口DMA接收

    1.不定長度數(shù)據(jù) 為什么會存在串口接收不定長度數(shù)據(jù)呢?首先,在通信雙方進(jìn)行數(shù)據(jù)傳輸?shù)臅r(shí)候,由于不同的設(shè)備在實(shí)現(xiàn)控制,數(shù)據(jù)采樣時(shí),發(fā)送的
    發(fā)表于 12-23 19:09 ?27次下載
    stm32 <b class='flag-5'>串口</b>接收<b class='flag-5'>不定長度數(shù)據(jù)</b>及黏包處理 + <b class='flag-5'>串口</b>DMA接收

    STM32CUBE MX串口DMA+中斷不定長接收詳解

    串口DMA+中斷不定長接收詳解stm32cube mx作為ST官方生成固件極大的幫助了我們,不再為移植底層寄存器而浪費(fèi)太多時(shí)間,但是在提高效率的同時(shí),HAL庫中還有一些莫名其妙的坑,需要我們自行解決
    發(fā)表于 12-24 18:48 ?6次下載
    STM32CUBE MX<b class='flag-5'>串口</b>DMA+中斷<b class='flag-5'>不定長</b>接收<b class='flag-5'>詳解</b>

    STM32 DMA串口接收不定長數(shù)據(jù)

    STM32 DMA串口接收不定長數(shù)據(jù)
    發(fā)表于 12-24 18:50 ?40次下載
    STM32  DMA<b class='flag-5'>串口</b>接收<b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>

    STM32之串口DMA接收不定長數(shù)據(jù)

    目錄STM32之串口DMA接收不定長數(shù)據(jù)引言DMA簡介什么是DMA在STM32的DMA資源DMA接收數(shù)據(jù)判斷數(shù)據(jù)接收完成接收完
    發(fā)表于 12-24 19:03 ?30次下載
    STM32之<b class='flag-5'>串口</b>DMA接收<b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>

    STM32CubeMX之串口接收不定長數(shù)據(jù)

    基本串口通信通常只能接收到定長數(shù)據(jù),無法穩(wěn)定接收不定長數(shù)據(jù),本章介紹利用STM32單片機(jī)的IDLE空閑中斷,接收
    的頭像 發(fā)表于 05-11 09:59 ?3368次閱讀
    STM32CubeMX之<b class='flag-5'>串口</b>接收<b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>

    三種方法實(shí)現(xiàn)串口接收不定長度的數(shù)據(jù)

    下面三種方式都親測可用,實(shí)際使用時(shí)應(yīng)采用第三種方法,更有效率。
    的頭像 發(fā)表于 09-14 16:16 ?1.1w次閱讀
    <b class='flag-5'>三種方法</b>實(shí)現(xiàn)<b class='flag-5'>串口</b>接收<b class='flag-5'>不定長</b>度的<b class='flag-5'>數(shù)據(jù)</b>

    【代碼分享】基于樂鑫ESP32的串口不定長數(shù)據(jù)接收方法

    【代碼分享】基于樂鑫ESP32的串口不定長數(shù)據(jù)接收方法
    的頭像 發(fā)表于 11-15 01:02 ?388次閱讀
    【代碼分享】基于樂鑫ESP32的<b class='flag-5'>串口</b><b class='flag-5'>不定長</b><b class='flag-5'>數(shù)據(jù)</b>接收<b class='flag-5'>方法</b>
    RM新时代网站-首页