STM32 串列埠中斷總結
本文以USART1為例,敘述串列埠中斷的程式設計過程。
1、先來講述一下在應用串列埠中斷時涉及到的一些庫檔案。
首先對於STM32外設庫檔案的應用程式設計,misc.c和stm32f10x_rcc.c是肯定要新增到。
接下來就是我們要用到的相關外設了。毫無疑問,串列埠檔案stm32f10x_usart.c是必須的。串列埠通訊是對通用GPIO埠引腳的功能複用,所以還需要stm32f10x_gpio.c檔案。另外,因為有中斷的產生,所以中斷檔案stm32f10x_it.c也是必要的,當然這個檔案一般和main.c放在一個資料夾下(一般習慣為User資料夾),因為我們的中斷響應函式是要在裡面自己編寫的。
當然還有其他的基本必須檔案如系統配置檔案等在這地方就不說了,這個是建立一個工程應該知道的。
2、初始化
對於串列埠通訊的初始化,不僅僅只是對串列埠的初始化(這個地方是比較煩人的,不像別的晶片那樣簡潔明瞭)。
l 首先時鐘使能配置。STM32內部的時鐘有很多,感興趣的自己看看參考手冊。此處以USART1為例說明。有USART1時鐘、GPIOA時鐘、GPIO複用(AFIO)時鐘。由於此處USART1和GPIOA、AFIO均在APB2上,所以可以一次配置完成。如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1 ,ENABLE);
l 其次中斷配置。主要有優先順序組設定、USART1中斷使能、該中斷的優先順序,中斷初始化。程式如下:
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//選擇分組方式0
/* 使能 USART1中斷 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
l 然後GPIO複用功能配置。一般情況下我們使用原始的外設和GPIO埠引腳的對映關係,如果要改變其對映的話,請另外檢視參考手冊上關於GPIO重對映部分。對於GPIO的複用,其引腳的輸入與輸出模式都有要求,在參考手冊上有詳細說明。
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 配置 USART1 Rx 作為浮空輸入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
/* 配置 USART1 Tx 作為推輓輸出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);
}
l 串列埠初始化配置。主要有串列埠基本引數配置(如波特率、資料位、工作方式等),串列埠中斷使能,串列埠使能。
(1) 基本引數配置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;//波特率
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);//用配置的引數驚喜串列埠初始化
(2) 串列埠中斷使能
USART_ITConfig(USARTy, USART_IT_RXNE, ENABLE);//使能接受中斷,在接受移位暫存器中有資料是產生
USART_ITConfig(USARTy, USART_IT_TXE, ENABLE);//使能傳送中斷,在傳送完資料後產生。
一般情況下,如果與PC通訊的話,我們只用接受中斷即可。
(3) 串列埠使能
USART_Cmd(USART1, ENABLE); //USART1使能
好了,經過以上不走之後呢,我們就可以進行資料的收發了。
3、傳送資料
使用函式USART_SendData(USART1, char data),一次只能傳送一個字元。當然我們可以用如下函式傳送字串。
void USART1_Puts(char * str)
{
while(*str)
{
USART_SendData(USART1, *str++); //傳送一個字元
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待發送完畢
}
}
當然我們也可以迴圈傳送字串陣列
for(i = 0; TxBuf1 != '\0'; i++) // TxBuf1為定義好的字串陣列
{
USART_SendData(USART2 , TxBuf1);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);
}
4、接收資料
由於我們使用的是接受中斷,所以當有資料需要接收時,會執相應的中斷函式。此處我們USART1的中斷函式在stm32f10x_it.c檔案中。找到函式void USART1_IRQHandler(void),如果沒有的話就自己加上吧,別忘了標頭檔案中需要宣告一下。當然你也可以在其他檔案中寫下該中斷函式。當產生中斷進入該函式之後,我們就可以進行自己的操作了。
void USARTy_IRQHandler(void)
{
if(USART_GetITStatus(USARTy, USART_IT_RXNE) != RESET)//如果暫存器中有資料
{
/* Read one byte from the receive data register */
RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);
}
/*************************************************************
if(USART_GetITStatus(USARTy, USART_IT_TXE) != RESET)
{
USART_SendData(USARTy, TxBuffer1[TxCounter1++]);
}
//這個地方那個之所以把這個寫出來主要是想說傳送中斷和接受中斷其實是共用一個
//中斷函式的,到底是那個中斷髮生了呢,這就需要我們讀取中斷狀態標誌來識別了。
*****************************************************************/
}
別忘了在接受完資料進行別的操作之前為了防止資料被覆蓋最好先禁止一下接受中斷/* 禁止 USART1接收中斷 */
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
/* 禁止 USART1傳送中斷 */
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
5、main函式
int main(void)//這個地方和特別,我們知道一般main函式是沒有返回值的,但在STM32//的程式設計中其返回型別為int。
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
USART_InitStructure.USART_BaudRate = 9600;
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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
while (1)//等待中斷
{
}
}
當然你也可以在main()中新增一些傳送指令之類的東西。
以上內容為個人總結,轉載請註明出處。若有錯誤,本人概不負任何責任。