STM32f103zet6 串口數(shù)基本配置及詳細說明:
玩stm32也有一段時間了,對串口中斷接受和DAM方式發(fā)送總一下總結,但是本節(jié)只講述串口中斷接受的基本配置,既然是基本就說明他很重要,如有疏忽,就會讓串口失靈。下一節(jié)主要講述DAM的用法。言歸正傳:首先我們要知道開啟一個功能的步驟如下,
(1)RCC配置
(2)GPIO配置
(3)USART配置
(4)發(fā)送/接收數(shù)據(jù)
在RCC配置中,我們除了常規(guī)的時鐘設置之外,需要打開USART相應的IO口時鐘,USART時鐘,還有管腳功能復用時鐘。
1、在GPIO配置中,將發(fā)送端的管腳配置為復用推挽輸出,講接受端的管腳設置為浮空輸入。注意紅色標記,這兩種模式很重要,注意其區(qū)別。
2、在USART的配置中,通過USART_InitTypeDdf結構體對USART進行初始化操作。如用中斷方式:在USART配置中要打開串口中斷。
3、在NVIC的配置中主要是USARTx_IRQChannel的配置。
下面是一段配置代碼:
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //開啟USART1時鐘
//配置PA9作為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(GPIOA , &GPIO_InitStructure);
//配置PA10作為USART1 Rx
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA , &GPIO_InitStructure);
//配置USART1
//中斷被屏蔽了
USART_InitStructure.USART_BaudRate = 9600; //波特率可以通過地面站配置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位數(shù)據(jù)
USART_InitStructure.USART_StopBits = USART_StopBits_1; //在幀結尾傳輸1個停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //禁用奇偶校驗
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //發(fā)送、接收使能
//配置USART1時鐘
USART_ClockInitStruct.USART_Clock = USART_Clock_Disable; //時鐘低電平活動
USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low; //SLCK引腳上時鐘輸出的極性-》低電平
USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge; //時鐘第二個邊沿進行數(shù)據(jù)捕獲
USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable; //最后一位數(shù)據(jù)的時鐘脈沖不從SCLK輸出
USART_Init(USART1, &USART_InitStructure);
USART_ClockInit(USART1, &USART_ClockInitStruct);
/* Enable USART1 DMA TX request */
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
//使能USART1接收中斷
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//使能USART1
USART_Cmd(USART1, ENABLE);
}
void NVIC_Configuration(void)//配置中斷
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
//將向量表起始地址設置為0x00000000
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else //VECT_TAB_FLASH
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
//配置用1位表示優(yōu)先級
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //選擇第1組優(yōu)先級 解釋如下第
//0 組:所有 4bit 用于指定響應優(yōu)先級;
//第 1 組:最高 1 位用于指定搶占式優(yōu)先級,后面 3 位用于指定響應優(yōu)先級;
//第 2 組:最高 2 位用于指定搶占式優(yōu)先級,后面 2 位用于指定響應優(yōu)先級;
//第 3 組:最高 3 位用于指定搶占式優(yōu)先級,后面 1 位用于指定響應優(yōu)先級;
//第 4 組:所有 4 位用于指定搶占式優(yōu)先級。
//允許USART1中斷
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//選擇串口1中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************
函數(shù)名:USART1_SendData
描述 :USART1發(fā)送函數(shù)
輸入 :無
輸出 :無
返回 :無
**************************************************************************************/
void USART1_SendData(uint16_t Data)
{
USART1-》DR = (Data & (uint16_t)0x01FF);
while(((USART1-》SR)&0x0080)==RESET);
}
/****************************************************************************
* 名稱:USART1_Printf()
* 功能:向串口發(fā)送一字符串 用法同Printf()函數(shù)
* 入口參數(shù):format 要發(fā)送的字符串的指針 。。。 為參數(shù)
* 出口參數(shù):發(fā)送的字符串的字符個數(shù)
****************************************************************************/
int USART1_Printf(const char *format, 。。。)
{
va_list v_list;
char *ptr;
int i= 0;
va_start(v_list, format); // Initialize variable arguments.
vsprintf(tbuf1, format, v_list );
va_end(v_list);
ptr= tbuf1;
while( (*ptr) && i《MAX_TBUF1) {
USART1_SendData(*ptr);
ptr++; i++;
}//while
return i;
}
void USART1_IRQHandler(void) //中斷接收函數(shù)
{
if((USART1-》SR)&0x0020) //是否接收中斷 (接收寄存器非空)
{
//寫入執(zhí)行動作
}
USART1-》SR = 0xFFDF;
}
注意1:
所謂搶占式優(yōu)先級和響應優(yōu)先級,他們之間的關系是:具有高搶占式優(yōu)先級的中斷可以在具有低搶占式優(yōu)先級
的中斷處理過程中被響應,即中斷嵌套。
當兩個中斷源的搶占式優(yōu)先級相同時,這兩個中斷將沒有嵌套關系,當一個中斷到來后,如果正在處理另一個
中斷,這個后到來的中斷就要等到前一個中斷處理完之后才能被處理。如果這兩個中斷同時到達,則中斷控制器根
據(jù)他們的響應優(yōu)先級高低來決定先處理哪一個;如果他們的搶占式優(yōu)先級和響應優(yōu)先級都相等,則根據(jù)他們在中斷
表中的排位順序決定先處理哪一個。每一個中斷源都必須定義 2 個優(yōu)先級。
有幾點需要注意的是:
1)如果指定的搶占式優(yōu)先級別或響應優(yōu)先級別超出了選定的優(yōu)先級分組所限定的范圍,將可能得到意想不到的結
果;
2)搶占式優(yōu)先級別相同的中斷源之間沒有嵌套關系;
3)如果某個中斷源被指定為某個搶占式優(yōu)先級別,又沒有其它中斷源處于同一個搶占式優(yōu)先級別,則可以為這個
中斷源指定任意有效的響應優(yōu)先級別。
注意2:
注意在對數(shù)據(jù)進行發(fā)送和接收的時候,要檢查 USART 的狀態(tài),只有等到數(shù)據(jù)發(fā)送或接收完畢之后才能進行下一幀數(shù)據(jù)的發(fā)送或接收。采用 USART_GetFlagStatus()函數(shù)。
同時還要注意的是,在發(fā)送數(shù)據(jù)的最開始,需要清除一下 USART 的標志位,否則,第 1 位數(shù)據(jù)會丟失。因為在硬件復位之后,USART 的狀態(tài)位 TC 是置位的。當包含有數(shù)據(jù)的一幀發(fā)送完成之后,由硬件將該位置位。只要當
USART 的狀態(tài)位 TC 是置位的時候,就可以進行數(shù)據(jù)的發(fā)送。然后 TC 位的置零則是通過軟件序列來清除的,具體的步驟是“先讀 USART_SR,然后寫入 USART_DR”,只有這樣才能夠清除標志位 TC,但是在發(fā)送第一幀數(shù)據(jù)的時候,并沒有進行讀 USART_SR 的操作,而是直接進行寫操作,因此 TC 標志位并沒有清空,那么,當發(fā)送第一幀數(shù)據(jù),然后用 USART_GetFlagStatus()檢測狀態(tài)時返回的是已經(jīng)發(fā)送完畢(因為 TC 位是置 1 的),所以程序會馬上發(fā)送下一幀數(shù)據(jù),那么這樣,第一幀數(shù)據(jù)就被第二幀數(shù)據(jù)給覆蓋了,所以看不到第一幀數(shù)據(jù)的發(fā)送
評論