串口DMA接收:
接收數據的流程:
串口接收DMA在初始化的時候就處于開啟狀態(tài),一直等待數據的到來,在軟件上無需做任何事情,只要在初始化配置的時候設置好配置就可以了。
判斷數據數據接收完成:
這里判斷接收完成是通過串口空閑中斷的方式實現,即當串口數據流停止后,就會產生IDLE中斷。這個中斷里面做如下幾件事:
1. 關閉串口接收DMA通道,2點原因:a.防止后面又有數據接收到,產生干擾。b.便于DMA的重新配置賦值,下面第4點。
2. 置位接收完成標志位
3. 處理接收buffer中數據
4. 重新設置DMA下次要接收的數據字節(jié)數,注意,這里是給DMA寄存器重新設置接收的計數值,這個數量只能大于或者等于可能接收的字節(jié)數,否則當DMA接收計數器遞減到0的時候,又會重載這個計數值,重新循環(huán)遞減計數,所以接收緩沖區(qū)的數據則會被覆蓋丟失。
5. 開啟DMA通道,等待下一次的數據接收,注意,對DMA的相關寄存器配置寫入,如第4條的寫入計數值,必須要在關閉DMA的條件進行,否則操作無效。
說明一下,STM32的IDLE的中斷在串口無數據接收的情況下,是不會一直產生的,產生的條件是這樣的,當清除IDLE標志位后,必須有接收到第一個數據后,才開始觸發(fā),一斷接收的數據斷流,沒有接收到數據,即產生IDLE中斷。IDLE位不會再次被置高直到RXNE位被置起(即又檢測到一次空閑總線)。RXNE接收中斷可以不用開啟,減少進中斷的次數。
void My_UART_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 使能DMA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // 使能時鐘 復用USART
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化 USART_TX 即 GPIOA.9
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化 USART_RX 即 GPIOA.10
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct); //初始化 USART
// USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 開啟 USART 接收緩沖區(qū)非空中斷
// USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 開啟 USART 發(fā)送緩沖區(qū)空中斷
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //開啟 USART1 總線空閑中斷
USART_Cmd(USART1, ENABLE);//使能USART中斷
DMA_DeInit(DMA1_Channel5);
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR); //外設--->內存
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)RxBuffer;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_BufferSize = BufferSize;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_Init(DMA1_Channel5, &DMA_InitStruct);
DMA_Cmd(DMA1_Channel5, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能 USART1接收DMA
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //搶占優(yōu)先級 2位 00 01 10 11
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //響應優(yōu)先級 2位 00 01 10 11
NVIC_Init(&NVIC_InitStruct); //初始化中斷
}
以上代碼如下圖
當MCU通過USART接收外部發(fā)來的數據時,在進行第①②③步的時候,主程序可以不用管,DMA直接將接收到的數據寫入緩存RxBuffer,程序此時也不會進入接收中斷,當數據接收完成之后產生接收空閑中斷,在中斷服務函數中將接收完成標志位置1,計算出接收緩存中的數據長度,清除中斷位,失能DMA防止在處理數據時候接收數據。主程序中檢測到接收完成標志被置1,進入數據處理程序,現將接收完成標志位置0,重新設置DMA下次要接收的數據字節(jié)數,使能DMA進入接收數據狀態(tài)。
void USART1_IRQHandler(void)
{
uint8_t clear = clear; // 用來消除編譯器的“沒有用到”的提醒
uint8_t data = 0;
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
clear = USART1->SR;
clear = USART1->DR;
// RxCounter = BufferSize - DMA1_Channel5->CNDTR;//緩存中的字節(jié)數
RxCounter = BufferSize - DMA_GetCurrDataCounter(DMA1_Channel5);//緩存中的字節(jié)數
// USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
RxStatus = 1; //標記接收到一幀
USART_ClearITPendingBit(USART1, USART_IT_IDLE); // 清除空閑中斷
DMA_Cmd(DMA1_Channel5, DISABLE); // 停止DMA,清除DMA緩存
}
}
int main(void)
{
uint8_t i = 0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 初始化中斷優(yōu)先級分組
My_UART_Init();
while(1)
{
if(RxStatus == 1)
{
RxStatus = 0;
i = 0;
while(RxCounter--)
{
USART_SendData(USART1, RxBuffer[i++]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
}
memset(RxBuffer, 0, i); // 清除緩存
RxCounter = 0;
// DMA1_Channel5->CNDTR = BufferSize;
DMA_SetCurrDataCounter(DMA1_Channel5, BufferSize);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
}
}
此程序可以進行接收不定長的數據幀,不需像RXNE每次接收到一個字節(jié)就進一次中斷。
上一篇:stm32 USART_IT_IDLE中斷 一幀數據
下一篇:stm32F030C8單片機串口利用USART_IT_IDLE接收完整的一幀
推薦閱讀
史海拾趣
創(chuàng)新是Artaflex公司持續(xù)發(fā)展的核心動力。公司不斷投入研發(fā)資金,加強技術創(chuàng)新和新產品開發(fā)。通過不斷推出具有創(chuàng)新性和競爭力的產品,公司不僅滿足了市場的多樣化需求,也贏得了客戶的信任和好評。同時,公司還注重人才培養(yǎng)和團隊建設,為公司的長期發(fā)展奠定了堅實的基礎。
隨著國內市場的逐漸飽和,CTC Coils Ltd公司開始將目光投向海外市場。公司首先在歐洲設立了銷售分支機構,通過參加國際電子展會、與當地企業(yè)建立合作關系等方式,逐步打開了歐洲市場。隨后,公司又進一步拓展到北美和亞洲其他地區(qū),實現了業(yè)務的國際化布局。
C&T始終堅持品質至上的原則,從原材料的采購到產品的生產、測試,每一個環(huán)節(jié)都嚴格把控。這種對品質的執(zhí)著追求,使得C&T的產品在市場上贏得了良好的口碑。許多知名電腦制造商都選擇與C&T合作,將其產品作為首選的半導體解決方案。
面對不斷變化的市場需求和技術趨勢,ADMOS公司始終保持著對創(chuàng)新的熱情和追求。公司投入大量資源用于研發(fā)新的技術和產品,不斷推出具有創(chuàng)新性和競爭力的產品。這些創(chuàng)新成果不僅提升了ADMOS在市場上的競爭力,也為公司的未來發(fā)展指明了方向。
面對不斷變化的市場需求和技術趨勢,ADMOS公司始終保持著對創(chuàng)新的熱情和追求。公司投入大量資源用于研發(fā)新的技術和產品,不斷推出具有創(chuàng)新性和競爭力的產品。這些創(chuàng)新成果不僅提升了ADMOS在市場上的競爭力,也為公司的未來發(fā)展指明了方向。
在電子行業(yè)競爭日益激烈的背景下,ADMOS公司始終堅守質量第一的原則。公司建立了完善的質量管理體系,從原材料采購到產品生產的每一個環(huán)節(jié)都進行嚴格把控。這種對質量的執(zhí)著追求使得ADMOS的產品在市場上獲得了廣泛的認可和信任,也為公司贏得了眾多長期合作伙伴。
共享一下我的論文-uClinux 在EasyARM2200開發(fā)板上的運行 摘 要:EasyARM2200開發(fā)板僅有512KB RAM和2MB FLASH存儲器資源,能否運行uClinux以及如何運行 uClinux,是喜愛這款開發(fā)板的技術人員一個共同的心聲。本文通過分析uClinux的內存管理和內核引導機制,介紹了uClinux2.4針對EasyARM2200開發(fā)板的移植和 ...… 查看全部問答∨ |
請教BiCMOS反相器的理解問題,以前貌似有人問過,但還是沒弄明白 如下圖,當輸入Vi為H,前級反相器的輸出(即T1管的基極)為L,此時T1管就截止了,相當于斷開 同時N3管的柵極也為L,N3也是截止的,N2的柵極是原始輸入信號為H,N2可以導通,但是T2 ...… 查看全部問答∨ |
愛因迪生:咦,又上來一位和色環(huán)電阻長得很像的元件。是誰呢?不過她長得很碩壯。為了再次出錯,我還是先驗證一下是不是電阻再說。 愛因迪生拿了個萬用表在手上,來到舞臺上。 愛因迪生:千萬別告訴我你是什么元件。我要自己猜猜。來來來,讓我量 ...… 查看全部問答∨ |
為了使大家對使用中或者使用過的PLC能有個總結,特征集討論三菱、西門子、歐姆龍最常用的3種PLC的使用心得。我本人用過最多的是三菱的FX、FX1N、FX2N系列PLC,感覺編寫程序容易,初學上手快,組網簡單,故障率低。希望大家也說說自己的工程和維修心 ...… 查看全部問答∨ |
autocorrelation(自相關)function 應該怎么用呢? 各位前輩,我是才剛剛開始接觸DSP(digital sound processing)的學生,現在要用autocorrelation funtion 找出一個periodic signal 的周期,但是實在是不知道autocorrelation function 應該怎么用~~~比方說我得到一個sinusoidal signal(有噪音) ...… 查看全部問答∨ |
|
出一個FPGA的核心板和USB下載線,幾乎全新,到手玩了一個月,就沒有動過了,1月份的時候550從淘寶上買的,現在350包郵,出掉~南京的支持面交, 有興趣的話直接聯(lián)系我 手機:13770305251 手上還有這兩個東西的保修單,是康草科技的 http://auction1.tao ...… 查看全部問答∨ |
|
經過了前期的反復討論,決定使用MSP430G2333這個MCU去做一個新的產品,主要是應用到觸摸,10位AD,另外因需要的IO口也比較多的原因,決定用32個腳的QFN,于是一大早,就興沖沖的跑到華強/賽格去找樣。在來之 ...… 查看全部問答∨ |
AT89C2051單片機設計開發(fā)的ML99V4型傳呼機發(fā)碼電路的功能、原理、編程及應用 AT89C2051單片機設計開發(fā)的ML99V4型傳呼機發(fā)碼電路的功能、原理、編程及應用… 查看全部問答∨ |
設計資源 培訓 開發(fā)板 精華推薦
- 英飛凌微控制器:以全新實惠套件和強大開發(fā)環(huán)境為開發(fā)者提供支持
- iTOP-i.MX6開發(fā)板設備數驅動Menuconfig的用法
- 迅為IMX6ULL開發(fā)板Qt for Android搭建開發(fā)環(huán)境
- 迅為i.MX8M mini開發(fā)板Windots QT系統(tǒng)開發(fā)環(huán)境搭建
- 迅為IMX8MM開發(fā)板Yocto系統(tǒng)使用Gstarwmra(一)
- 迅為IMX8M mini開發(fā)板Linix系統(tǒng)修改默認屏幕
- iTOP-4412開發(fā)板支持4G以上文件系統(tǒng)擴展
- 迅為IMX8MM開發(fā)板Yocto系統(tǒng)設置開機自啟動
- 迅為IMX6Q開發(fā)板 Buildroot文件系統(tǒng)mqtt測試
- 復旦大學在集成電路領域獲關鍵突破!每秒存取25億次,史上最快!
- 星閃強勢入局,會給UWB與藍牙定位帶來哪些沖擊?
- 又兩款旗艦新車搭載星閃車鑰匙!誰在引爆這波汽車連接革命?
- 榜單首發(fā)!域控SerDes處于市場爆發(fā)周期,哪些供應商正在領跑市場
- 英特爾? 具身智能大小腦融合方案發(fā)布:構建具身智能落地新范式
- 車載UWB雷達技術:有哪些優(yōu)勢?
- 嵐圖開啟L3智駕:天元智能架構技術解讀
- 德州儀器如何通過7000多種車規(guī)芯片,引領汽車產業(yè)的創(chuàng)新
- 2025年上海國際車展技術前瞻 – 智駕安全(環(huán)境感知)
- 史上最嚴動力電池國標解讀:爆燃零容忍,倒逼廠家不打嘴炮真研發(fā)