STM32外部配置
USART作為一種標準介面在應用中十分常見。本文著重分析其作為UART的配置和應用方法。
1、STM32韌體庫使用外圍裝置的主要思路
在STM32中,外圍裝置的配置思路比較固定。首先是使能相關的時鐘,一方面是裝置本身的時鐘,另一方面如果裝置通過IO口輸出還需要使能IO口的時鐘;最後如果對應的IO口是複用功能的IO口,則還必須使能AFIO的時鐘。
其次是配置GPIO,GPIO的各種屬性由硬體手冊的AFIO一章詳細規定,較為簡單。
接著相關裝置需要如果需要使用中斷功能,必須先配置中斷優先順序,後文詳述。
然後是配置外圍裝置的相關屬性,視具體裝置而定,如果裝置需要使用中斷方式,必須使能相應裝置的中斷,之後需要使能相關裝置。
最後如果裝置使用了中斷功能,則還需要填寫相應的中斷服務程式,在服務程式中進行相應操作。
2、UART的配置步驟
2.1、開啟時鐘
由於UART的TX和RX和AFIO都掛在APB2橋上,因此採用韌體庫函式RCC_APB2PeriphClockCmd()進行初始化。UARTx需要分情況討論,如果是UART1,則掛在APB2橋上,因此採用RCC_APB2PeriphClockCmd()進行初始化,其餘的UART2~5均掛在APB1上。
2.2、GPIO初始化
GPIO的屬性包含在結構體GPIO_InitTypeDef,其中對於TX引腳,GPIO_Mode欄位設定為GPIO_Mode_AF_PP(複用推輓輸出),
以下是TX引腳設定的例項程式碼:
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = UART_TX_PIN[COM];
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(UART_TX_PORT[COM], &GPIO_InitStructure);
2.3、中斷優先順序的配置
這是STM32比較奇怪的地方,在只有一箇中斷的情況下,仍然需要配置優先順序,其作用是使能某條中斷的觸發通道。STM32的中斷有至多兩個層次,分別是先佔優先順序和從優先順序,而整個優先順序設定引數的長度為4位,因此需要首先劃分先佔優先順序位數和從優先順序位數,通過NVIC_PriorityGroupConfig()實現;
特定裝置的中斷優先順序NVIC的屬性包含在結構體NVIC_InitTypeDef中,其中欄位NVIC_IRQChannel包含了裝置的中斷向量,儲存在啟動程式碼中;欄位NVIC_IRQChannelPreemptionPriority為主優先順序,NVIC_IRQChannelSubPriority為從優先順序,取值的範圍應根據位數劃分的情況而定;最後NVIC_IRQChannelCmd欄位是是否使能,一般定位ENABLE。最後通過NVIC_Init()來使能這一中斷向量。例項程式碼如下:
/* Configure theNVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
2.4、配置UART相關屬性
通過結構體USART_InitTypeDef來確定。UART模式下的欄位如下
USART_BaudRate:波特率,視具體裝置而定
USART_WordLength:字長
USART_StopBits:停止位
USART_Parity:校驗方式
USART_HardwareFlowControl:硬體流控制
USART_Mode:單/雙工
最後通過USART_Init()來設定。例項程式碼為:
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_Cmd()來啟動裝置UART。
2.5、中斷的服務程式的設計
目前使用了UART的兩個中斷USART_IT_RXNE(接收快取補空中斷)和USART_IT_TXE(傳送快取空中斷),前一箇中斷保證了一旦有資料接收到就進入中斷以接收特定長度的資料,後一箇中斷表示一旦發完一個數據就進入中斷函式,保證連續傳送一段資料。一個裝置的所有中斷都包含在一箇中斷服務程式中,因此必須首先分清楚這次響應的是哪一個中斷,使用USART_GetITStatus()函式確定;採用USART_ReceiveData()函式接收一個位元組資料,採用USART_SendData()函式傳送一個位元組資料,當關閉中斷時採用USART_ITConfig()失能響應的中斷。例項程式:
voidUART4_IRQHandler(void)
{
if(USART_GetITStatus(UART4,USART_IT_RXNE) != RESET)
{//當檢測掉讀入中斷
RxBuffer[RxCounter++] = USART_ReceiveData(UART4);
if (RxCounter ==NbrOfDataToRead)
{
USART_ITConfig(UART4, USART_IT_RXNE, DISABLE); //禁止中斷
}
}
if(USART_GetITStatus(UART4, USART_IT_TXE) != RESET)
{
/* Write one byte to the transmit data register */
USART_SendData(UART4, TxBuffer[TxCounter++]);
if(TxCounter ==NbrOfDataToTransfer)
{
//TxCounter = 0;
/* Disable the USARTy Transmit interrupt */
USART_ITConfig(UART4, USART_IT_TXE, DISABLE);
}
}
}
其中主程式與中斷服務程式通過全域性變數來通訊,這也是一種多程序共享儲存區的體現形式。