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

歷史上的今天

今天是:2024年09月24日(星期二)

正在發生

2019年09月24日 | USART_ClearITPendingBith和 USART_ClearFlag的區別

發布者:開元軒 來源: eefocus關鍵字:USART_ClearITPendingBith  USART_ClearFlag  區別 手機看文章 掃描二維碼
隨時隨地手機看文章

起初

stm32 v3.5 庫函數里面,對于串口USART有這樣兩個函數:

                USART_ClearFlag()和USART_ClearITPendingBit()



查庫函數定義,說一個是清除標志,一個是清除中斷預處理位。然后我看了stm32f10x_usart.c文件,發現兩個函數都操作的是USART->SR寄存器,但是這個寄存器只有一組標志位,沒有什么中斷預處理位。。


實際上兩個函數實現的功能是一樣的,都是清除相對應的標志位,只是標志位和中斷位含義不一樣,是標志位但

是不一定會產生中斷。例如:

#define USART_IT_TXE                         ((uint16_t)0x0727)

#define USART_IT_TC                          ((uint16_t)0x0626)

#define USART_IT_RXNE                        ((uint16_t)0x0525)

這是中斷位,可以產生中斷

 

#define USART_FLAG_TXE                       ((uint16_t)0x0080)

#define USART_FLAG_TC                        ((uint16_t)0x0040)

#define USART_FLAG_RXNE                      ((uint16_t)0x0020)

這是標志位,有的標志位不能產生中斷

 

標志位在程序中可以作為判定條件,支持程序的運行,中斷則是跳轉到中斷函數執行。兩個函數實現的功能是一

樣的,在中斷程序中可以用兩個中的任一個。我想區分兩個函數是為了更清晰吧。

還有

#define USART_IT_TC                          ((uint16_t)0x0626)

#define USART_FLAG_TC                        ((uint16_t)0x0040)

 

這兩個數值不同是因為標志位只是為了清除標志位而設的,而中斷位設置成這個值是因為在其他函數中這一位還

有其他用途。而且還要注意:

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));

  assert_param(IS_USART_PERIPH_FLAG(USARTx, USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */   

   

  USARTx->SR = (uint16_t)~USART_FLAG;

}

 

 這一步 USARTx->SR = (uint16_t)~USART_FLAG; 似乎應該是  USARTx->SR &= (uint16_t)~USART_FLAG;

其實狀態位只能有硬件置位,軟件只能讀和清零,所以這樣寫也是正確的。

沒有很明白,所以轉在這里,等我哪天靈光乍現了,再來加上我的理解

上面的內容是別人的,我略作修改,下面的內容是我原創。不知道本文到底是屬于原創還是轉載,但是......我的更簡潔、精辟


 -----------------------------------------------------------------------------------------------------------------------


靈光乍現了

我是在使用TC的時候遇見這個問題的,所以這里就只分析TC這個位


先研究簡單點的USART_ClearFlag函數


//調用形式

USART_ClearFlag(USART3,USART_FLAG_TC);

 

//USART_FLAG_TC的定義

#define USART_FLAG_TC               ((uint16_t)0x0040)

 

//USART_ClearFlag函數的原型

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));

  assert_param(IS_USART_PERIPH_FLAG(USARTx, USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */   

   

  USARTx->SR = (uint16_t)~USART_FLAG;

}

一目了然,最后USARTx->SR = ~(0100'0000);


再來研究復雜點的USART_ClearITPendingBit函數(注意,這兩個函數的第二個參數,是不一樣的)


//調用形式

USART_ClearITPendingBit(USART3,USART_IT_TC);

 

//USART_IT_TC的定義

#define USART_IT_TC           ((uint16_t)0x0626)//=0000'0110'0010'0110

 

//USART_ClearITPendingBit的函數原型

void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)

{

  uint16_t bitpos = 0x00, itmask = 0x00;

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CLEAR_IT(USART_IT));

  assert_param(IS_USART_PERIPH_IT(USARTx, USART_IT)); /* The CTS interrupt is not available for UART4 and UART5 */

  

  bitpos = USART_IT >> 0x08;                     //=0000'0110

  itmask = (uint16_t)((uint16_t)0x01 << bitpos); //=0100'0000

  USARTx->SR = (uint16_t)~itmask;                //=~(0100'0000)

}

可以看到最后還是USARTx->SR=~(0100'0000);


對比一下USART_ClearFlag和USART_ClearITPendingBit的參數

image.png

USART_ClearFlag的參數 USART_ClearITPendingBit的參數

USART_FLAG_CTS    = 0x0200 USART_IT_CTS   = 0x096A

USART_FLAG_LBD    = 0x0100 USART_IT_LBD    = 0x0846

USART_FLAG_TC      = 0x0040 USART_IT_TC      = 0x0626

USART_FLAG_RXNE = 0x0020 USART_IT_RXNE = 0x0525

這里可以發現一個規律USART_ClearFlag參數只有一個位是“1”,其位置正好等于USART_ClearITPendingBit的參數左移八位后的結果,所以這里可以非常非常肯定的講:函數USART_ClearFlag和函數USART_ClearITPendingBit的功能totally一樣


----------------------------------------------------------------------------------------------------------------------------


涉及內容擴展:

STM32的USART發送數據時如何使用TXE和TC標志


在USART的發送端有2個寄存器,一個是程序可以看到的寄存器——發送數據寄存器(通過USART_DR查看),另一個是程序看不到的寄存器——發送移位寄存器,對應的有兩個USART數據發送標志,一個是TXE=發送數據寄存器空,另一個是TC=發送移位寄存器空。

(這粗箭頭和這細箭頭,簡直不要太形象哦,粗箭頭是八位八位的傳,細箭頭是一位一位的傳)


    當USART_DR中的數據傳送到移位寄存器后,TXE被設置,此時移位寄存器開始向TX信號線按位傳輸數據,但因為TDR已經變空,所以程序可以把下一個要發送的字節(操作USART_DR)寫入TDR中,而不必等到移位寄存器中所有位發送結束,所有位發送結束時(送出停止位后)硬件會設置TC標志。


  另一方面,在剛剛初始化好USART還沒有發送任何數據時,也會有TXE標志,因為這時發送數據寄存器是空的。TXEIE和TCIE的意義很簡單,TXEIE允許在TXE標志為'1'時產生中斷,而TCIE允許在TC標志為'1'時產生中斷。


  至于什么時候使用哪個標志,需要根據你的需要自己決定。但我認為TXE允許程序有更充裕的時間填寫TDR寄存器,保證發送的數據流不間斷。TC可以讓程序知道發送結束的確切時間,有利于程序控制外部數據流的時序。

image.png


三種發送方法

1、不開發送完成中斷:

/*******************************************************************************

* 函數名  : UART1_SendString

* 描述    : USART1發送字符串

* 輸入    : *s字符串指針

* 注釋    :0==RESET,表示發送還未完成

USART_FLAG_TC!=RESET,就是=SET,表示發送完成,此時執行USART_GetFlagStatus會把USART_FLAG_TC清零(未證實)

*******************************************************************************/

void UART1_SendString(u8* s)

{

  while(*s)//檢測字符串結束符

  {

   //USART_FLAG_TC==RESET時,表示發送還未完成。

    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 

    USART_SendData(USART1 ,*s++);//發送當前字符

  }

}

2、開中斷,額外設置一個標志:

u8 FLAG_TC=0;//定義全局變量

/*******************************************************************************

* 函數名  : UART1_SendString

* 描述    : USART1發送字符串

* 輸入    : *s字符串指針

*******************************************************************************/

void UART1_SendString(char* s)

{

  FLAG_TC=0;//提前準備一下

  while(*s)//檢測字符串結束符

  {

    USART_SendData(USART1 ,*s++);//發送當前字符

    while( FLAG_TC==0); //0:發送還未完成;1:發送完成

    FLAG_TC=0;

  }

}

 

 

void USART1_IRQHandler(void)

{

  if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)//發送完成中斷,= SET

  {

    USART_ClearITPendingBit(USART1,USART_IT_TC);

    FLAG_TC=1;

  }

}

 


開中斷時,就不能通過簡單的判斷標志位USART_FLAG_TC的狀態去決定能否發送下一個字符。比方說,使用 


while(*s)

{

 

   USART_SendData(USART1 ,*s++);//發送字符

 

   while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 

 

   ...

}

執行完發送字符的語句后,因為不可能這么快完成發送,所以程序接下來執行的是while語句。在等待期間,字符發送完畢,這時就會進入到中斷,如果在中斷里清除標志位,退出中斷后,標志位USART_FLAG_TC仍然是RESET;如果不在中斷里清除標志位,就不能退出中斷。所以程序就會死在while里。


所以這里就需要額外設置一個標志。


3、開中斷,數據發送由函數啟動,在中斷里完成:

//定義全局變量。也可以為了簡化,把這四個參數結合起來包含在一個結構體里

u8 TxLength;   //發送數據長度

u8 TxIndicator;//發送指示器,表示目前發送完成哪一位了,下面要發送的是第(TxIndicator+1)位

u8 TxBuff[256];//Data 

u8 TxFnd;      //發送完成標志

     

/*************************************************************************

*程序名稱    :   SendFirstByte

*功能        :   啟動發送第一個字節

*@Notes     :   雞賊啊,剩下的都放在USART_FLAG_TC中斷里面,因為這個中斷是

                 發送完成中斷,是利用“發送第一個字節”來“啟動發送”

*@Notes     :   需要注意,如果發送結果是亂碼的話,一種供參考的解決方案是

                把數據直接賦值給TxBuff,而不要通過函數的形參傳遞

*輸入參數    :   u8 txbuf[]: 需要發送的數據,u8 len : 數據中的字節數

*返回值      :   無

*************************************************************************/

void SendFirstByte( u8 txbuf[], u8 len )

{

TxBuff      = txbuf;//需要發送的數據

TxLength    = len  ;//發送數據長度

TxIndicator = 1    ;//0已經發送,也是用來啟動發送的

 

USART_SendData(USART1, txbuf[0]);  /**@Notes:只發送了txbuf的第一個字節*/

}

 

/*************************************************************************

*程序名稱    :   USART1_IRQHandler

*功能        :   完成發送數據   

*************************************************************************/

void USART1_IRQHandler(void)

{

if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)

{

USART_ClearITPendingBit(USART1,USART_IT_TC);

if( TxIndicator < TxLength  )//數組的索引max永遠小于數組元素的個數

{

USART_SendData(USART1, TxBuff[TxIndicator++]);

}

else//最后一字節數據發送完成

{

TxFnd = 0;

TxIndicator = 0;

}

}

}

USART收發過程中常遇問題總結:

Q:為什么使用USART發送一串字符,最后自接收到了最后一個?

A:是因為發送的間隔太短了,可以在發送每個字符之前先判斷一下上一個字符是否發送完成,可以參考上面的“三種發送方法”


Q:為什么使用USART發送一串字符,有時候接收不到第一個字符,有時候又可以接收得到?

A:解決方案是把判斷能否發送的語句放在發送數據之前

關鍵字:USART_ClearITPendingBith  USART_ClearFlag  區別 引用地址:USART_ClearITPendingBith和 USART_ClearFlag的區別

上一篇:stm32串口的flag和it標志位
下一篇:STM32F1x系列——外部中斷

推薦閱讀

工業機器人何時才能實現“國產化”?我想這個問題換成“國產核心零部件何時才能崛起”可能更貼切些。長久以來,核心零部件的缺失始終是橫在工業機器人國產化道路上的一塊大石,國產零部件廠家也一直是在夾縫中求生存,盡管發展緩慢,但近年來隨著政府政策支持,資本的進入,國產核心零部件也取得了一些突破。國產主要減速機企業一覽表可以看出,目前國內主...
根據IT專業調查公司IDC統計,2018年全球可穿戴市場增長了27.5%,手表、手環、智能耳機等的銷量達到1.722億臺。在中國市場,預計2022年可穿戴設備將達到1.1億個的規模。常見的可穿戴類產品有健康類產品,此外還有運動類、定位類產品,以及一些具體場景里的智能設備,能夠判斷我們的情境和活動。近日TDK集團的專家接受了《電子產品世界》的采訪,介紹了TDK的...
在我的上一篇博客中我介紹了利用Zynq SoC上的兩個ARM Cortex-A9 MPCore處理器執行不同的任務程序,實現非對稱的多進程處理模式的概念。我期望你能坐得住因為這篇博客有點長,但是我們會有收獲,到最后我們會讓我們的AMP系統啟動并運行,在我們實現AMP系統啟動并運行之前會進行很多步的準備工作,但是這些都非常的簡單所以不用擔心。在Zynq SoC上搭建AM...
MPU6050,x軸俯仰的范圍是0-360°,有時候安裝的時候會出現0負的情況,即陀螺儀顯示的是300+的形式,而假如程序ZHONGZHI也寫300+,車是不知能直立的!請教ZHONGZHI的范圍是這個時候可以試試改成負值,就對了。

史海拾趣

問答坊 | AI 解惑

請教一下wince6.0 USB端口識別的問題。

目前采用telechips的8900,板子上有一個1.1的HOST和2.0的OTG,目前需要做一個需求,就是當u盤插入的時候,能夠識別出插入的是1.1的端口還是2.0的,telechips大部分代碼提供的是靜態庫, 目前有什么方法可以實現?把usb的控制器值打印了一部分出來, ...…

查看全部問答∨

關于微軟的提供的WINCE SDK

  準備在PDA上開發一個簡單的程序,不打算自己定制wince SDK,看見參考書上的有微軟提供的Pocket PC 2003,打算用這個,但是上了微軟的網站,沒有找到,書是2006版,可能變化太快了,只找到了一個pda SDK 1.1,本人是新手,誰能解釋一下, ...…

查看全部問答∨

Nios IDE 運行中的一個錯誤

IDE 中LED 跑馬燈的程序運行時總是出現 nios2-terminal: connected to hardware target using JTAG UART on cable nios2-terminal: "USB-Blaster [USB-0]", device 1, instance 0 nios2-terminal: (Use the IDE stop button or Ctrl-C to te ...…

查看全部問答∨

vxworks下串口操作

本人菜鳥,剛接觸vxworks,在vxworks下進行2路串口通信 使用tty0,tty1等方式open 并調用read函數讀取串口數據 現在不知道何時串口收到數據,所以調用read函數一直停在那,請問如何讀取串口數據可以避免死循環?(由于限制,不考慮單獨起任務讀 ...…

查看全部問答∨

stm32f103的SPI通訊問題

拜問下 大蝦們 SPI1 和 SPI2 都設定為雙線雙工 , SPI1 主 SPI2 從   在 通訊的時候 SPI1 向 SPI2 發送數據 SPI2 能接收 但是&nbs ...…

查看全部問答∨

STM8S103的讀保護讓我瘋了

給客戶做了6個樣板,用STVP燒錄了軟件,選擇了READONLY保護選項。 前幾天客戶把6個板子送過來要修改。結果發現有4塊板子是正常,但是有2塊板子的讀保護沒有了,代碼通過STVP輕松讀出來了。 真暈啦。這樣的問題竟讓讓我遇到…

查看全部問答∨

仿真28335需要什么仿真器

聽說能支持28335仿真的仿真器很少,想咨詢下這方面的。 準備過一段時間購買一套。…

查看全部問答∨

這是最后一篇了,五精華無懸念:STM32的IAP方案

replyreload += \',\' + 1110631;STM32的IAP方案          幾乎所有的同類書籍都介紹綜合性的應用示例如“萬年歷 + 溫度顯示 + 鬧鐘響鈴 + 計時表”這樣的一個實時時鐘范例或“STM32 + 音頻解碼 + 大容 ...…

查看全部問答∨

LED應用-1 線控制 & AN033

本帖最后由 dontium 于 2015-1-23 13:13 編輯 LED應用手冊   1 線控制 – 省去 LED 驅動器的微處理器控制 AN033 -- 將射頻閃光 LED 軟件示例轉換為 CC2420 - MSP430(修訂版 A)   超實用的,快來看啊~~~ …

查看全部問答∨

在FPGA非正弦信號的有效值計算?

本人由于項目需求,需要在求含有比較多諧波的數字正弦波信號的有效值。目前我想到的方式,采集信號進行高次諧波過濾,求基波的平均值,然后求有效。在FPGA中實現,占用的資源比較多,特別是采集信號的路數較多的情況下。請教各位大蝦,在FPGA中求有 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 泰顺县| 剑川县| 文登市| 景洪市| 长子县| 吴忠市| 寿阳县| 平武县| 东丰县| 麻栗坡县| 新化县| 高碑店市| 罗田县| 大连市| 樟树市| 嘉峪关市| 红原县| 灵丘县| 东宁县| 泸溪县| 紫金县| 博客| 万载县| 龙海市| 精河县| 丹东市| 桦甸市| 南昌县| 嘉荫县| 南召县| 拉孜县| 古田县| 依安县| 长岛县| 石棉县| 丁青县| 娱乐| 康定县| 桐城市| 武平县| 桓仁|