stm32的USART_IT_TXE和USART_IT_TC
首先,串口發(fā)送數據,可以使用的方式有:
本文引用地址:http://www.ex-cimer.com/article/201612/325196.htm1、發(fā)送一個數據,然后讀取USART_IT_TXE或者USART_IT_TC寄存器的狀態(tài)。
2、使用串口發(fā)送中斷
3、使用dma發(fā)送完成中斷
在效率上,肯定是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的功能后,明顯的是,串口就開始進入發(fā)送寄存器空狀態(tài),也就是說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);讓其進入傳輸完成中斷。有人說,這個中斷是發(fā)送一個字節(jié)完成后中斷,這種理解十分的讓人有歧義,應該說,發(fā)送一個字節(jié)數據之后,如果后續(xù)還有數據,這個中斷是不會進去的,這個USART_GetITStatus(USART1, USART_IT_TC) != RESET;串口空閑相關。應該稍微準確的說法是,發(fā)送一個字節(jié)數據完成后,串口處于空閑狀態(tài)了,這個時候,會進入這個中斷。
好了,如果把串口初始化完成了,這個時候,串口發(fā)送中斷都被禁止了,怎么去發(fā)送數據呢?
發(fā)送數據,直接把USART_ITConfig(USART1, USART_IT_TXE, ENABLE);顯然是不夠的,需要通過USART_SendData(USART1,數據);然后開啟中斷??梢詴呵铱醋魇羌せ畲?,但是過程應該是數據到達寄存器后,很快為空,進而產生if(SET == USART_GetITStatus(USART1, USART_IT_TXE))為真的條件,從而一切仍然能夠正常運行了。
注意點:
1、中斷流程
2、再次發(fā)送數據,操作步驟。
綜上,一個串口中斷發(fā)送數據的程序就可以明顯展開了。
評論