STM32串口實驗


實驗階段1,定時器計時1s觸發中斷,在中斷中往外發送數據

定時器設定為36000分頻,周期設定為2000,並開啟中斷,配置代碼如下

    tim_timebase_struct.TIM_CounterMode = TIM_CounterMode_Up;
    tim_timebase_struct.TIM_ClockDivision = TIM_CKD_DIV1;
    tim_timebase_struct.TIM_Prescaler = DEBUG_UART_TX_TIM_PSC;
    tim_timebase_struct.TIM_Period = DEBUG_UART_TX_TIM_PERIOD;
    TIM_TimeBaseInit(DEBUG_UART_TX_TIM, &tim_timebase_struct);
    
    TIM_Cmd(DEBUG_UART_TX_TIM, ENABLE);
    
    TIM_ITConfig(DEBUG_UART_TX_TIM, TIM_IT_Update, ENABLE);

串口配置與PC端調試助手設置一致即可,一般都配置為無硬件流控,無奇偶校驗,1位停止位,八位數據位

    usart_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    usart_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    usart_struct.USART_Parity = USART_Parity_No;
    usart_struct.USART_StopBits = USART_StopBits_1;
    usart_struct.USART_WordLength = USART_WordLength_8b;
    usart_struct.USART_BaudRate = DEBUG_UART_BAUDRATE;
    USART_Init(DEBUG_UART, &usart_struct);
    
    USART_Cmd(DEBUG_UART, ENABLE);

中斷服務函數中還是常規的檢測中斷標志位然后清除中斷標志位

void DEBUG_UART_TX_TIM_IRQ_HANDLER(void)
{
    if(TIM_GetITStatus(DEBUG_UART_TX_TIM, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(DEBUG_UART_TX_TIM, TIM_IT_Update);
        
        printf("hello\r\n");
    }
}

串口發送函數使用了輸出流重定向,需要在魔術棒配置中勾選使用微庫(Use MicroLIB)

int fputc(int ch, FILE* stream)
{
    while(USART_GetFlagStatus(DEBUG_UART, USART_FLAG_TXE) == RESET);
    
    USART_SendData(DEBUG_UART, ch);
    
    return ch;
}

實驗階段2,通過按鍵觸發外部中斷的方式來產生一次數據發送,按鍵GPIO配置為一般輸出,下拉即可,並且需要調用一個函數將GPIO連接到EXTI

    gpio_struct.GPIO_Mode = GPIO_Mode_IN;
    gpio_struct.GPIO_PuPd = GPIO_PuPd_DOWN;
    gpio_struct.GPIO_Speed = GPIO_Speed_Level_1;
    gpio_struct.GPIO_Pin = PUSHBUTTON_PIN;
    GPIO_Init(PUSHBUTTON_GPIO, &gpio_struct);
    
    SYSCFG_EXTILineConfig(PUSHBUTTON_EXTI_PORTSOURCE, PUSHBUTTON_EXTI_PINSOURCE);

本實驗使用的是ST官方的NUCLEO開發板,MCU型號為STM32F303RE,使用標准庫開發,串口的GPIO配置如下

    gpio_struct.GPIO_Mode = GPIO_Mode_AF;
    gpio_struct.GPIO_OType = GPIO_OType_PP;
    gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    gpio_struct.GPIO_Speed = GPIO_Speed_Level_1;
    gpio_struct.GPIO_Pin = DEBUG_UART_TX | DEBUG_UART_RX;
    GPIO_Init(DEBUG_UART_GPIO, &gpio_struct);
    
    GPIO_PinAFConfig(DEBUG_UART_GPIO, DEBUG_UART_TX_PINSOURCE, GPIO_AF_7);
    GPIO_PinAFConfig(DEBUG_UART_GPIO, DEBUG_UART_RX_PINSOURCE, GPIO_AF_7);

中斷服務函數如下

void PUSHBUTTON_IRQ_HANDLER(void)
{
    if(EXTI_GetITStatus(PUSHBUTTON_EXTI_LINE) != RESET)
    {
        EXTI_ClearITPendingBit(PUSHBUTTON_EXTI_LINE);
        
        printf("Push button clicked!!\r\n");
    }
}

該實驗功能點有一個明顯BUG,即外部中斷可能會連續觸發,導致一次按鍵可能導致重復發送數據

---***---該BUG為硬件消抖做的不好所致,在官方的NUCLEO64開發板上有BUG,但在野火MINI板上運行OK

 實驗階段3,做一個接受回傳的功能,開啟串口中斷,在中斷中將收到的數據進行回傳

void DEBUG_UART_IRQ_HANDLER(void)
{
    if(USART_GetITStatus(DEBUG_UART, USART_IT_RXNE) != RESET)
    {
        USART_ClearITPendingBit(DEBUG_UART, USART_IT_RXNE);
        
        uint16_t data = USART_ReceiveData(DEBUG_UART);
        USART_SendData(DEBUG_UART, data);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM