本文以USART1爲例,敘述串口中斷的編程過程。編程
1、先來說述一下在應用串口中斷時涉及到的一些庫文件。數組
首先對於STM32外設庫文件的應用編程,misc.c和stm32f10x_rcc.c是確定要添加到。函數
接下來就是咱們要用到的相關外設了。毫無疑問,串口文件stm32f10x_usart.c是必須的。串口通訊是對通用GPIO端口引腳的功能複用,因此還須要stm32f10x_gpio.c文件。另外,由於有中斷的產生,因此中斷文件stm32f10x_it.c也是必要的,固然這個文件通常和main.c放在一個文件夾下(通常習慣爲User文件夾),由於咱們的中斷響應函數是要在裏面本身編寫的。spa
固然還有其餘的基本必須文件如系統配置文件等在這地方就不說了,這個是建立一個工程應該知道的。orm
2、初始化ip
對於串口通訊的初始化,不單單只是對串口的初始化(這個地方是比較煩人的,不像別的芯片那樣簡潔明瞭)。字符串
l 首先時鐘使能配置。STM32內部的時鐘有不少,感興趣的本身看看參考手冊。此處以USART1爲例說明。有USART1時鐘、GPIOA時鐘、GPIO複用(AFIO)時鐘。因爲此處USART1和GPIOA、AFIO均在APB2上,因此能夠一次配置完成。以下:it
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1 ,ENABLE);io
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)//等待中斷
{
}
}