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);
    }
}

 

posted @ 2018-10-15 12:03  自由的青  阅读(1547)  评论(0编辑  收藏  举报