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

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

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

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

[復(fù)制鏈接]

485

主題

485

帖子

1623

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
1623
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-12-1 17:50:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師- p9 P% r% M# {! E
關(guān)注我,一起變得更加優(yōu)秀!說起通信,首先想到的肯定是串口,日常中232和485的使用比比皆是,數(shù)據(jù)的發(fā)送、接收是串口通信最基礎(chǔ)的內(nèi)容。這篇文章主要討論串口接收數(shù)據(jù)的斷幀操作。空閑中斷斷幀一些mcu(如:stm32f103)在出廠時(shí)就已經(jīng)在串口中封裝好了一種中斷——空閑幀中斷,用戶可以通過獲取該中斷標(biāo)志位來判斷數(shù)據(jù)是否接收完成,中斷標(biāo)志在中斷服務(wù)函數(shù)中獲取,使用起來相對(duì)簡(jiǎn)單。void UART4_IRQHandler(void)$ _) ]" i5 R/ _0 _7 i
{
. m: [. m$ Z! ~- A( r% J3 o    uint8_t data = 0;
$ P' `( [) G* o( e/ N    data = data;3 p; ?. x/ ^- D  T- q
    if(USART_GetITStatus(LoraUSARTx, USART_IT_RXNE) == SET)
/ ^6 w$ G; R) ]1 v3 l6 m' l, E    {8 i% B# g1 `' I' F- v# p& e5 f/ G
        USART_ClearITPendingBit(LoraUSARTx, USART_IT_RXNE);
: j7 u6 m6 ~' U        if(Lora_RecvData.Rx_over == 0)
( I9 I7 ^. r2 |% S. s% V            Lora_RecvData.RxBuf[Lora_RecvData.Rx_count++] = LoraUSARTx->DR;! X* ^  d1 ~! x9 L0 R2 W$ g1 C
    }
( t) l1 Z# ?" ?" L' m    if(USART_GetITStatus(LoraUSARTx, USART_IT_IDLE) == SET)
9 F! ?( L3 I) g" V1 t* f# N! t    {
  ^9 U/ O- C( K7 V! L4 a        data = LoraUSARTx->SR;. v* J3 h) s1 y  r- l) {* D, Z
        data = LoraUSARTx->DR;: v8 r: m5 _8 ^7 C
        ; L( ^: a5 h, `6 F
        Lora_RecvData.Rx_over = 1; //接收完成
0 M) v+ v2 B, N4 I) q    }
( ]  M( [9 p3 B! m}例程中,當(dāng)接收完成標(biāo)志 Lora_RecvData.Rx_over 為1時(shí),就可以獲取 uart4 接收到的一幀數(shù)據(jù),該數(shù)據(jù)存放在 Lora_RecvData.RxBuf 中。
3 w* X0 M  a* b- |9 z9 z% O2 h超時(shí)斷幀空閑幀中斷的使用固然方便,但是并不是每個(gè)mcu都有這種中斷存在(只有個(gè)別高端mcu才有),那么這個(gè)時(shí)候就可以考慮使用超時(shí)斷幀了。
( {; c8 i$ u+ @; y: x9 wModbus協(xié)議中規(guī)定一幀數(shù)據(jù)的結(jié)束標(biāo)志為3.5個(gè)字符時(shí)長(zhǎng),那么同樣的可以把這種斷幀方式類比到串口的接收上,這種方法需要搭配定時(shí)器使用。1 v3 U1 L. v7 \* L% Q& l$ z: C7 ~
其作用原理就是:串口進(jìn)一次接收中斷,就打開定時(shí)器超時(shí)中斷,同時(shí)裝載值清零(具體的裝載值可以自行定義),只要觸發(fā)了定時(shí)器的超時(shí)中斷,說明在用戶規(guī)定的時(shí)間間隔內(nèi)串口接收中斷里沒有新的數(shù)據(jù)進(jìn)來,可以認(rèn)為數(shù)據(jù)接收完成。
0 E3 z; d4 [# i2 e! }3 Puint16_t Time3_CntValue = 0;//計(jì)數(shù)器初值
: Q' s) g' J% u( s6 u. A( [
" T) h4 V& ~2 I; C0 c/*******************************************************************************
% L! @( {7 i3 U9 H# m * TIM3中斷服務(wù)函數(shù)4 r7 q* A3 \$ C' K
******************************************************************************/+ A8 Y$ P0 S) H( |6 C
void Tim3_IRQHandler(void)
/ c& ~! A) g4 Y{; N/ F  }0 l" J  z3 Z. a, I, |
    if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
. Z, K1 |, o# `    {
. Z; e. p( p1 z/ o/ G5 M        Tim3_M0_Stop();    //關(guān)閉定時(shí)器3) y& b  A+ H# T6 x7 q6 p) h
        Uart0_Rec_Count = 0;//接收計(jì)數(shù)清零
, K; V! _0 d/ W! {" Y8 k        Uart0_Rec_Flag = 1; //接收完成標(biāo)志# W* @4 O2 p) \' a0 n
        Tim3_ClearIntFlag(Tim3UevIrq); //清除定時(shí)器中斷- o7 W  }: N# l+ Q" q
    }5 {$ G  _; F) ~* I8 i+ [/ e
}
6 [) S# e4 R" Q+ ~. x  Y
" W" w( q1 o7 q6 W1 ovoid Time3_Init(uint16_t Frame_Spacing)
  V6 v9 W( P2 U7 N* g{* j' p4 G( y4 ^0 v
    uint16_t u16ArrValue;//自動(dòng)重載值* ?. X( ]9 E" T# }% m, w) ~
    uint32_t u32PclkValue;//PCLK頻率: y' {! j# I( ]* ^
    8 w1 n. Q% y- Q  V8 T
    stc_tim3_mode0_cfg_t     stcTim3BaseCfg;
+ i9 k$ S; }! L8 Y% S( g( v   
0 d  K6 K1 R& N! B( Y    //結(jié)構(gòu)體初始化清零2 a. x- ?+ @( F5 A& N+ Y
    DDL_ZERO_STRUCT(stcTim3BaseCfg);4 l. V/ @$ T3 p6 h, M
   
" B1 Y4 G' ]8 q# C/ N$ Y$ F% y1 E    Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Base Timer外設(shè)時(shí)鐘使能
. n( o8 x3 U; X$ W   
" e  b$ ]. n2 r& L- _+ G  `& f. _    stcTim3BaseCfg.enWorkMode = Tim3WorkMode0;              //定時(shí)器模式
$ z* p, O  \* v+ Z    stcTim3BaseCfg.enCT       = Tim3Timer;                  //定時(shí)器功能,計(jì)數(shù)時(shí)鐘為內(nèi)部PCLK9 x6 a7 [, D" V- w3 x1 z
    stcTim3BaseCfg.enPRS      = Tim3PCLKDiv1;               //不分頻
8 s+ J2 [, _! \' o- o( z6 u: y    stcTim3BaseCfg.enCntMode  = Tim316bitArrMode;           //自動(dòng)重載16位計(jì)數(shù)器/定時(shí)器
) X1 ~; j0 E( A  d5 V8 t    stcTim3BaseCfg.bEnTog     = FALSE;
9 |$ C( E4 y, i, e9 ?    stcTim3BaseCfg.bEnGate    = FALSE;
/ R, S5 `6 n9 Y6 D    stcTim3BaseCfg.enGateP    = Tim3GatePositive;& B- Y$ y8 c# |
    ) y, S6 |, Q# c5 n" Y0 M' \! v
    Tim3_Mode0_Init(&stcTim3BaseCfg);             //TIM3 的模式0功能初始化
" f  V) x" g: x6 H        4 F* h  J4 r5 z; u. r6 Y
    u32PclkValue = Sysctrl_GetPClkFreq();          //獲取Pclk的值
1 k. E: g* n* E- [/ D   //u16ArrValue = 65535-(u32PclkValue/1000);      //1ms測(cè)試" `. l% z# }. V! n% r4 u4 Q
    u16ArrValue = 65536 - (uint16_t)((float)(Frame_Spacing*10)/RS485_BAUDRATE*u32PclkValue);//根據(jù)幀間隔計(jì)算超時(shí)時(shí)間4 ?# H) x3 w, \- K& H/ P0 l
    Time3_CntValue = u16ArrValue;             //計(jì)數(shù)初值
5 D4 U- e$ j+ A$ V    Tim3_M0_ARRSet(u16ArrValue);              //設(shè)置重載值
4 f  ?* r4 j. ~) B    Tim3_M0_Cnt16Set(u16ArrValue);            //設(shè)置計(jì)數(shù)初值+ y" Z) u$ N. i9 `  K
    & ?+ f5 |( T$ t, f- }
    Tim3_ClearIntFlag(Tim3UevIrq);            //清中斷標(biāo)志
) O& s9 w9 P% O* E/ c+ H$ i    Tim3_Mode0_EnableIrq();                   //使能TIM3中斷(模式0時(shí)只有一個(gè)中斷)- G1 q0 F1 h2 W. L3 D  |" E
    EnableNvic(TIM3_IRQn, IrqLevel3, TRUE);   //TIM3 開中斷  ( a& x5 {1 n; D* t$ ^* ^
} $ z4 o9 }) j/ i' _
: c9 R5 Y* d7 n
/**************************此處省略串口初始化部分************************/
' h4 h3 n  I$ f5 ?3 C  I//串口0中斷服務(wù)函數(shù)* ]) g: l+ k' j
void Uart0_IRQHandler(void)
% r3 D, }  p4 ?' b% B; S{
: P3 X4 Q: \& C' P7 e- a    uint8_t rec_data=0;
/ N- t8 t( s& o8 \    . D" Z1 o1 }1 B- B
    if(Uart_GetStatus(M0P_UART0, UartRC))         
+ e1 _& H  j$ D! ?+ ?    {& k' A% R- N6 h( Y8 g9 p
        Uart_ClrStatus(M0P_UART0, UartRC);        6 K8 v6 Q. Y2 _; W+ o
        rec_data = Uart_ReceiveData(M0P_UART0);     $ m( i% i* ^, m
        if(Uart0_Rec_Count[U]//幀長(zhǎng)度, p( F* A6 B4 R; {9 A' C/ C4 j
        {
/ ?& @1 ?/ j/ d" _8 B& |            Uart0_Rec_Buffer[Uart0_Rec_Count++] = rec_data;        % r* s9 V/ b8 n
        }
# L  T" m! u3 k! z5 a1 W        Tim3_M0_Cnt16Set(Time3_CntValue);//設(shè)置計(jì)數(shù)初值
8 V/ w+ ^' H9 E- @& r' W        Tim3_M0_Run();   //開啟定時(shí)器3 超時(shí)即認(rèn)為一幀接收完成
' P8 F! ^, r* c, [    }: `' p3 V. m9 O
}例程所用的是華大的hc32l130系列mcu,其它類型的mcu也可以參考這種寫法。其中超時(shí)時(shí)間的計(jì)算尤其要注意數(shù)據(jù)類型的問題,u16ArrValue = 65536 - (uint16_t)((float)(Frame_Spacing * 10)/RS485_BAUDRATE * u32PclkValue);其中Frame_Spacing為用戶設(shè)置的字符個(gè)數(shù),uart模式為一個(gè)“1+8+1”共10bits。. D8 [8 b7 G$ n8 N9 \" H& u5 z
狀態(tài)機(jī)斷幀狀態(tài)機(jī),狀態(tài)機(jī),又是狀態(tài)機(jī),沒辦法!誰讓它使用起來方便呢?其實(shí)這種方法我用的也不多,但是狀態(tài)機(jī)的思想還是要有的,很多邏輯用狀態(tài)機(jī)梳理起來會(huì)更加的清晰。
6 \' \7 w8 ]7 P& A+ ~8 \9 V# |% P相對(duì)于超時(shí)斷幀,狀態(tài)機(jī)斷幀的方法節(jié)約了一個(gè)定時(shí)器資源,一般的mcu外設(shè)資源是足夠的,但是做一些資源冗余也未嘗不是一件好事,萬一呢?對(duì)吧。8 e$ z5 p1 H6 s/ k  {" e( G& r  q, l
//狀態(tài)機(jī)斷幀# v0 a  \5 N  Q7 K" r7 K( c) M: l5 ~
void UART_IRQHandler(void)  //作為485的接收中斷
9 j: @4 W0 |# {7 D{- y2 E* @) t: K4 K
    uint8_t count = 0;
# W7 z1 I8 {8 p& [# y8 T! }( _    unsigned char lRecDat = 0; ! [4 d" a8 _0 J) v% \* ?. ?

+ Z, F' I. m2 V8 D7 \. m; |8 h    if(/*觸發(fā)接收中斷標(biāo)志*/)  9 y# z' n6 I: b8 t
    {3 y, p3 u8 n" C2 w
        //清中斷狀態(tài)位+ c2 V% [, |- B" b7 x4 `% h
        rec_timeout = 5;
$ }& Y/ A/ w, `        if((count == 0)) //接收數(shù)據(jù)頭,長(zhǎng)度可以自定義* z" c, i2 ]! J3 S
        {
. d0 ^" F  [/ J3 U5 V( F            RUart0485_DataC[count++] = /*串口接收到的數(shù)據(jù)*/;
, W: m) x; X7 }5 b; k            gRecStartFlag = 1;
6 i/ u& j' f" @% P            return;; P* z0 Z' E: X$ N: R, R: G6 u9 i* b
        }- t: X. u* B) t( f0 w
        if(gRecStartFlag == 1). H, O2 S4 x# u$ I
        {1 m: t& S2 g* T) J. F: n: T
            RUart0485_DataC[count++] = /*串口接收到的數(shù)據(jù)*/;# j. ^$ y2 c2 a( N
        
9 f# o; z" Q# e& l: ~            if(count > MAXLEN) //一幀數(shù)據(jù)接收完成& Y- a4 g! L  v
            {
0 ^3 W* O3 e" C                count=0;
& x: P7 T6 R7 x1 @3 q                gRecStartFlag = 0;
2 d  ~- G; h. D9 q) U, m6 c: f               
% [2 h4 Z# s0 t5 n1 J                if(RUart0485_DataC[MAXLEN]==CRC16(RUart0485_DataC,MAXLEN))0 H6 w. l1 p& |9 R0 J" D# F. M: f
                {) \+ m) w* e  @
                    memcpy(&gRecFinshData,RUart0485_DataC,13);
' W0 {. _( C# N% [/ _; C# U' B9 t                    gRcvFlag = 1; //接收完成標(biāo)志位                    
8 F8 m3 t# `* ?5 B* j6 f' L                }8 u% C: m& r( i" B% a4 z
            }   ; S7 X, ?+ m/ K$ `8 a% Q& ]6 N
        }9 l7 R$ u* u, l- I
        return;
& j1 C  E4 n0 j    }2 }( ?6 f; Z- u8 Y
    return ;2 \" j3 [, }8 j2 y1 R4 X7 M
}這種做法適合用在一直有數(shù)據(jù)接收的場(chǎng)合,每次接收完一幀有效數(shù)據(jù)后就把數(shù)據(jù)放到緩沖區(qū)中去解析,同時(shí)還不影響下一幀數(shù)據(jù)的接收。
+ Q& P! ?' _+ T整個(gè)接收狀態(tài)分為兩個(gè)狀態(tài)——接收數(shù)據(jù)頭和接收數(shù)據(jù)塊,如果一幀數(shù)據(jù)存在多個(gè)部分的話還可以在此基礎(chǔ)上再增加幾種狀態(tài),這樣不僅可以提高數(shù)據(jù)接收的實(shí)時(shí)性,還能夠隨時(shí)看到數(shù)據(jù)接收到哪一部分,還是比較實(shí)用的。  K5 S5 t/ ~9 K& H8 `8 F
"狀態(tài)機(jī)+FIFO"斷幀記得剛畢業(yè)面試的時(shí)候,面試官還問過我一個(gè)問題:如果串口有大量數(shù)據(jù)要接收,同時(shí)又沒有空閑幀中斷你會(huì)怎么做?
1 D; U' s" y8 t: t- g; h! l沒錯(cuò),就是FIFO(當(dāng)時(shí)并沒有回答上來,因?yàn)闆]用過),說白了就是開辟一個(gè)緩沖區(qū),每次接收到的數(shù)據(jù)都放到這個(gè)緩沖區(qū)里,同時(shí)記錄數(shù)據(jù)在緩沖區(qū)中的位置,當(dāng)數(shù)據(jù)到達(dá)要求的長(zhǎng)度的時(shí)候再把數(shù)據(jù)取出來,然后放到狀態(tài)機(jī)中去解析。當(dāng)然FIFO的使用場(chǎng)合有很多,很多數(shù)據(jù)處理都可以用FIFO去做,有興趣的可以多去了解一下。/********************串口初始化省略,華大mcu hc32l130******************/: q4 Z1 ^- [5 U7 }* N  e0 q& S" p
void Uart1_IRQHandler(void)
- E6 L; a# d. f5 o* i( M; G0 S{
! w- Y3 G* z2 m    uint8_t data;/ X5 F% e2 l$ R9 n
    if(Uart_GetStatus(M0P_UART1, UartRC))      //UART0數(shù)據(jù)接收
# ^" W: n, ?$ g7 k    {
1 o$ H! t% O! M9 m+ k+ B        Uart_ClrStatus(M0P_UART1, UartRC);    //清中斷狀態(tài)位* b( f* M& @( d8 \* |/ J
        data = Uart_ReceiveData(M0P_UART1);   //接收數(shù)據(jù)字節(jié)
5 o9 {4 l7 D% w  {$ L/ @        comFIFO(&data,1);
3 M/ v, L! q$ I% ^" j) `  B! Y    }
4 a& I" @2 b/ _4 k}
# F: _7 }6 A1 H2 o+ {
3 a, p. f3 N9 l) T/******************************FIFO*******************************/
9 \( {! {0 D2 a2 B$ dvolatile uint8_t     fifodata[FIFOLEN],fifoempty,fifofull;
- s. r" p8 f! K$ Q, x8 w& svolatile uint8_t     uart_datatemp=0;! N# W. S( g6 O+ a" p

1 F9 o* @1 `6 k1 B6 u7 g( T1 ?uint8_t comFIFO(uint8_t *data,uint8_t cmd)( |! w) T7 B- Y8 E; }. s
{
& a# M1 f0 a5 B7 s9 ~! g% g    static uint8_t rpos=0;  //當(dāng)前寫的位置 position 0--99
) p8 e( V$ Y8 }4 J    static uint8_t wpos=0; //當(dāng)前讀的位置2 _# d# o% ?4 L5 H9 S& q) ?

  v4 h* e4 `2 `    if(cmd==0) //寫數(shù)據(jù)
* e4 r4 `( ~; J, v7 J1 a" T! J    {
+ \8 V8 M  Y1 O. A        if(fifoempty!=0)       //1 表示有數(shù)據(jù) 不為空,0表示空6 B4 R9 ?$ {4 K4 I# {
        {7 G+ s3 ^/ K! T  h% C7 s* q
            *data=fifodata[rpos];5 p+ c1 P& D/ A  K  W2 ~
            fifofull=0;
' Q/ Y, [/ I5 F5 T            rpos++;) m# v, d: Q# T9 {4 _
            if(rpos==FIFOLEN)
3 [' W* O5 k) I  c# k' x( d: O* ]                rpos=0;
8 r& y* B) y- f            if(rpos==wpos) + }* L* u0 I& t( g
                fifoempty=0;
0 x0 e% O& D! X, c5 ], G            return 0x01;
4 y6 ^1 [8 T! z' y        }
% L3 c6 P4 d# i3 b6 b        else
$ y; e. a$ {- `, S) a$ X4 e            return 0x00;
6 I, W7 s% |" t  L9 ^; e' z- F
+ U( Q3 f/ Y5 h    }
- l+ U  S' M( S' r, b: Q    else if(cmd==1) //讀數(shù)據(jù)! ?3 j* S; }2 {2 ]7 I/ m; }
    {
9 b# k3 m1 \5 B* D        if(fifofull==0)( l, H0 Q7 N/ ?
        {
3 _. c8 ?: i  X' T# ^7 r            fifodata[wpos]=*data;
: O* `/ a& F- E            fifoempty=1;6 T; X. G  j7 y
            wpos++;, p# J  u: c4 E; ?! b3 O
            if(wpos==FIFOLEN) ; n) |) s% v; p9 N" V3 i
                wpos=0;5 t: t' u" a5 `
            if(wpos==rpos) % A3 R5 {$ s  k  ]
                fifofull=1;: u) K6 ^  l0 Q+ d) j
            return 0x01;0 @+ }2 h1 \# y% ]. ^  N& y* `& q) k
        } else( `, U: N; p7 F' O1 A6 [- D3 a0 f
            return 0x00;. E5 ?6 W4 s$ T1 \3 c
    }& o7 I$ F- h* c" Q0 E  Q
    return 0x02;; p" k5 {, K+ t  x$ s$ r
}- n* V% j  ]5 U% _

+ F' H) C) O7 ~( e! Z, l/********************************狀態(tài)機(jī)處理*******************************/
3 |# x& E8 X: p6 U- V% ?* Avoid LoopFor485ReadCom(void)+ V) F" g% t5 J# Z5 E
{/ ?$ H& e* K# c8 F6 m
    uint8_t data;
% s1 i9 f: e' l( p$ v! \" k; V, g
" `: F* i' f4 K) w$ G    while(comFIFO(&data,0)==0x01)
- W8 c2 p+ f' A0 x3 y7 H0 X    {0 W( _# V5 I* ?" c2 V4 N
        if(rEadFlag==SAVE_HEADER_STATUS) //讀取頭: @6 }- a% p) F0 i8 v6 A
        {6 D# E' Y  ]; L8 ?2 t8 ^9 h
            if(data==Header_H)
, E0 Q& _) R1 Y7 W; X            {: m- Z% A& _  p4 S8 W3 t6 e
                buffread[0]=data;
; @, \6 q2 J" `  N0 q  b                continue;( x  o. O) t: Q1 q* M
            }/ n- X7 w" J3 o+ o) w2 f8 H- z
            if(data==Header_L)7 K6 j& H6 y0 I
            {
) E2 m1 q9 g9 M5 C' M                buffread[1]=data;
, I6 c1 P. R) F5 g# \6 A$ b* n                if(buffread[0]==Header_H)
/ J9 u5 {" s9 {; n8 x6 I3 o                {
  R2 m" s. f- N! s' N) n7 p                    rEadFlag=SAVE_DATA_STATUS;+ M3 f( U& r, y9 J( Y
                }
5 G( r" u$ a8 g6 f            }
0 ~& Y7 U5 V- q1 a: i8 F3 d: q1 A. J            else0 N3 O- d( N: l  W
            {
6 o+ i0 C# P3 B( N1 L                memset(buffread,0,Length_Data);& d8 s4 s: l8 L. @: t$ M
            }8 b5 E7 s7 u% w
        }
/ ^) i: |* j* R" z( U        else if(rEadFlag==SAVE_DATA_STATUS)  //讀取數(shù)據(jù)
0 i4 q. ?& d3 E& ^+ ]: w        {
4 H' _5 v# j! `6 b/ a            buffread[i485+2]=data;
  J5 q0 e8 h4 u" O% F& {5 c8 E            i485++;
& _  a5 z% o! ?! C& k. ~            if(i485==(Length_Data-2)) //數(shù)據(jù)幀除去頭* v  U3 b7 {% q9 b  A  r  y: \
            {
' P6 o6 n' q7 L2 L, d9 H0 }0 u6 \                unsigned short crc16=CRC16_MODBUS(buffread,Length_Data-2);
. ]* b; L# G1 ?+ _+ h- J                if((buffread[Length_Data-2]==(crc16>>8))&&(buffread[Length_Data-1]==(crc16&0xff)))
4 b6 y, i1 |0 L                {8 Z/ P" n/ _, {8 v$ m
                    rEadFlag=SAVE_OVER_STATUS;
; b8 c. @% N- z* t1 h/ B5 q                    memcpy(&cmddata,buffread,Length_Data);  //拷貝Length_Struct個(gè)字節(jié),完整的結(jié)構(gòu)體7 u, y! j3 Y- F" F) V8 G* i
                }
' O6 @: t- t# h1 [/ X9 Q' Y$ T                else
8 z: @9 U+ Q6 i) m) d7 h. s0 h: H                {
9 x; A1 N0 b7 c3 k$ E( w! R" f+ ?/ h- j                    rEadFlag=SAVE_HEADER_STATUS;
% h+ I/ y9 t: h# a6 F                }
; v+ |5 T; q: P8 s* @5 }        
# V  n1 i/ i- z( _# f                memset(buffread,0,Length_Data);
/ \! A! s5 O+ K% `( p9 a- u5 D                i485=0;
% g$ ]+ K2 K6 n1 O/ B) A                break;7 h2 o  w  U" d4 ]
            }) U  ], Q2 I' S+ Z2 r" `
        }
  ]5 H$ E. s% [+ ?& w    }
3 Z2 w, w1 K3 C, u$ f$ B  f}原文:https://blog.csdn.net/qq_56527127/article/details/123018515
$ n; G' o4 d7 V' D" e7 h/ s
( z" y* g2 w2 \2 N-END-! Q8 g$ T$ U! R
往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀
0 D) O( m- a7 P" Y" m' ]$ u4 j& E! C+ F" J
                                                        * c5 e( F' D- o( P- X
                                                               
' ]1 s+ u4 R5 I6 z                                                                        5 a3 |- X: @  C+ e
                                                                                4 @; _5 ]3 d- x, c" t  ]5 @8 Y: h
9 I2 z3 t; I! j2 T2 P4 b" o
                                                                                7 T) f9 h3 s  \& H& d
                                                                                        嵌入式軟件調(diào)試,如何計(jì)算任務(wù)的運(yùn)行周期?, i; S. i9 L! ?: O( b
                                                                                ; ?' s! ]3 L( O3 p
                                                                        # H6 _& X  E, n" w! n4 ?; f& b
                                                                & t; x/ Y- C7 j* n0 S% f
                                                       
1 [; h1 L$ a% N                                               
+ Q% I* v5 k4 _4 }& ^1 T# v, j* n3 G  n1 p6 a- D4 J9 t
                                                       
. _& A& P' b( S                                                                  E0 _/ i8 ?  A2 A. r+ i9 i
                                                                       
) |8 a5 r, [8 S& d                                                                                7 H  e7 n! z/ m/ M6 N9 f5 T: q
' C' }( r1 w" `1 a4 ^
                                                                                ; Z2 \9 ^7 s* C% C! Z0 a
                                                                                        嵌入式軟件,如何把編譯時(shí)間加入到bin文件,進(jìn)行版本管理?4 ?& t2 ~1 F" D; v
                                                                               
( u+ J& q5 ~9 a& R5 t9 C& }# `& r                                                                        3 E5 l. b" {$ q
                                                               
2 T, p% i2 T& W% }& l- D                                                        % }( Z1 g$ s: O7 r: w+ p5 C/ p
                                                % [% A# u( q5 A- h  e

. w1 g, p% X8 P$ a1 C( ]) m! |                                                        2 r6 u3 t# F7 p- M5 i
                                                               
4 n* Y; V* ~# k8 l/ @+ O                                                                       
( N$ S" W! X: W& E                                                                               
0 y7 X2 D& N7 }, i' H7 I% d ) g1 l9 e1 [, j- @
                                                                               
. ]& z$ V  D( P( G1 L0 ^                                                                                        嵌入式初學(xué)者入門后,應(yīng)該如何開始進(jìn)階學(xué)習(xí)?& }( o8 b$ r. q/ A3 \, _
                                                                                % }( o5 N2 W  b* h8 V
                                                                        0 z$ v% n, y" o; Z; _
                                                               
7 e; ]9 f+ g/ ~1 d6 k                                                       
# D; j6 k/ l% ^0 Y; L* Y                                                # |! j6 G" y) J2 r  [- i. n
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
0 U  e& j7 R0 D. B+ O  w關(guān)注我,一起變得更加優(yōu)秀!

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

本版積分規(guī)則


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