電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 80|回復(fù): 0
收起左側(cè)

嵌入式經(jīng)常用到串口,如何判斷串口數(shù)據(jù)接收完成?

[復(fù)制鏈接]

485

主題

485

帖子

1623

積分

三級會員

Rank: 3Rank: 3

積分
1623
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-12-1 17:50:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
( Z6 X' [2 z0 f關(guān)注我,一起變得更加優(yōu)秀!說起通信,首先想到的肯定是串口,日常中232和485的使用比比皆是,數(shù)據(jù)的發(fā)送、接收是串口通信最基礎(chǔ)的內(nèi)容。這篇文章主要討論串口接收數(shù)據(jù)的斷幀操作?臻e中斷斷幀一些mcu(如:stm32f103)在出廠時就已經(jīng)在串口中封裝好了一種中斷——空閑幀中斷,用戶可以通過獲取該中斷標(biāo)志位來判斷數(shù)據(jù)是否接收完成,中斷標(biāo)志在中斷服務(wù)函數(shù)中獲取,使用起來相對簡單。void UART4_IRQHandler(void)8 L# e6 E; }. ^
{: V! T9 |: n5 x. P
    uint8_t data = 0;
6 G+ f# B1 Z- k; V* _7 @    data = data;' m5 L$ I5 |# ^2 X7 i# z! E
    if(USART_GetITStatus(LoraUSARTx, USART_IT_RXNE) == SET)
4 Q' L) E7 f) H- a* f    {/ ^  g+ e! M  U9 R4 k! q3 u
        USART_ClearITPendingBit(LoraUSARTx, USART_IT_RXNE);
, [: `* _2 y7 l% s0 B) [& b* x        if(Lora_RecvData.Rx_over == 0)4 w: m. V$ K4 C# ^! h; Q! d# B
            Lora_RecvData.RxBuf[Lora_RecvData.Rx_count++] = LoraUSARTx->DR;
. ?2 Q" d1 e: I. W    }5 J" r' C" E! z3 Y, d
    if(USART_GetITStatus(LoraUSARTx, USART_IT_IDLE) == SET)/ m  o0 j) m  N9 R5 b3 J- L8 L
    {
, |/ J3 ]* f5 \% m$ Z        data = LoraUSARTx->SR;
* p5 \# W1 ]6 A$ K        data = LoraUSARTx->DR;( o6 L$ b& S& M. R, N7 l5 J& ^
        # w: ?4 W+ [' A
        Lora_RecvData.Rx_over = 1; //接收完成
5 `* c/ c( f; i, w# A$ l6 N- P9 e    }
0 i. n8 n. F7 K, E6 q4 C1 n5 X}例程中,當(dāng)接收完成標(biāo)志 Lora_RecvData.Rx_over 為1時,就可以獲取 uart4 接收到的一幀數(shù)據(jù),該數(shù)據(jù)存放在 Lora_RecvData.RxBuf 中。# ^# P% C$ u! e, a, o
超時斷幀空閑幀中斷的使用固然方便,但是并不是每個mcu都有這種中斷存在(只有個別高端mcu才有),那么這個時候就可以考慮使用超時斷幀了。$ Z- j2 m4 t/ q' J, ]0 i
Modbus協(xié)議中規(guī)定一幀數(shù)據(jù)的結(jié)束標(biāo)志為3.5個字符時長,那么同樣的可以把這種斷幀方式類比到串口的接收上,這種方法需要搭配定時器使用。$ A0 b3 h3 q4 K7 ?
其作用原理就是:串口進(jìn)一次接收中斷,就打開定時器超時中斷,同時裝載值清零(具體的裝載值可以自行定義),只要觸發(fā)了定時器的超時中斷,說明在用戶規(guī)定的時間間隔內(nèi)串口接收中斷里沒有新的數(shù)據(jù)進(jìn)來,可以認(rèn)為數(shù)據(jù)接收完成。/ n8 t" v4 ?0 F' v
uint16_t Time3_CntValue = 0;//計(jì)數(shù)器初值5 }7 r4 ~6 I* x; s+ r; L) ?

) A. D' R: P; f' C2 J1 N" ~2 i/*******************************************************************************
# u1 f4 M' R) l- A. ] * TIM3中斷服務(wù)函數(shù); s+ K$ N+ a! V$ s( s
******************************************************************************/
! G( i/ s& m. y6 `+ q7 _void Tim3_IRQHandler(void)% ?8 i8 f3 B) u4 W+ ]# j/ [. `& l
{+ m& x2 f; t  [" p0 C, g
    if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
- R. n+ o& D2 Y    {  x  j) T( H! P; l0 h: e. l
        Tim3_M0_Stop();    //關(guān)閉定時器3
; _. ~% e; x! I& Z" N/ S; i        Uart0_Rec_Count = 0;//接收計(jì)數(shù)清零% H3 c+ g. \% a- X" X1 ?# s
        Uart0_Rec_Flag = 1; //接收完成標(biāo)志
, F7 K- e' q4 v: u        Tim3_ClearIntFlag(Tim3UevIrq); //清除定時器中斷7 m' ^8 ?- S' b$ p$ h) b7 ~3 ^& P$ {
    }7 b; {$ n: s; s5 ?3 R
}* c5 t* p: @0 X2 o1 G& Y- \0 }

4 _$ y& s4 t/ b, L6 D5 K3 P2 }void Time3_Init(uint16_t Frame_Spacing)
  h: Y* o' `& G( E# s  G{7 I- \/ x) ^+ ]. {2 Q/ v# B! N# s9 O+ ^& l
    uint16_t u16ArrValue;//自動重載值6 g! X+ a+ ^! _6 d; F9 X
    uint32_t u32PclkValue;//PCLK頻率' Q3 v8 D  U. P, O
   
* W$ E* @/ i6 Z& x    stc_tim3_mode0_cfg_t     stcTim3BaseCfg;1 r" R" f4 O. z3 E/ `7 b5 w: D
    * [& }) Y- K3 V# U
    //結(jié)構(gòu)體初始化清零
  o: R2 ^- f# v; R2 a8 x    DDL_ZERO_STRUCT(stcTim3BaseCfg);. r6 y# X% B6 ?$ I: q8 L3 a1 o
   
& @! D) p' l' J4 J    Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Base Timer外設(shè)時鐘使能
! c6 Z8 E" P/ T1 M   
) Z& i# v7 X8 H: v2 U    stcTim3BaseCfg.enWorkMode = Tim3WorkMode0;              //定時器模式
% j- p# C/ O  G4 M' o7 l    stcTim3BaseCfg.enCT       = Tim3Timer;                  //定時器功能,計(jì)數(shù)時鐘為內(nèi)部PCLK
, t1 h3 d" I6 x" u    stcTim3BaseCfg.enPRS      = Tim3PCLKDiv1;               //不分頻' @( \- q) b( s; H+ z' e' w& B
    stcTim3BaseCfg.enCntMode  = Tim316bitArrMode;           //自動重載16位計(jì)數(shù)器/定時器
9 N2 [* u6 O3 I; ?9 g: {- G    stcTim3BaseCfg.bEnTog     = FALSE;4 d6 C1 n; D  A, F' o+ [
    stcTim3BaseCfg.bEnGate    = FALSE;
( y5 i) m* W3 z+ n" B* Z    stcTim3BaseCfg.enGateP    = Tim3GatePositive;4 E( K$ |( g) G6 T% L0 E+ D& k- ]
    ' W& f* d. V1 d
    Tim3_Mode0_Init(&stcTim3BaseCfg);             //TIM3 的模式0功能初始化
/ }/ J: j8 u% ]        
0 Q/ @2 s! [+ K3 v. [    u32PclkValue = Sysctrl_GetPClkFreq();          //獲取Pclk的值2 J1 |( j8 ^# C7 _
   //u16ArrValue = 65535-(u32PclkValue/1000);      //1ms測試5 l. ~$ O. I. N1 Z
    u16ArrValue = 65536 - (uint16_t)((float)(Frame_Spacing*10)/RS485_BAUDRATE*u32PclkValue);//根據(jù)幀間隔計(jì)算超時時間2 r+ \' O0 V( f( g  b6 q
    Time3_CntValue = u16ArrValue;             //計(jì)數(shù)初值" E7 ^9 g7 K( z+ R
    Tim3_M0_ARRSet(u16ArrValue);              //設(shè)置重載值& X! m* S4 {0 L* d
    Tim3_M0_Cnt16Set(u16ArrValue);            //設(shè)置計(jì)數(shù)初值
& j8 X3 y3 h( f2 ^+ j) H: r    + E' M6 \  V1 ^% M
    Tim3_ClearIntFlag(Tim3UevIrq);            //清中斷標(biāo)志
6 I# `2 @: f1 Q" ]* ?' b    Tim3_Mode0_EnableIrq();                   //使能TIM3中斷(模式0時只有一個中斷)) T# U1 r" o! Q3 ~- w( |0 ?
    EnableNvic(TIM3_IRQn, IrqLevel3, TRUE);   //TIM3 開中斷  
: O, Z  H3 y/ u& V- Z7 L) `! h} ( ~: c3 o% [% i+ d' t! R
9 U& R  d1 h4 F$ I1 c% V1 f1 P
/**************************此處省略串口初始化部分************************/
8 P$ s  @6 T" w* \/ ?4 P- o: V//串口0中斷服務(wù)函數(shù)* ^8 Z9 U4 V) u5 o8 }: I$ G3 ]
void Uart0_IRQHandler(void)
% u/ S1 s9 w8 z+ R) z{- `# J' r, V. U
    uint8_t rec_data=0;; Y# ^5 R. o4 B# k* t
    + X3 |! i1 O0 O: C0 o) J2 l
    if(Uart_GetStatus(M0P_UART0, UartRC))         
, [5 {7 C8 m5 ]& P    {0 n, W/ G/ U$ O; A7 L" X
        Uart_ClrStatus(M0P_UART0, UartRC);        
  x) [) ?4 i- \9 R        rec_data = Uart_ReceiveData(M0P_UART0);     % N1 q( j' F0 M! _+ g: K
        if(Uart0_Rec_Count[U]//幀長度8 O1 U8 m: P8 c, N
        {) b! k& [0 F" r& _; X; B8 H: l
            Uart0_Rec_Buffer[Uart0_Rec_Count++] = rec_data;        
1 P, L0 x9 \$ U$ L        }
- J- D+ f1 o! @2 c, G# O        Tim3_M0_Cnt16Set(Time3_CntValue);//設(shè)置計(jì)數(shù)初值
7 G1 ^: }+ A+ x! Y% b+ G+ \/ A        Tim3_M0_Run();   //開啟定時器3 超時即認(rèn)為一幀接收完成5 g7 S4 w% a) S! n7 z2 ?: f
    }2 C% v7 q! Q) T+ v7 C( @
}例程所用的是華大的hc32l130系列mcu,其它類型的mcu也可以參考這種寫法。其中超時時間的計(jì)算尤其要注意數(shù)據(jù)類型的問題,u16ArrValue = 65536 - (uint16_t)((float)(Frame_Spacing * 10)/RS485_BAUDRATE * u32PclkValue);其中Frame_Spacing為用戶設(shè)置的字符個數(shù),uart模式為一個“1+8+1”共10bits。0 ?* [$ [) u" g; O
狀態(tài)機(jī)斷幀狀態(tài)機(jī),狀態(tài)機(jī),又是狀態(tài)機(jī),沒辦法!誰讓它使用起來方便呢?其實(shí)這種方法我用的也不多,但是狀態(tài)機(jī)的思想還是要有的,很多邏輯用狀態(tài)機(jī)梳理起來會更加的清晰。
' p8 c) R. v8 U- g) W, P8 s; g& K相對于超時斷幀,狀態(tài)機(jī)斷幀的方法節(jié)約了一個定時器資源,一般的mcu外設(shè)資源是足夠的,但是做一些資源冗余也未嘗不是一件好事,萬一呢?對吧。
- ]& n, A% p& T+ y7 Y) j//狀態(tài)機(jī)斷幀- h. ~: i* ^9 p' J: ]( u. Y1 K+ d
void UART_IRQHandler(void)  //作為485的接收中斷
$ T, N: _, h( d. b1 o{
9 I9 R6 R/ X& e4 _2 Q% c0 u    uint8_t count = 0;
( J# X# {4 l5 ^( n    unsigned char lRecDat = 0;
" s8 n* x: K( ~, k% Y' F7 | : o) ]* o: \# `5 A! Z" d" e8 T
    if(/*觸發(fā)接收中斷標(biāo)志*/)  
) }0 A6 D8 K. v: l1 |    {
# \/ a0 O$ f# n& h. |        //清中斷狀態(tài)位
( d- Z# U% U- b3 ]2 h& ~- G6 }        rec_timeout = 5;5 J1 K  e7 @# o6 e- V: u
        if((count == 0)) //接收數(shù)據(jù)頭,長度可以自定義
6 {5 u) _  x7 [& @        {% M, M; W$ w; t1 T/ o
            RUart0485_DataC[count++] = /*串口接收到的數(shù)據(jù)*/;1 T. u5 Y5 ]$ y
            gRecStartFlag = 1;* h6 j  @- n' o' _
            return;# B7 z# U' X4 i. a0 [6 d
        }- Y0 J3 \1 @# x4 j+ c( C
        if(gRecStartFlag == 1)) l) F7 z, |* ^; z4 u  h
        {8 M6 f$ e7 Q4 K0 O) p
            RUart0485_DataC[count++] = /*串口接收到的數(shù)據(jù)*/;
. l- _* l& E- D& U        $ I6 N; Z$ R0 ^7 O# p9 b) N, y
            if(count > MAXLEN) //一幀數(shù)據(jù)接收完成
; L6 w- ?5 h& l& ?8 A5 c9 F            {5 S- f' I' j* P
                count=0;
8 B- h/ T! t. D# B( {/ N6 M                gRecStartFlag = 0;
" g8 H% S6 D* Z               
( T" [& F* I3 d0 u# f# w4 k  y                if(RUart0485_DataC[MAXLEN]==CRC16(RUart0485_DataC,MAXLEN))9 b; b, V' y4 g* d, Q
                {$ ?: p+ B- h9 g# q5 o4 U$ h, E
                    memcpy(&gRecFinshData,RUart0485_DataC,13);
; r5 {( V  t/ f. ~( J3 j0 p; i                    gRcvFlag = 1; //接收完成標(biāo)志位                    
/ w& |' O. E+ f9 Y6 W: g                }
( U( z. }+ J% {& L  x            }   
5 ?. w) s% J* R) `# E        }# U' E  b- ~0 h- w+ ~! ?
        return;
' V: i6 c( |; r    }
6 W) E1 g! b$ G4 X8 T. E    return ;
  h: \- |: l; |* s) C}這種做法適合用在一直有數(shù)據(jù)接收的場合,每次接收完一幀有效數(shù)據(jù)后就把數(shù)據(jù)放到緩沖區(qū)中去解析,同時還不影響下一幀數(shù)據(jù)的接收。
: `( V* B  S: G. S  g1 ?+ y整個接收狀態(tài)分為兩個狀態(tài)——接收數(shù)據(jù)頭和接收數(shù)據(jù)塊,如果一幀數(shù)據(jù)存在多個部分的話還可以在此基礎(chǔ)上再增加幾種狀態(tài),這樣不僅可以提高數(shù)據(jù)接收的實(shí)時性,還能夠隨時看到數(shù)據(jù)接收到哪一部分,還是比較實(shí)用的。
/ m1 B2 r1 d& I6 m/ Z$ m"狀態(tài)機(jī)+FIFO"斷幀記得剛畢業(yè)面試的時候,面試官還問過我一個問題:如果串口有大量數(shù)據(jù)要接收,同時又沒有空閑幀中斷你會怎么做?
6 i4 y5 O6 O  ?# W0 _0 z沒錯,就是FIFO(當(dāng)時并沒有回答上來,因?yàn)闆]用過),說白了就是開辟一個緩沖區(qū),每次接收到的數(shù)據(jù)都放到這個緩沖區(qū)里,同時記錄數(shù)據(jù)在緩沖區(qū)中的位置,當(dāng)數(shù)據(jù)到達(dá)要求的長度的時候再把數(shù)據(jù)取出來,然后放到狀態(tài)機(jī)中去解析。當(dāng)然FIFO的使用場合有很多,很多數(shù)據(jù)處理都可以用FIFO去做,有興趣的可以多去了解一下。/********************串口初始化省略,華大mcu hc32l130******************/
, |- i6 u& I% M2 Q  jvoid Uart1_IRQHandler(void)* P% E6 ~- _+ m/ A4 F6 A
{2 m: U5 p" D2 A% n+ {* T5 F+ h8 I
    uint8_t data;
& Z( M! y) \5 Y7 ]! f9 }- S. R    if(Uart_GetStatus(M0P_UART1, UartRC))      //UART0數(shù)據(jù)接收9 P9 q6 H/ u5 G: Y' {0 W
    {
8 Y: S- @: U1 k. _) P" V  S        Uart_ClrStatus(M0P_UART1, UartRC);    //清中斷狀態(tài)位8 B( P4 O$ A8 ]  W' @; m
        data = Uart_ReceiveData(M0P_UART1);   //接收數(shù)據(jù)字節(jié)
$ _0 ?9 H/ L8 h9 r. U6 N  d        comFIFO(&data,1);
0 P/ W6 \! \6 _! {    }
4 `+ |  D  q( C7 j* d}
; _6 s1 X- {, x  @! U" i* |8 @. ?4 k1 J
% i' s+ \2 ^( b& ]: A6 v/******************************FIFO*******************************/
, K4 e/ c0 {: d9 \! g  Zvolatile uint8_t     fifodata[FIFOLEN],fifoempty,fifofull;" l/ ?- W* F5 s+ q9 t" O
volatile uint8_t     uart_datatemp=0;
7 M: y0 s9 |% R, `/ p
; O1 O7 R+ {5 k5 xuint8_t comFIFO(uint8_t *data,uint8_t cmd)1 q* r' O) W8 A9 D$ Z! I  c6 ~+ Q9 n
{
# t/ k8 X' v# S( h    static uint8_t rpos=0;  //當(dāng)前寫的位置 position 0--99 + ~4 g7 P; v9 q2 [, }' I! ~$ Y/ x
    static uint8_t wpos=0; //當(dāng)前讀的位置
" C$ M7 V4 R: ^ 6 A  e+ ]' J8 }' \$ O( t3 ?
    if(cmd==0) //寫數(shù)據(jù)
3 V* G1 X' G3 d1 y0 P+ Z3 ~/ Z" a/ D    {
  [8 P! N+ s5 b        if(fifoempty!=0)       //1 表示有數(shù)據(jù) 不為空,0表示空
% i& v) T- ~; ^* A1 |        {; d  `$ C4 I' ]
            *data=fifodata[rpos];  i$ x" V  [5 y' l) z
            fifofull=0;
# z* N+ W" l  R            rpos++;
4 r1 E9 [/ X: n( Q% p6 i            if(rpos==FIFOLEN)
0 a% u4 Q  P8 g' F* a                rpos=0;" o! [' o; V1 M( x+ S4 i0 O
            if(rpos==wpos)
' r' v6 Q+ U. f$ ~. H6 B) z. u7 f                fifoempty=0;5 N' L$ a" Y" R( v8 T" N! ~4 e
            return 0x01;, c3 C- I0 P! a$ X; `. [
        }
4 o2 d! e9 @& K: p7 m( M        else2 n) d, a# D  S! k1 ~' h5 r
            return 0x00;6 n( G) \# K' A/ r

% C$ F( s& R- J: K. _" d7 f    } - {+ d6 {* O; \+ b4 c' A- ]
    else if(cmd==1) //讀數(shù)據(jù)
9 k1 u- T5 d. O8 Z6 `. `4 Q9 i    {
2 ]4 |3 a; X: T' z0 b6 ~        if(fifofull==0)/ e, D6 D& N  O, m' C+ c: T6 b
        {
" `6 U/ O, `* X( }5 K            fifodata[wpos]=*data;3 W. f7 h2 R$ x! Y( p6 f
            fifoempty=1;. W. R  B  j/ D7 s! l) ]
            wpos++;( N$ @% Y0 b  T# @: X  @5 J! R
            if(wpos==FIFOLEN) 4 o% `' O8 b3 W& c' G, R
                wpos=0;5 J) O3 ]0 A; p0 R
            if(wpos==rpos) 6 H' ^" @# ?8 U& Y
                fifofull=1;
8 J' K/ F( G1 h            return 0x01;
9 ]3 X* n0 W' s& t" _        } else
, M7 m2 I( M4 E" u            return 0x00;
( S! F4 @. z- V' r: t    }
9 m+ m. i& m* ^" t$ S: u* o+ @    return 0x02;
2 A: U9 \+ l  _0 ~9 e}
& i8 S) N7 ~3 y. w + P8 y6 C  P/ F" W* c
/********************************狀態(tài)機(jī)處理*******************************/
2 j. z& m2 C* ~" f+ y) [void LoopFor485ReadCom(void)( J, P( Q# i2 z" `- Y  V! N
{
. F' I  {4 d5 g    uint8_t data;  L, g/ {1 B5 f' a2 w' \- V7 t" k

) i9 x; O! a2 o5 ]) ~5 z    while(comFIFO(&data,0)==0x01)
( m2 ?) k- g6 q8 r    {/ Z; t4 ?# E; {" W0 K4 r' T1 \
        if(rEadFlag==SAVE_HEADER_STATUS) //讀取頭" ]! i) F! ~* M7 [6 a
        {' u- T. L9 R. q' ^/ }0 n
            if(data==Header_H)1 d3 B/ c, a: ]0 F- {' F, T1 B1 ~
            {5 e( i: P1 T1 [; }
                buffread[0]=data;  x% C* j: K1 y
                continue;
' e- {* X% x" y  p3 o6 s            }
4 \+ m- s' M0 n; }, ]            if(data==Header_L)
6 q4 c9 O& ^8 Z+ M  f5 G4 J1 e            {2 A' J' D1 H8 I# ^; V
                buffread[1]=data;: D4 O3 p( V2 [- p1 e* }/ z4 Q2 i
                if(buffread[0]==Header_H)( _/ q% I# u6 o7 H2 N" |- v
                {
$ g& Q+ b( F% B- i                    rEadFlag=SAVE_DATA_STATUS;2 u5 d: m+ C" N* U2 o! Y/ p
                }
1 ~/ r0 ^3 ~# @) U: R! Y+ {6 J. y            }
- m2 {0 H; e  w1 y' X% q4 N            else9 ~* e3 m& r  d+ J
            {
! K; V+ X3 t+ V' t                memset(buffread,0,Length_Data);3 {6 ]8 R, n  ]- }! H- e: }
            }
& {* ?1 `4 h: i! z4 s5 M5 ^$ j. S        } + q: ?5 v# a) U
        else if(rEadFlag==SAVE_DATA_STATUS)  //讀取數(shù)據(jù)( P( a9 q# L  s2 k1 L8 H+ M) \
        {8 w( _: M1 f6 V5 z+ c2 s
            buffread[i485+2]=data;4 ~& Q! C; B4 x3 _4 u
            i485++;/ |% o7 _  u- I+ \
            if(i485==(Length_Data-2)) //數(shù)據(jù)幀除去頭
& J8 c: k, O* `6 [4 Q# t            {
. |/ k' Y0 R8 l; a! d4 |, M. p6 [                unsigned short crc16=CRC16_MODBUS(buffread,Length_Data-2);
8 Q: i& Y& `/ r! `0 L                if((buffread[Length_Data-2]==(crc16>>8))&&(buffread[Length_Data-1]==(crc16&0xff)))
" T3 u- x4 T' {' q' B                {# o/ T% D1 g$ K; u6 E. V
                    rEadFlag=SAVE_OVER_STATUS;
+ H9 K  Y. @9 L  X' n0 Q5 Q7 Y, n                    memcpy(&cmddata,buffread,Length_Data);  //拷貝Length_Struct個字節(jié),完整的結(jié)構(gòu)體
) L1 E2 c+ H. `4 [. B! z# F0 M                }
" d' }3 k7 s- t9 v' {+ m                else( W. w: g0 S9 T5 ?9 [( D
                {2 c3 k: f1 J/ V$ r; j
                    rEadFlag=SAVE_HEADER_STATUS;5 T# h7 G( ?. M* o8 [- f8 K8 o
                }$ |8 y/ }6 V# {8 E9 X
        
. U6 r! J& `9 A  d* m+ f( L                memset(buffread,0,Length_Data);
7 s8 g" |7 B, I                i485=0;: \! `/ F. H' x( J
                break;7 }5 C- r  n/ I7 z
            }" d7 m: U4 l+ L- ~
        }
* K2 B# z3 F1 v/ e    }! K- n& o7 `% e, S8 v
}原文:https://blog.csdn.net/qq_56527127/article/details/123018515( S1 W. `# J6 D3 C# `
0 E6 A5 l( k2 Z' w
-END-
+ K% t* F  L1 K1 K2 ]往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀3 f; V* h9 K/ Q

0 q6 e) l5 e3 E- A% m. k% X                                                       
" H( E# y7 d2 C. k( C                                                                " F1 m& q* ?7 }3 [: Z
                                                                       
8 Y; C5 d: e  T# z8 k, }7 m% R( a                                                                               
- j0 h, C9 C3 S8 Z' |( G: e( Z- z5 c
9 q: T% ]5 l' I& ], X1 }7 f                                                                                - S% t  D; I. R2 {
                                                                                        嵌入式軟件調(diào)試,如何計(jì)算任務(wù)的運(yùn)行周期?5 Q& [6 X( }* g! P& W
                                                                                  t9 n/ m/ D' G
                                                                       
1 q5 W: G0 |5 J3 t# r                                                                & n$ ]* T: f% a# l1 z
                                                       
: t( J1 N7 t1 ~  F                                                3 b3 _( `* z4 Z5 m2 E2 {8 h/ i
, X" D' D0 x' Q9 f
                                                        ! K+ p. B: |) H+ Q. D
                                                               
. N' o+ T( t* s3 b4 W                                                                        ! C1 v: r1 o# v' @
                                                                               
' _$ t& U& j1 |  Q * x- e( t& i0 k! ^# Y
                                                                               
" G! x% h/ j# C6 z                                                                                        嵌入式軟件,如何把編譯時間加入到bin文件,進(jìn)行版本管理?
, B+ o+ c$ i- o- u( ~# h+ O                                                                                6 c* q% R9 o6 E* e  z! A$ y5 z! C) y$ Z
                                                                        2 F/ ~! N: @( _% x- |2 G
                                                               
" o$ F0 w0 A& r                                                        9 b4 s7 M# m7 j  Z
                                               
( z7 n+ l/ U$ W& V& k1 s: c7 E$ D( o9 e8 b# ^+ V- O
                                                        % I; z9 K$ J9 ?" z) g/ \  B
                                                                0 p) ^( E/ F: i2 T& P# b
                                                                        * E! x, `! ?% \1 T# T
                                                                                7 w6 \+ k/ A( R; w) F
: m  H: c+ v" \. _
                                                                               
# K! d! b, z0 I/ @( ]                                                                                        嵌入式初學(xué)者入門后,應(yīng)該如何開始進(jìn)階學(xué)習(xí)?- {0 E/ P" N4 q/ L
                                                                                # O0 H9 @  U2 [, s- O
                                                                        / ?$ A$ y# D4 S5 x5 _
                                                                : q& o; N- x3 v2 A8 c3 s7 ?
                                                       
* e  b1 W: i' j' K& \                                                & C3 N0 M$ a: L$ G8 K
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師) A: W) W' `' D% p8 j  f9 e
關(guān)注我,一起變得更加優(yōu)秀!

發(fā)表回復(fù)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表