查看: 3931|回复: 5

【STM32F4探索套件】序列之6:串口通信

[复制链接]
  • TA的每日心情
    开心
    2019-6-24 16:41
  • 签到天数: 709 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2014-8-20 11:10:15 | 显示全部楼层 |阅读模式
    分享到:
    本节我们将串口简介、串口原理、硬件设计、软件设计和下载验证5部分来分析,主要是从下面5个方面进行讲解:
    1.STM32F4串口部分介绍
    2.STM32F429简单串口原理介绍
    3.硬件设计
    4.软件设计
    5.下载验证
    一、串口的简介【通用同步异步收发器 USART
    实现功能:上电一直打印一串字符串。下面简单介绍一下USART的特性:

    二、简单介绍原理
    通信使用 3 根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。
    STM32fF429引脚:
    RXD -- PA10 接收数据线
    TXD -- PA9  发送数据线
    串口软件编写的一般步骤:
    (a) 串口时钟使能,GPIO时钟使能
    (b) 串口复位
    (c) GPIO端口模式设置
    (d) 串口参数初始化
    (e) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
    (f) 使能串口
    (g) 编写串口中断处理函数
    为了更好了解固件库在串口配置中的使用,下面简单介绍几个与串口有关的固件库函数。这些函数和定义主要在stm32f4xx_usart.c stm32f4xx_usart.h 中。
    (a) 串口时钟使能函数。USART挂载在APB2总线上,所以使能函数为:
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
    (b) 串口复位函数。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设才做。复位是在函数USART_DeInit()完成。
    USART_DeInit(USART_TypeDef* USARTx)
    (c) 串口参数初始化。串口初始化是通过USART_Init()函数来实现的。
    USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
    (d) 数据发送与接收。STM32 的发送与接收是通过数据寄存器 USART_RDRUSART_TDR来实现的,当向USART_TDR寄存器写数据的时候,串口就会自动发送数据,当收到数据的时候,就存储在USART_RDR寄存器中。
    STM32 库函数操作 USART_TDR 寄存器发送数据的函数是:
    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
    通过该函数可以向串口寄存器写一个数据。
    STM32 库函数操作 USART_RDR 寄存器读取串口接收到的数据的函数是:
    uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
    通过该函数可以读取串口接受到的数据。
    (e) 串口状态。
    读取串口状态的函数是:
    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
    第二个入口参数非常关键,它是我们要查看串口的哪种状态。
    (f) 串口使能。串口使能是通过函数USART_Cmd()来实现的。
    void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
    (g) 开启串口响应中断。有时候当我们还需要开启串口中断,那么我们还需要使能串口中断,使能串口中断的函数是:
    void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
    (h) 获取相应的中断状态。当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。 经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是:
    ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
    具体可以参考《STM32F030参考手册》。
    三、硬件设计

    硬件比较简单就是两个引脚!!
    四、软件设计
    软件是参考网上的一个程序,等下传上附件!!!
    void uart_init(u32 bound){
        //GPIO端口设置
        GPIO_InitTypeDef GPIO_InitStructure;
            USART_InitTypeDef USART_InitStructure;
            NVIC_InitTypeDef NVIC_InitStructure;
             
              /* Enable GPIOC and GPIOE clock */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
            
              /* Enable USART1 APB clock */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
              /* USART1 Pins configuration ************************************************/
      /* Connect pin to Periph */
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);   
      GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
            
      /* Configure pins as AF pushpull */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStructure);             //TX
      
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStructure);             //RX
       //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
            NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
            NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
            NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
            NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
      
       //USART 初始化设置
            USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
            USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
            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(USART1, &USART_InitStructure); //初始化串口
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
        USART_Cmd(USART1, ENABLE);                    //使能串口
    }
    void USART1_IRQHandler(void)                        //串口1中断服务程序
            {
            u8 Res;
    #ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII.
            OSIntEnter();   
    #endif
            if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
                    {
                    Res =USART_ReceiveData(USART1);//(USART1->DR);        //读取接收到的数据
                   
                    if((USART_RX_STA&0x8000)==0)//接收未完成
                            {
                            if(USART_RX_STA&0x4000)//接收到了0x0d
                                    {
                                    if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
                                    else USART_RX_STA|=0x8000;        //接收完成了
                                    }
                            else //还没收到0X0D
                                    {        
                                    if(Res==0x0d)USART_RX_STA|=0x4000;
                                    else
                                            {
                                            USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                                            USART_RX_STA++;
                                            if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收         
                                            }                 
                                    }
                            }                    
         }
    #ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII.
            OSIntExit();                                                                                          
    #endif
    }
    五、下载验证

    [size=0.83em]图片3.png (50.92 KB, 下载次数: 0)
    下载附件
    [color=rgb(153, 153, 153) !important]2014-3-16 22:19 上传



    整个程序在附件里面,希望大家验证!!!

    stm32f429 USART.zip (564.26 KB, 下载次数: 33)

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-8-15 09:28
  • 签到天数: 222 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-8-20 21:05:54 | 显示全部楼层
    支持楼主!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-6-24 16:41
  • 签到天数: 709 天

    连续签到: 1 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-8-21 15:12:50 | 显示全部楼层
    奋斗哥 发表于 2014-8-20 21:05
    支持楼主!!!

    谢谢 欢迎光临 多多指点
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-3-24 10:15
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-12-8 12:14:22 | 显示全部楼层
    串口        库函数必须顶 谢谢
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-6-24 16:41
  • 签到天数: 709 天

    连续签到: 1 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-12-8 20:13:08 | 显示全部楼层
    飞翔-396652 发表于 2014-12-8 12:14
    串口        库函数必须顶 谢谢

       欢迎啊
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 11:03
  • 签到天数: 2145 天

    连续签到: 36 天

    [LV.Master]伴坛终老

    发表于 2015-2-2 22:17:05 | 显示全部楼层
    STM32F4探索套件】序列之6:串口通信
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-12 08:48 , Processed in 0.181887 second(s), 25 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.