新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > stm32的USART_IT_TXE和USART_IT_TC

        stm32的USART_IT_TXE和USART_IT_TC

        作者: 時間:2016-12-03 來源:網絡 收藏
        一般來說,串口的發送中斷傳輸數據,對于我目前的應用來說,應用的要求并不是很高,因此,因此就一直沒有對其進行一個比較好的實驗與認識。然而,在一次串口程序升級(IAP)升級實驗中,發現有人使用了這個發送中斷方式進行的,所以特別的進行了一個個步驟的實驗來進一步知道其運行機理。

        首先,串口發送數據,可以使用的方式有:

        本文引用地址:http://www.104case.com/article/201612/325196.htm

        1、發送一個數據,然后讀取USART_IT_TXE或者USART_IT_TC寄存器的狀態。

        2、使用串口發送中斷

        3、使用dma發送完成中斷

        在效率上,肯定是3比較好。其次是2。

        網上關于USART_IT_TXE和USART_IT_TC是怎么個用法,各家有各家的言論,在我這里只通過實驗來了解,因為網上的很多人的講解是有一些歧義的。

        本人用的芯片為stm32f103vet6,利用串口1進行實驗,先貼上串口1的配置部分:

        void USART1_Config(void)

        {

        GPIO_InitTypeDef GPIO_InitStructure;

        USART_InitTypeDef USART_InitStructure;

        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /* Configure USART1 Rx (PA.10) as input floating */

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

        GPIO_Init(GPIOA, &GPIO_InitStructure);

        USART_InitStructure.USART_BaudRate = 115200;

        USART_InitStructure.USART_WordLength = USART_WordLength_8b;

        USART_InitStructure.USART_StopBits = USART_StopBits_1;

        USART_InitStructure.USART_Parity = USART_Parity_No ;

        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

        USART_Init(USART1, &USART_InitStructure);

        USART_Cmd(USART1, ENABLE);

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

        NVIC_Init( &NVIC_InitStructure );

        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

        USART_ITConfig(USART1, USART_IT_TC, ENABLE);

        }

        然后是中斷部分的實驗代碼:

        void USART1_IRQHandler(void)

        {

        if(SET == USART_GetITStatus(USART1, USART_IT_TXE))

        {

        USART_ClearITPendingBit(USART1, USART_IT_TXE);

        if(有數據)

        {

        }

        else

        {

        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

        USART_ITConfig(USART1, USART_IT_TC, ENABLE);

        }

        }

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

        {

        USART_ClearITPendingBit(USART1, USART_IT_TC);

        USART_ITConfig(USART1, USART_IT_TC, DISABLE);

        }

        }

        現在分析,在使能了串口1的功能后,明顯的是,串口就開始進入發送寄存器空狀態,也就是說if(SET == USART_GetITStatus(USART1, USART_IT_TXE))是成立的,如果沒有if判斷語句的話,也就是沒有if{}else{},那么就會一直在if(SET == USART_GetITStatus(USART1, USART_IT_TXE))中斷中,因此對于if(有數據)就需要在if(有數據){

        USART_SendData(USART1,數據);}了,一直等到沒有數據了,就進入關閉USART_GetITStatus(USART1, USART_IT_TC) != RESET與之同時,需要開啟USART_ITConfig(USART1, USART_IT_TC, ENABLE);讓其進入傳輸完成中斷。有人說,這個中斷是發送一個字節完成后中斷,這種理解十分的讓人有歧義,應該說,發送一個字節數據之后,如果后續還有數據,這個中斷是不會進去的,這個USART_GetITStatus(USART1, USART_IT_TC) != RESET;串口空閑相關。應該稍微準確的說法是,發送一個字節數據完成后,串口處于空閑狀態了,這個時候,會進入這個中斷。

        好了,如果把串口初始化完成了,這個時候,串口發送中斷都被禁止了,怎么去發送數據呢?

        發送數據,直接把USART_ITConfig(USART1, USART_IT_TXE, ENABLE);顯然是不夠的,需要通過USART_SendData(USART1,數據);然后開啟中斷。可以暫且看作是激活串口,但是過程應該是數據到達寄存器后,很快為空,進而產生if(SET == USART_GetITStatus(USART1, USART_IT_TXE))為真的條件,從而一切仍然能夠正常運行了。

        注意點:

        1、中斷流程

        2、再次發送數據,操作步驟。

        綜上,一個串口中斷發送數據的程序就可以明顯展開了。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 调兵山市| 巴马| 类乌齐县| 遵化市| 广昌县| 布拖县| 杭锦后旗| 原阳县| 类乌齐县| 南宫市| 东阿县| 洛宁县| 新密市| 宁陕县| 海南省| 思茅市| 洪江市| 临安市| 松溪县| 涡阳县| 建湖县| 寿阳县| 姚安县| 建始县| 呼伦贝尔市| 炎陵县| 松桃| 安福县| 法库县| 宝鸡市| 多伦县| 蒲江县| 南投市| 松江区| 兖州市| 仁布县| 海晏县| 股票| 健康| 南开区| 奇台县|