STM32 串口接收中斷 代碼

1、代碼介紹

今天做項目,要用到串口中斷接收,在網上一搜,大量代碼,copy過來編譯沒問題,但是運行起來才發現不能產生中斷,於是決定自己搞搞,用了半天的功夫,終於有結果了。

2、共同討論

代碼屬個人編寫,自有不足之處,望大家指出。

3、單片機型號

代碼基於HY--Stm32_100p單片機編寫


#include "stm32f10x.h"

/*************************************************
函數: void RCC_Configuration(void)
功能: 復位和時鐘控制 配置
參數: 無
返回: 無
**************************************************/
void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;                    //定義外部高速晶體啓動狀態枚舉變量
    RCC_DeInit();                                    //復位RCC外部設備寄存器到默認值
    RCC_HSEConfig(RCC_HSE_ON);                       //打開外部高速晶振
    HSEStartUpStatus = RCC_WaitForHSEStartUp();      //等待外部高速時鐘準備好
    if(HSEStartUpStatus == SUCCESS)                  //外部高速時鐘已經準別好
    {
          FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //開啓FLASH預讀緩衝功能,加速FLASH的讀取。所有程序中必須的用法.位置:RCC初始化子函數裏面,時鐘起振之後
          FLASH_SetLatency(FLASH_Latency_2);                    //flash操作的延時
              
          RCC_HCLKConfig(RCC_SYSCLK_Div1);               //配置AHB(HCLK)時鐘等於==SYSCLK
          RCC_PCLK2Config(RCC_HCLK_Div1);                //配置APB2(PCLK2)鍾==AHB時鐘
          RCC_PCLK1Config(RCC_HCLK_Div2);                //配置APB1(PCLK1)鍾==AHB1/2時鐘
               
          RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //配置PLL時鐘 == 外部高速晶體時鐘 * 9 = 72MHz
          RCC_PLLCmd(ENABLE);                                   //使能PLL時鐘
     
          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  //等待PLL時鐘就緒
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //配置系統時鐘 = PLL時鐘
          while(RCC_GetSYSCLKSource() != 0x08) ;                 //檢查PLL時鐘是否作爲系統時鐘
    }
}


/*******************************************************************************
* Function Name   : NVIC_Configuration
* Description        : Configures NVIC and Vector Table base location.
* Input                    : None
* Output                 : None
* Return                 : None
*******************************************************************************/
void NVIC_Configuration(void)
{
       NVIC_InitTypeDef NVIC_InitStructure;
      
       /* Set the Vector Table base location at 0x08000000 */
       NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
      
       /* Configure the NVIC Preemption Priority Bits */  
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
      
       /* Enable the USART2 Interrupt */
       NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;       //通道設置爲串口2中斷
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //中斷響應優先級0
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //打開中斷
       NVIC_Init(&NVIC_InitStructure);   //初始化
}

/*******************************************************************************
函數名:USART2_Configuration
輸  入:
輸  出:
功能說明:
初始化串口硬件設備,啓用中斷
配置步驟:
(1)打開GPIO和USART2的時鐘
(2)設置USART2兩個管腳GPIO模式
(3)配置USART2數據格式、波特率等參數
(4)使能USART2接收中斷功能
(5)最後使能USART2功能
*/
void USART2_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;


/* 第1步:打開GPIO和USART部件的時鐘 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        


/* 第2步:將USART Tx的GPIO配置爲推輓複用模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);


/* 第3步:將USART Rx的GPIO配置爲浮空輸入模式
由於CPU復位後,GPIO缺省都是浮空輸入模式,因此下面這個步驟不是必須的
但是,我還是建議加上便於閱讀,並且防止其它地方修改了這個口線的設置參數
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*  第3步已經做了,因此這步可以不做
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);




/* 第4步:配置USART2參數
   - BaudRate = 115200 baud
   - Word Length = 8 Bits
   - One Stop Bit
   - No parity
   - Hardware flow control disabled (RTS and CTS signals)
   - Receive and transmit enabled
*/
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(USART2, &USART_InitStructure);


        /* 若接收數據寄存器滿,則產生中斷 */
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);


/* 第5步:使能 USART2, 配置完畢 */
USART_Cmd(USART2, ENABLE);


        /* 如下語句解決第1個字節無法正確發送出去的問題 */
        USART_ClearFlag(USART2, USART_FLAG_TC);     // 清標誌
}

void LED_GPIO_Configure(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/******************************************************************
                STM32在串口2接收1字節                                           
                說明:串口2接收中斷                                             
******************************************************************/
void USART2_IRQHandler(void)     //在中斷服務程序中,由於主機響應中斷時並不知道是哪個中斷源發出中斷請求,因此必須在中斷服務程序中對中斷源進行判別,然後分別進行處理。當然,如果只涉及到一箇中斷請求,是不用做上述判別的。但是無論什麼情況,做上述判別是個好習慣
{
          GPIO_SetBits(GPIOC, GPIO_Pin_6);// D1亮        
 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)    //若接收數據寄存器滿
 {
            USART_ClearITPendingBit(USART1,USART_IT_RXNE);
            USART_SendData(USART2, USART_ReceiveData(USART2));
            while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
         } 
          GPIO_ResetBits(GPIOC, GPIO_Pin_6); //D1滅 


void main(void)
{
 RCC_Configuration();
 NVIC_Configuration();
 USART2_GPIO_Configuration();
          LED_GPIO_Configure();
          while(1);
}

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