zoukankan      html  css  js  c++  java
  • STM32学习笔记(二)——串口控制LED

     

    开发板芯片:STM32F407ZGT6

    PA9-USART1_TX,PA10-USART1_RX;

    PF9-LED0,PF10-LED1;

     

    一、串口1配置过程(不使用串口中断):

    1.使能时钟,包括GPIO时钟和串口1时钟使能,注意它们是挂载在不同的时钟总线上的。

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    //使能端口时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);    //使能串口时钟

    2.端口映射到串口1。

        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);//端口映射到串口
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

    3.GPIO初始化,注意配置模式时,要设置为复用模式,其他和GPIO基本配置相同

        IO_Init。GPIO_Mode = GPIO_Mode_AF;            //设置为复用模式
        IO_Init。GPIO_OType = GPIO_OType_PP;
        IO_Init。GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
        IO_Init。GPIO_PuPd = GPIO_PuPd_UP;
        IO_Init。GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &IO_Init);

    4.串口1初始化,包括:波特率,发送接收使能,数据位,停止位,奇偶校验,硬件控制流

        UT_Init。USART_BaudRate = 9600;        //波特率
        UT_Init。USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //无硬件控制流
        UT_Init。USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //发送接收
        UT_Init。USART_Parity = USART_Parity_No;            //无奇偶校验
        UT_Init。USART_StopBits = USART_StopBits_1;        //停止位1
        UT_Init。USART_WordLength = USART_WordLength_8b;    //数据位8
        USART_Init(USART1, &UT_Init);

    5.串口1使能。

        USART_Cmd(USART1, ENABLE);            //串口使能

    二、相关的函数和寄存器介绍

     1、数据接收

    1.1.状态寄存器

    其中的位5:RXNE就是可以接收完成标志位,当数据接收完成时,RXNE会自动置1,我们可以通过读取该位的状态,来判断是否接收到数据,直接读取该位的方法是

      u8 Receive_Data = 0;

     Receive_Flag = USART1->SR & 1 << 5;        //若接收到数据则标志位=1

     上面的方法就是直接读取位5的值,接收完成则Receive_Flag=1。

    其实我们更喜欢用一个函数来读取RXNE的状态:

    USART_GetFlagStatus(USART1, USART_IT_RXNE)
    

    该函数不仅可以读取RXNE的状态,还可以读取其他位的状态,若标志置1,该函数则会返回SET,即1。

    我们可以看看该函数是如何实现的呢?

    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
    {
      FlagStatus bitstatus = RESET;
      /* Check the parameters */
      assert_param(IS_USART_ALL_PERIPH(USARTx));
      assert_param(IS_USART_FLAG(USART_FLAG));
    
      /* The CTS flag is not available for UART4 and UART5 */
      if (USART_FLAG == USART_FLAG_CTS)
      {
        assert_param(IS_USART_1236_PERIPH(USARTx));
      } 
        
      if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
      {
        bitstatus = SET;
      }
      else
      {
        bitstatus = RESET;
      }
      return bitstatus;
    }

     可以看出该函数也是通过读取寄存器相应的位来返回相应的状态。

    还有另一个函数和这个很相似:

    USART_GetITStatus(USART1, USART_IT_RXNE);

    这个函数也是读取RXNE的状态,不同的是当我们打开了串口中断,接收到数据时,这个函数才会返回1.

    也就是说,无论串口中断是打开,接受完成后RXNE标志位都会置1,即USART_GetFlagStatus(USART1, USART_IT_RXNE)返回1,如果开启了中断,那么USART_GetFlagStatus(USART1, USART_IT_RXNE)和USART_GetITStatus(USART1, USART_IT_RXNE)都会置1。

    当RXNE置1,即接收到数据后,我们要及时的读取接收到的数据,相应的函数是Receive_Data = USART_ReceiveData(USART1);

    我们也可以直接读取USART1->DR寄存器,如Receive_Data = USART1->DR;

    1.2.数据寄存器

    当读取完成后,RXNE将自动清零,如果没有读取数据,则需要软件清零,可以使用函数USART_ClearFlag(USART1,USART_IT_RXNE);来进行手动清零,或通过将状态寄存器位5-RXNE置为0:USART1->SR &= ~(1 << 5);这一点是很重要的。

    2.数据发送

    将数据进行处理后,我们需要回复一些数据,我们可以通过函数USART_SendData(USART1,data);来向外发送数据,当然我们也可以像读取数据那样,将数据写入DR寄存器来实现 USART1->DR=data。其实我们更多的是通过重定向printf()函数来向外格式化输出数据,如printf("Receive Succsed: %d ", Data);这个更方便一些。

    三、程序实现

    那么我们怎么来实现电脑发送0x01来控制LED反转呢?

    1.串口配置函数

    void USART1_Config()
    {
        GPIO_InitTypeDef IO_Init;
        USART_InitTypeDef UT_Init;
    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    //使能端口时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);    //使能串口时钟
        
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);//端口映射到串口
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
    
        IO_Init.GPIO_Mode = GPIO_Mode_AF;            //设置为复用模式
        IO_Init.GPIO_OType = GPIO_OType_PP;
        IO_Init.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
        IO_Init.GPIO_PuPd = GPIO_PuPd_UP;
        IO_Init.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &IO_Init);
    
        UT_Init.USART_BaudRate = 9600;        //波特率
        UT_Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //无硬件控制流
        UT_Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //发送接收
        UT_Init.USART_Parity = USART_Parity_No;            //无奇偶校验
        UT_Init.USART_StopBits = USART_StopBits_1;        //停止位1
        UT_Init.USART_WordLength = USART_WordLength_8b;    //数据位8
        USART_Init(USART1, &UT_Init);
    
        USART_Cmd(USART1, ENABLE);            //串口使能
    }

    2.主函数

    主函数怎么写呢?其实很简单,就是对接收的数据进行一下判断就OK了,如果接收到的数据==0x01,那么LED=!LED,是不是很简单呢?

    int main(void)
    {
        LED_Init();
        delay_init(168);
        USART1_Config();
        LED0_OFF;
        LED1_OFF;
        while(1)
        {
            u8 Receive_Data = 0;
            if(USART_GetITStatus(USART1, USART_IT_RXNE))        //若接收到数据
            {
                Receive_Data = USART_ReceiveData(USART1);        //读取数据后,RXNE标志位自动清零;
                printf("Receive Succsed: %2x 
    ", Receive_Data);
                if(Receive_Data == 0x01)
                    LED0 = !LED0;
    //        USART_ClearFlag(USART1,USART_IT_RXNE);        //手动清零
            }
            else
            {
                LED1 = !LED1;
                printf("Running....
    ");
                delay_ms(500);
            }
        }
    }

    这里使用了串口发送“Running....”和LED1闪烁来指示程序正在运行,这种方法很常用,可以指示程序的运行状态。

    本文章没有使用串口中断来进行控制,下一篇文章将会介绍如何使用串口中断来控制LED。

    参考资料:

    STM32F4xx中文参考手册

    STM32F4开发指南-库函数版本_V1.1

    USART_百度百科

    以上是我学习过程的一些个人理解,有不对或不准确的地方,欢迎各位大神指正。

    2017年4月16日21:58:46

    欢迎大家关注我的个人博客 http://www.wangchaochao.top/
    微信扫码关注我的公众号

    不定期更新个人学习笔记和技术总结,欢迎大家互相学习交流!

  • 相关阅读:
    ELK+Kafka+Beats实现海量日志收集平台(三)
    ELK+Kafka+Beats实现海量日志收集平台(二)
    ELK+Kafka+Beats实现海量日志收集平台(一)
    Linux 上安装logstash-6.6.0及配置kafka输入
    Linux 上安装filebeat-6.6.0
    SpringBoot与Kafka整合实现简单分布式消息队列
    logstash-6.6.0.tar.gz、filebeat-6.6.0-linux-x86_64.tar.gz 下载百度云
    Centos 7.X 上安装Kafka及一些常用命令
    Linux MariaDB 10.4.8 官网地址下载及百度云
    [Errno 28] No space left on device ERROR: Could not install packages due to an EnvironmentError
  • 原文地址:https://www.cnblogs.com/whik/p/6720303.html
Copyright © 2011-2022 走看看