• stm32之USART学习


    首先,我是看着这位博主的文章受到的启发,进而加深了自己对USART的理解。下面是自己改装并实验过的程序。

    原文:http://www.cnblogs.com/greatwgb/archive/2011/07/28/2119350.html

    1.     串口的基本概念

    在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信。

    USART通过3个引脚与其他设备连接在一起,任何USART双向通信至少需要2个引脚:接受数据输入(RX)和发送数据输出(TX)。

    RX: 接受数据串行输入。通过过采样技术来区别数据和噪音,从而恢复数据。

    TX: 发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。

     

    2.     串口的如何工作的

    一般有两种方式:查询和中断。

    (1)查询:串口程序不断地循环查询,看看当前有没有数据要它传送。如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32板子到PC)。

    (2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从 PC到STM3板子,也可以从STM32板子到PC。

     

    程序源码:

    /*************************************
    
    USART(通用同步异步收发器)实验
    使用USART1实现数据的发送与接收
    日期:2016.2.25
    
    ******************************************/
    
    
    #include "stm32f10x.h"
     
    FlagStatus RX_status;
     
    //void RCC_cfg();
    void GPIO_cfg(void);
    void USART_cfg(void);
    void NVIC_cfg(void);
     
     
     
    int main()
    {
           int i;
           unsigned char TxBuf1[] = "HELLO,QIANSHUAI,Welcome to my STM32! Please press any key!";
        
           GPIO_cfg();
           NVIC_cfg();
           USART_cfg();
     
           USART_ClearFlag(USART1,USART_FLAG_TC);    //清除标志位,否则第1位数据会丢失
     
           for( i=0;TxBuf1[i]!='';i++)     //发送数据,当有数据在发送的时候,Pg14会亮
           {
                  USART_SendData(USART1,TxBuf1[i]);
                  GPIO_SetBits(GPIOG,GPIO_Pin_14);
                  
                  while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);  //等待数据发送完毕
                  GPIO_ResetBits(GPIOG,GPIO_Pin_14);
           }
     
           while(1);
     
    }
     
     
                      //IO口配置
    void GPIO_cfg()
    {
           GPIO_InitTypeDef GPIO_InitStructure;
             RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
           //实验发现,当不使能RCC_APB2Periph_USART1时,运行也不会报错,但是串口助手显示程序一直卡在发送状态,led一直亮着。
              
        //   GPIO_StructInit(&GPIO_InitStructure);        //我的板子的例程中并没有声明这一句
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;      //PA9作为US1的TX端,打开复用,负责发送数据
           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
           GPIO_Init(GPIOA, &GPIO_InitStructure);
     
           //PA10作为US1的RX端,负责接收数据
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //浮空输入
           GPIO_Init(GPIOA, &GPIO_InitStructure);
     
           //LED2显示串口正在发送/接收数据
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
           GPIO_Init(GPIOG, &GPIO_InitStructure);
    }
     
    //串口初始化,在初始化USART前应该先把GPIO设置好,USART是GPIO的复用功能.
    void USART_cfg()
    {
           USART_InitTypeDef USART_InitStructure;
           
           USART_StructInit(&USART_InitStructure);    //将结构体设置为缺省状态
        
           USART_InitStructure.USART_BaudRate = 115200;    //波特率设置为115200
           
           USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //一帧数据的宽度设置为8bits
          
           USART_InitStructure.USART_StopBits = USART_StopBits_1;    //在帧结尾传输1个停止位
          
           USART_InitStructure.USART_Parity = USART_Parity_No;     //奇偶失能模式,无奇偶校验
         
           USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;     //发送/接收使能
          
           USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //硬件流控制失能  
           
           USART_Init(USART1, &USART_InitStructure);     //根据参数初始化串口1寄存器
               
           USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);     //打开串口1的中断响应函数
           
           USART_Cmd(USART1, ENABLE);    //打开串口1
    }
     
    //配置中断
    void NVIC_cfg()
    {
            NVIC_InitTypeDef NVIC_InitStructure;
        
            NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //选择中断分组2
                   
            NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;             //选择串口1中断
            NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占式中断优先级设置为0
            NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         //响应式中断优先级设置为0
            NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能中断
            NVIC_Init(&NVIC_InitStructure);
    }
     
     
    //然后在stm32f10x_it.c文件中找到相应的中断处理函数,并填入一下内容。
    //注意在stm32f10x_it.c中,要声明一下外部变量RX_status
     
    //extern FlagStatus RX_status;
     
    void USART1_IRQHandler(void)     //中断入口函数
    {
          
           GPIO_SetBits(GPIOG, GPIO_Pin_14);
     
           //确认是否接收到数据
           RX_status = USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
           //接收到数据
           if(RX_status == SET)
           {
                  //将数据回送至超级终端
                  USART_SendData(USART1, USART_ReceiveData(USART1));
                  //等待数据发送完毕
                  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
                  GPIO_ResetBits(GPIOG, GPIO_Pin_14);
           }
     
    }

    这个是自己改过的程序。其实也是很简答的。

  • 相关阅读:
    Codeforces 1255B Fridge Lockers
    Codeforces 1255A Changing Volume
    Codeforces 1255A Changing Volume
    leetcode 112. 路径总和
    leetcode 129. 求根到叶子节点数字之和
    leetcode 404. 左叶子之和
    leetcode 104. 二叉树的最大深度
    leetcode 235. 二叉搜索树的最近公共祖先
    450. Delete Node in a BST
    树的c++实现--建立一棵树
  • 原文地址:https://www.cnblogs.com/qsyll0916/p/6442832.html
Copyright © 2020-2023  润新知