STM32F207調試記錄之串口配置

本篇文章是我前段時間發佈在其他不公開平臺上的原創文章,今天拿過來和大家分享一下。

這幾天在配置串口時出現了一些令人不解的問題,鬼魅般的不行啊!真是令人頭疼!因爲再一次遇到了這個問題,故想有必要做一個記錄。
     先說一下配置USART1的過程吧。
①配置串口1時鐘,在APB2上
②複用功能連上IO引腳
③ 配置GPIO爲複用模式、推輓、50MHz、上拉
④配置串口波特率爲指定波特率、 8位數據長度、1位停止位、無校驗、無流控制、串口模式爲接收和發送
⑤使能串口
⑥配置串口中斷包括 中斷通道、搶佔優先級、響應優先級、通道使能
⑦配置串口接收中斷使能、發送中斷使能 
至此串口配置完畢。
在主函數中放上串口發送函數(一秒發一次),開始調試,現象如下:
首先將斷點放在發送中斷和接收中斷處理的地方,每隔一秒會進入發送中斷中,但是最前兩次狀態寄存器中的值是正常的,之後會出現其他異常狀態,此時將發送中斷處理處的斷點去除,程序會每隔一秒進入接收中斷,因爲本人並沒有發送數據給這串口,但確實進入的接收中斷,故纔有了開頭時的不解。
由於先前也出現過這樣的情況,上一次是在串口5上而這一次在串口1上,上一次花了好幾個晚上加班檢查到底是那個地方出了問題。
從老項目上的代碼進行對比發現似乎都是一樣的,百度各種尋找解決辦法,並沒有發現有哪不對。最後實在沒辦法,把官方demo例程拿出來研究了,看了一遍又一遍,然後按照例程重新寫了一遍。哈,沒問題了。
貼出代碼:

/*!
 * @brief   串口1 IO初始化
 * @param
 * @return	NONE
 * @note	PA9-TXD,PA10-RXD
 */
void USART_COM1IOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);	//!<串口1時鐘初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//!<串口1時鐘初始化
  
	GPIO_PinAFConfig(GPIOA, 9, GPIO_AF_USART1);		//!<GPIO連接到串口1上,PA9-TXD
	GPIO_PinAFConfig(GPIOA, 10, GPIO_AF_USART1);		//!<GPIO連接到串口1上,PA10-RXD

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;		//!<接收和發送均設爲複用模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//!<無上拉也無下拉

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/*!
 * @brief   串口1 中斷初始化
 * @param
 * @return	NONE
 * @note	
 */
void USART1InterruptInit(uint32 pri)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =pri;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  USART_ITConfig(USART1, USART_IT_TC, ENABLE);//!<使能USART1發送中斷
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//!<使能USART1接收中斷
}

/*!
 * @brief   將UART1初始化到指定的波特率上
 * @param	baud_value:波特率 pri:優先級
 * @return	NONE
 * @note	PC串口
 */
void USART1_Init(uint32 baud_value,uint32 pri)
{
	USART_InitTypeDef USART_InitStructure;

	USART_COM1IOInit();  
	USART_InitStructure.USART_BaudRate = baud_value;
	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);	//!<串口1初始化
	USART_Cmd(USART1, ENABLE);			//!<使能串口1
	USART1InterruptInit(pri);			//!<串口1中斷配置
}
以上爲本人修改過後可用初始化代碼。
    經過仔細對比調試過後,最終把問題鎖定在了那個IO口上拉下拉的配置上。本來配置爲上拉串口異常,改爲無上拉也無下拉之後程序正常了。按照常理來說,既然已經配置成複用推輓了,拉上或下拉就無所謂了,看來這個地方又是芯片給留出了一個坑,恰巧讓俺跳進去了兩次。程序正常之後,將那個配置重新改爲上拉,程序還是正常。這個坑隱藏得好深!
    都進去過兩次了,想仔細瞭解清楚,便去請教了大神同事,來解惑啦。
    之前沒有重視這個問題,我本來以爲會跟外圍電路設計有關。同事否定了我的觀點,正常設計的外圍電路對芯片的影響基本沒有。這個現象估計與芯片內部設計有關,由於官方例程中使用的配置爲無上拉也無下拉,故推薦保持該配置。

問題解決了,才能好好睡覺,準備下班。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章