娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

STM32串口接收不定長(zhǎng)數(shù)據(jù):采用標(biāo)志位(比如0X0D,0X0A)結(jié)束法

發(fā)布者:AngelicGrace最新更新時(shí)間:2024-06-14 來(lái)源: elecfans關(guān)鍵字:STM32  串口接收  不定長(zhǎng)數(shù)據(jù)  標(biāo)志位 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

缺點(diǎn):有些情況下會(huì)導(dǎo)致數(shù)據(jù)丟失(可能返回?cái)?shù)據(jù)中0x0d、0a本身為有效數(shù)據(jù))

適用:約定協(xié)議的數(shù)據(jù)幀(發(fā)送數(shù)據(jù)的設(shè)備必須以相應(yīng)的約定字節(jié)作為一次數(shù)據(jù)結(jié)束)


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

{

u8 Res; //定義Res,用于Res =USART_ReceiveData(USART1);中存儲(chǔ)串口1發(fā)送的數(shù)據(jù)(這里的數(shù)據(jù)按位發(fā)送)

#if SYSTEM_SUPPORT_OS  //如果SYSTEM_SUPPORT_OS為真,則需要支持OS

OSIntEnter();    

#endif

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)

{

Res =USART_ReceiveData(USART1); //讀取接收到的數(shù)據(jù)

if((USART_RX_STA&0x8000)==0)//接收未完成    1000 0000 0000 0000

//判斷USART_RX_STA的第一位是否為0,這時(shí)因?yàn)閁SART_RX_STA的初始值為0,所以我們進(jìn)入if(USART_RX_STA&0x4000)。

{

if(USART_RX_STA&0x4000)//接收到了0x0d 0100 0000 0000 0000

//判斷USART_RX_STA的第二位是否為1,所以我們進(jìn)入else //還沒(méi)收到0X0D。

{

if(Res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開(kāi)始

else USART_RX_STA|=0x8000; //接收完成了 

}

else //還沒(méi)收到0X0D

{

if(Res==0x0d)USART_RX_STA|=0x4000;//再次判斷這次接收到的是不是0x0d,判斷了Res是否0x0d, 即Res是否為回車,這里如果串口有輸入數(shù)據(jù)的話明顯可以判斷的,所以我們進(jìn)入下面的else.

else

{

USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;  // 0011 1111 1111 1111

USART_RX_STA++;

if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開(kāi)始接收   

}  

}

}     

     } 

#if SYSTEM_SUPPORT_OS

OSIntExit();   

#endif

}

OSIntEnter()和OSIntExit()兩者必須成對(duì)出現(xiàn)。

進(jìn)入中斷時(shí)調(diào)用OSIntEnter(),退出中斷時(shí)調(diào)用OSIntExit()。

OSIntEnter 是進(jìn)?中斷服務(wù)函數(shù),?來(lái)記錄中斷嵌套層數(shù)(OSIntNesting增加 1);

OSIntEnter()應(yīng)該在中斷關(guān)閉后調(diào)用,所以函數(shù)里面沒(méi)有使用OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL(),如此在調(diào)用OSIntEnter()前需關(guān)閉中斷。

OSIntExit():所有中斷結(jié)束后進(jìn)行任務(wù)調(diào)度,使系統(tǒng)更加實(shí)時(shí)。

OSIntExit 是退出中斷服務(wù)函數(shù),該函數(shù)可能觸發(fā)?次任務(wù)切換(當(dāng) OSIntNesting==0&&調(diào)度器未上鎖&&就緒表最?優(yōu)先級(jí)任務(wù) != 被中斷的任務(wù)優(yōu)先級(jí)時(shí)),否則繼續(xù)返回原來(lái)的任務(wù)執(zhí)?代碼(如果 OSIntNesting 不為 0,則減 1)。

OS_Sched():uCOS進(jìn)行任務(wù)調(diào)度,不在中斷調(diào)用。

OSIntNesting:統(tǒng)計(jì)中斷嵌套數(shù),最多255。在OSIntExit()和OS_Sched()中都有判別。

OS_ENTER_CRITICAL():保存中斷狀態(tài),關(guān)中斷。uCOS將無(wú)法再執(zhí)行任務(wù)調(diào)度,硬件中斷也被屏蔽。



void  OSIntEnter (void)


{


if (OSRunning == OS_TRUE) {


if (OSIntNesting < 255u) {


OSIntNesting++;                      /* Increment ISR nesting level                        */


}


}


}


這個(gè)函數(shù)的作用是對(duì)全局變量OSIntNesting增1,OSIntNesting為中斷嵌套深度。


void  OSIntExit (void)


{


#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */


OS_CPU_SR  cpu_sr = 0u;


#endif


if (OSRunning == OS_TRUE) {


OS_ENTER_CRITICAL();


if (OSIntNesting > 0u) {                           /* Prevent OSIntNesting from wrapping       */


OSIntNesting--;


}


if (OSIntNesting == 0u) {                          /* Reschedule only if all ISRs complete ... */


if (OSLockNesting == 0u) {                     /* ... and not locked.                      */


OS_SchedNew();


OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];


if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */


#if OS_TASK_PROFILE_EN > 0u


OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */


#endif


OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */


OSIntCtxSw();                          /* Perform interrupt level ctx switch       */


}


}


}


OS_EXIT_CRITICAL();


}


}


函數(shù)的前面部分對(duì)OSIntNesting減1,剛好與OSIntEnter() 相對(duì)應(yīng);后面部分則進(jìn)行任務(wù)調(diào)度。

總結(jié):任何中斷服務(wù)函數(shù),我們都應(yīng)該加上 OSIntEnter 和 OSIntExit 函數(shù),UCOSII 是?個(gè)可剝奪型的內(nèi)核,中斷服務(wù)?程序運(yùn)?之后,系統(tǒng)會(huì)根據(jù)情況進(jìn)??次任務(wù)調(diào)度去運(yùn)?優(yōu)先級(jí)別最?的就緒任務(wù),?并不?定接著運(yùn)?被中斷的任務(wù)!


#if...#endif是C++中的條件編譯預(yù)處理命令 有兩種格式:


1:#ifdef 標(biāo)示符


程序段1


#else


程序段2


#endif


表示:如果標(biāo)示符已經(jīng)被#define命令定義過(guò),則編譯程序段1,否則編譯程序段2。期中else部分可以沒(méi)有。


2:#if 表達(dá)式


程序段1


#else


程序段2


#endif


表示:如果表達(dá)式為真,則編譯程序段1,否則編譯程序段2.

if((USART_RX_STA&0x8000)==0) //0x8000,即二進(jìn)制1000 0000 0000 0000,與變量USART_RX_STA,按位與(&),并與0比較,作用是判斷USART_RX_STA數(shù)值第16位是否為0。

USART_RX_STA&0x8000有兩種可能:

第一種1××× ×××× ×××× ××××&1000 0000 0000 0000=1000 0000 0000 0000

第二種0××× ×××× ×××× ××××&1000 0000 0000 0000=0000 0000 0000 0000

由此可以判斷USART_RX_STA第16位是否為0



USART_RX_STA的作用,USART_RX_STA一共有16位,前兩位為標(biāo)記位,后14位記錄了串口發(fā)送的數(shù)的位數(shù)。第一位標(biāo)記位標(biāo)記了Res是否為0x0a,第二位標(biāo)記位標(biāo)記了Res是否為0x0d。

知識(shí)點(diǎn):0x0d是回車的ASCLL碼,0x0a是換行的ASCLL碼


USART_RX_BUF這個(gè)是用來(lái)保存接收到的數(shù)據(jù)的可以看到每次結(jié)束判斷會(huì)有

USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;

USART_RX_STA=0; //接收狀態(tài)標(biāo)記

USART_RX_STA的作用就是在全部函數(shù)之間實(shí)現(xiàn)一個(gè)消息傳遞,自己設(shè)置,自己管理,自己識(shí)別。

bit15 bit14 bit13~0

接收完成標(biāo)志0x0a 接收到0X0d標(biāo)志 接收到的有效數(shù)據(jù)個(gè)數(shù)


USART_RX_STA|=0x4000;將第二位狀態(tài)標(biāo)志位置為1;在倒數(shù)第1次循環(huán)中使用USART_RX_STA|=0x8000;將第一位狀態(tài)標(biāo)志位也置為1,;而后串口數(shù)據(jù)接收結(jié)束,所有從串口接收的數(shù)據(jù)保存在USART_RX_BUF[ ]數(shù)組中,串口所發(fā)送的數(shù)據(jù)長(zhǎng)度保存在USART_RX_STA的后14位中。


關(guān)鍵字:STM32  串口接收  不定長(zhǎng)數(shù)據(jù)  標(biāo)志位 引用地址:STM32串口接收不定長(zhǎng)數(shù)據(jù):采用標(biāo)志位(比如0X0D,0X0A)結(jié)束法

上一篇:STM32CUBEMX(13)--SPI,W25Q128外部Flash移植
下一篇:總結(jié)STM32控制中常見(jiàn)的PID算法 理解萬(wàn)能的PID算法

推薦閱讀最新更新時(shí)間:2025-04-24 08:27

關(guān)于調(diào)試STM32程序時(shí),某些標(biāo)志被調(diào)試軟件意外清除的問(wèn)題
在調(diào)試的過(guò)程中,使用調(diào)試軟件的寄存器或存儲(chǔ)器顯示窗口,可以很方便地查看外設(shè)寄存器的狀態(tài)。 很多朋友都碰到過(guò)這樣的問(wèn)題:在單步調(diào)試時(shí)始終不能在顯示窗口看到某些標(biāo)志位的變化,應(yīng)該設(shè)置這些標(biāo)志位的時(shí)候,窗口中卻顯示為0,不少人都錯(cuò)誤地認(rèn)為這是芯片的問(wèn)題。 我們知道,不少STM32外設(shè)的狀態(tài)寄存器位,可以通過(guò)對(duì)某些寄存器的讀操作而清除(例如I2C的I2C_SR1中的很多標(biāo)志位),在調(diào)試過(guò)程中,每當(dāng)程序停止在設(shè)置的斷點(diǎn)或單步停止時(shí),調(diào)試軟件都會(huì)自動(dòng)地讀出所有指定的寄存器和存儲(chǔ)器中的內(nèi)容,并刷新窗口的顯示,調(diào)試軟件的這個(gè)讀操作恰好清除了那些標(biāo)志位,造成了上面描述的現(xiàn)象。 有幾個(gè)簡(jiǎn)單的辦法解決這個(gè)問(wèn)題: 1)關(guān)閉寄存器或存儲(chǔ)器顯示窗口 2
[單片機(jī)]
STM32串口DMA接收定長(zhǎng)數(shù)據(jù)
引言 在使用stm32或者其他單片機(jī)的時(shí)候,會(huì)經(jīng)常使用到串口通訊,那么如何有效地接收數(shù)據(jù)呢?假如這段數(shù)據(jù)是不定長(zhǎng)的有如何高效接收呢? 同學(xué)A:數(shù)據(jù)來(lái)了就會(huì)進(jìn)入串口中斷,在中斷中讀取數(shù)據(jù)就行了! 中斷就是打斷程序正常運(yùn)行,怎么能保證高效呢?經(jīng)常把主程序打斷,主程序還要不要運(yùn)行了? 同學(xué)B:串口可以配置成用DMA的方式接收數(shù)據(jù),等接收完畢就可以去讀取了! 這個(gè)同學(xué)是對(duì)的,我們可以使用DMA去接收數(shù)據(jù),不過(guò)DMA需要定長(zhǎng)才能產(chǎn)生接收中斷,如何接收不定長(zhǎng)的數(shù)據(jù)呢? DMA簡(jiǎn)介 題外話:其實(shí),上面的問(wèn)題是很有必要思考一下的,不斷思考,才能進(jìn)步。 什么是DMA DMA:全稱Direct Memory Access,即直
[單片機(jī)]
<font color='red'>STM32</font>之<font color='red'>串口</font>DMA<font color='red'>接收</font>不<font color='red'>定長(zhǎng)</font><font color='red'>數(shù)據(jù)</font>
#C51串口通訊4-#一串數(shù)據(jù)#中斷即時(shí)解析用戶自定義協(xié)議(握手接收應(yīng)答)
前言 提示: 1.上一章測(cè)試一種方法:簡(jiǎn)單協(xié)議下利用串口中斷實(shí)時(shí)接收數(shù)據(jù)并校驗(yàn)后進(jìn)行解析。 2.實(shí)際項(xiàng)目開(kāi)發(fā)時(shí),主機(jī)下發(fā)命令后,從機(jī)首先進(jìn)行握手確認(rèn),數(shù)據(jù)錯(cuò)誤情況下要進(jìn)行相應(yīng)回應(yīng)(如錯(cuò)誤指令)。 3.本章繼續(xù)豐富開(kāi)發(fā),增加主從應(yīng)答機(jī)制 提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 一、場(chǎng)景 示例: 主機(jī)下發(fā)命令,從機(jī)中斷解析并應(yīng)答,主函數(shù)處理事件 二、編程實(shí)現(xiàn) 1.自定義協(xié)議 如: ##主機(jī)類型定義命令類型(查詢,設(shè)置,器件控制等等) 以控制數(shù)碼管顯示0x01為例 ##從機(jī)握手應(yīng)答: a.數(shù)據(jù)正確回復(fù):BB66BB8000 b.和校驗(yàn)錯(cuò)誤回復(fù):BB66BB8100 c.異或校驗(yàn)錯(cuò)誤回復(fù):BB66BB820
[單片機(jī)]
#C51<font color='red'>串口</font>通訊4-#一串<font color='red'>數(shù)據(jù)</font>#中斷即時(shí)解析用戶自定義協(xié)議(握手<font color='red'>接收</font>應(yīng)答)
STM32CubeMX HAL庫(kù)串口+DMA數(shù)據(jù)發(fā)送不定長(zhǎng)數(shù)據(jù)接收
參考資料: 1、ST HAL庫(kù)官網(wǎng)資料 2、https://blog.csdn.net/u014470361/article/details/79206352#comments 一、STM32CubeMX配置外部時(shí)鐘 注意在進(jìn)行外部時(shí)鐘配置時(shí),即“High Speed Clock”和“Low Speed Clock”需配置成“Crytal/Ceramic Resonator(低溫/陶瓷諧振器)”不能配置為 BYASS Clock Source(時(shí)鐘脈沖源) ,否則系統(tǒng)起不來(lái)。 二、SWD下載接口配置 如果用HAL庫(kù)不進(jìn)行SWD或JTAG配置,單片機(jī)只能進(jìn)行下載一次程序,要進(jìn)行第二次或更多次程序下載,需要按復(fù)位鍵(如
[單片機(jī)]
STM32CubeMX HAL庫(kù)<font color='red'>串口</font>+DMA<font color='red'>數(shù)據(jù)</font>發(fā)送不<font color='red'>定長(zhǎng)</font>度<font color='red'>數(shù)據(jù)</font><font color='red'>接收</font>
STM8S003F使用IO口模擬串口(三)使用中斷方式發(fā)送和接收數(shù)據(jù)
在前兩篇文章中我們介紹了IO口模擬串口發(fā)送數(shù)據(jù)和接收數(shù)據(jù),前兩種方法都是使用定時(shí)器來(lái)進(jìn)行發(fā)送和接收,沒(méi)有用到中斷,優(yōu)點(diǎn)是邏輯簡(jiǎn)單,但是缺點(diǎn)很明顯,只能進(jìn)行單個(gè)字節(jié)的發(fā)送和接收,而且不能同時(shí)工作。因此在實(shí)際工程中沒(méi)有什么作用,僅供學(xué)習(xí)使用。使用中斷方式我們可以發(fā)送和接收多個(gè)字節(jié)的數(shù)據(jù)。 1、使用中斷方式進(jìn)行IO口模擬串口發(fā)送和接收數(shù)據(jù)的原理 這篇文章我將使用中斷的方式進(jìn)行發(fā)送和接收,同樣的,由于原理缺陷,這篇文章介紹的方法無(wú)法同時(shí)接收和發(fā)送,而且由于發(fā)送會(huì)延時(shí),是一個(gè)不太好的方法,僅供學(xué)習(xí)使用。 注意:這篇文章實(shí)現(xiàn)的IO口模擬串口無(wú)法同時(shí)接收和發(fā)送數(shù)據(jù)!如有需要在實(shí)際項(xiàng)目中使用IO口模擬串口工作,請(qǐng)移步: 1.1、發(fā)送數(shù)據(jù)的
[單片機(jī)]
DMA和UART的深刻認(rèn)識(shí)--串口接收的3種工作方式(附STM32F4代碼)
可能會(huì)遇到的問(wèn)題: 1.能實(shí)現(xiàn)接收但不發(fā)送 注意是否是識(shí)別函數(shù)出錯(cuò) 2.DMA單次傳輸模式要求再初始化,否者出現(xiàn)第二次中斷不執(zhí)行。使用循環(huán)模式出現(xiàn)的問(wèn)題是要結(jié)合配置公式: 3.DMA再次初始化不完全,會(huì)出現(xiàn)接收一次成功,再來(lái)一次不行。第三次能接收的問(wèn)題 4.串口調(diào)試連續(xù)點(diǎn)擊的次數(shù)太快,會(huì)使的里面的發(fā)送程序出錯(cuò) 一.串口uart中斷接收 遇到的問(wèn)題: 1、串口調(diào)試接收引腳壞掉 2.接收數(shù)據(jù)識(shí)別,使用的庫(kù)函數(shù)出錯(cuò) 串口設(shè)置的一般步驟可以總結(jié)為如下幾個(gè)步驟: 1) 串口時(shí)鐘使能, GPIO 時(shí)鐘使能。 2) 設(shè)置引腳復(fù)用器映射:調(diào)用 GPIO_PinAFConfig 函數(shù)。 3) GPIO 初始
[單片機(jī)]
DMA和UART的深刻認(rèn)識(shí)--<font color='red'>串口</font><font color='red'>接收</font>的3種工作方式(附STM32F4代碼)
USART串口發(fā)送接收數(shù)據(jù)
1.發(fā)送模塊程序及仿真圖 (程序中發(fā)送數(shù)據(jù)為0x03) (以下是發(fā)送模塊程序) #include pic.h __CONFIG(HS&UNPROTECT&DUNPROT&PWRTDIS&BORDIS&WDTDIS&LVPDIS&DEBUGEN&WRTEN); #define uchar unsigned char #define uint unsigned int uchar k,d; void usartint(void) { TRISC=0xC0;//RC端口RC6、RC7分別為輸出和輸入1100 0000 SPBRG= 77;//設(shè)置波特率9600,系統(tǒng)時(shí)鐘12MHZ TXST
[單片機(jī)]
單片機(jī)串口接收中斷老是接收到00 00 00 00
發(fā)現(xiàn)一個(gè)問(wèn)題,串口接收中斷 Sendstring( Receiving ............ ); //串口向終端發(fā)送字符串,結(jié)尾處回車換行 Sendstring( ---------------------- ); void revdata(void) interrupt 4 { unsigned char temp; while(RI==0); //if(RI==0) //return; // //如果沒(méi)有接收中斷標(biāo)志,返回 RI = 0; //清串行中斷標(biāo)志位 temp = SBUF; //接收緩沖器中的字符 Sendchar(temp);
[單片機(jī)]
小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 郓城县| 乐业县| 霍州市| 化隆| 彭州市| 安塞县| 绥棱县| 瑞昌市| 天水市| 阆中市| 通化市| 邛崃市| 青海省| 古交市| 湖口县| 广饶县| 洛川县| 体育| 新沂市| 柳江县| 屯门区| 土默特右旗| 定边县| 沙河市| 固阳县| 襄城县| 濮阳市| 孝昌县| 谷城县| 永兴县| 靖安县| 赤壁市| 进贤县| 平阴县| 普兰店市| 靖江市| 丰台区| 健康| 周口市| 屏山县| 九寨沟县|