查看: 7103|回复: 10

关于STM32F103RET6的UART2的流控制研究

[复制链接]
  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-7-25 09:54:18 | 显示全部楼层 |阅读模式
    分享到:
    本L最近驱动一个扫描头模块SE955,一直无法通讯成功,详细见:大家用过STM32F10X的uart流控功能吗?
    https://www.cirmall.com/bbs/forum.php?mod=viewthread&tid=15126&fromuid=3087

    特别让人不舒服的地方是这个模块需要UART的流控制功能,本L选择的是STM32F103RET6作为主控MCU,用流控制的uart2做通讯接口,搞腾了2-3周了,一直没进展。
    也查了不少资料,以下是网文
    “硬件流控制常用的有RTS/CTS流控制和DTR/DSR(数据终端就绪/数据设置就绪)流控制。
    硬件流控制必须将相应的电缆线连上,用RTS/CTS(请求发送/清除发送)流控制时,应将通讯两端的RTS、CTS线对应相连,数据终端设备(如计算机)使用RTS来起始调制解调器或其它数据通讯设备的数据流,而数据通讯设备(如调制解调器)则用CTS来起动和暂停来自计算机的数据流。这种硬件握手方式的过程为:我们在编程时根据接收端缓冲区大小设置一个高位标志(可为缓冲区大小的75%)和一个低位标志(可为缓冲区大小的25%),当缓冲区内数据量达到高位时,我们在接收端将CTS线置低电平(送逻辑0),当发送端的程序检测到CTS为低后,就停止发送数据,直到接收端缓冲区的数据量低于低位而将CTS置高电平。RTS则用来标明接收设备有没有准备好接收数据。
    常用的流控制还有还有DTR/DSR(数据终端就绪/数据设置就绪)。我们在此不再详述。由于流控制的多样性,我个人认为,当软件里用了流控制时,应做详细的说明,如何接线,如何应用。


    翻看 STM32的用户手册
    查到如下:

      引脚             配置                 GPIO配置
    USARTx_RTS      硬件流量控制          推挽复用输出
    USARTx_CTS      硬件流量控制          浮空输入或带上拉输入

    根据此,我做了如下的配置:
    使能CTS,RTS对应的外设功能,设置为输出。

    void USART2_Config(void)
    {
            GPIO_InitTypeDef GPIO_InitStructure;
            USART_InitTypeDef USART_InitStructure;

            /* config USART2 clock */
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

            /* USART2 GPIO config */
       /* Configure USART2 Tx (PA.02) RTS (PA.01) as alternate function push-pull */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_1;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
                
      /* Configure USART2 Rx (PA.03) CTS (PA.00) as input floating */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_0;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
             
            /* USART2 mode config */
            //USART_InitStructure.USART_BaudRate = 115200;
            USART_InitStructure.USART_BaudRate = 9600;
            USART_InitStructure.USART_WordLength = USART_WordLength_8b;
            USART_InitStructure.USART_StopBits = USART_StopBits_1;
            USART_InitStructure.USART_Parity = USART_Parity_No ;
            USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
            USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

            USART_Init(USART2, &USART_InitStructure);
            USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
      USART_Cmd(USART2, ENABLE);
    }

    可是效果并没有出来,仍然无法进行通讯,我测量RTS脚,在发送数据其间一直是低电平。要接收数据 RTS发完数据必须拉高,实际情况下结果却没拉高。所以肯定通讯不了的。

    可是对照《STM32的用户手册》中文翻译版有如下的说明:由于我在办公室的电脑上无法发图片,就不发图片了。具体在手册的537页

    两个USART间的硬件流控制:通过将UASRT_CR3中的RTSE和CTSE置位,可以分别独立地使能RTS和CTS流控制。
    RTS流控制
    如果RTS流控制被使能(RTSE=1),只要USART接收器准备好接收新的数据,nRTS就变成有效(接低电平)。当接收寄存器内有数据到达时,nRTS被释放,由此表明希望在当前帧结束时停止数据传输。
    CTS流控制
    如果CTS流控制被使能(CTSE=1),发送器在发送下一帧前检查nCTS输入。如果nCTS有效(被拉成低电平),则下一个数据被发送(假设那个数据是准备发送的,也就是TXE=0),否则下一帧数据不被发出去。若nCTS在传输期间被变成无效,当前的传输完成后停止发送。
    当CTSE=1时,只要nCTS输入一变换状态,硬件就自动设置CTSIF状态位。它表明接收器是否准备好进行通信。如果设置了USART_CT3寄存器的CTSIE位,则产生中断。

    看描述貌似RTS,CTS信号是自动产生和检测的,

    但是事实是根本不是这样。

    本L有点恼火了,流控制不就是把RTS在发数据的时候拉低,接收数据的时候CTS设置为输入(浮空)状态吗?
    我直接配制RTS,CTS所在I/O为输出输入口,采用象485控制一样的方式,发送前把RTS拉低,发送完数据把RTS拉高,CTS不预理睬,随便它去,反正uart的接收中断一直开着的,检测数据桢格式,可以完美接收数据的。
    这样一修改,发送读取序列号的命令,神奇的一幕出现了,SE955有反应了,返回了序列号。

    估计我还没吃透STM32F103的UART流控制功能,有经验的欢迎交流,我这里权当 抛砖引玉了!
    得到一个结论:如果有设备需要UART流控制的功能,用一个标准UART+2根GPIO(用做CTS,RTS信号),就可以实现了。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2014-5-20 10:01
  • 签到天数: 41 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2013-7-30 13:41:44 | 显示全部楼层
    还没用过这方面,先mark下,留用!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-7-30 15:17:36 | 显示全部楼层
    呵呵,用到的人确实不算多,都没有什么人回复我的帖子
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-9-8 09:23
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2013-8-5 09:08:15 | 显示全部楼层
    mark 一下,忙完再研究。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-8-5 10:10:03 | 显示全部楼层
    好,有什么研究心得一起讨论
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-10-15 22:18:02 | 显示全部楼层
    LZ,我现在用华为的EM770W 3G模块,也需要RTS硬件流控,捣鼓了好久都没结果,想问一下,你说的配制RTS,CTS所在I/O为输出输入口,是配置成什么模式的,另外我只要把硬件流控设置为RTS_CTS,GetFlagStatus就一直得到RESET状态,不能发送数据。求教。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-10-17 13:29:13 | 显示全部楼层
    是这样的,我虽然设置流控制功能了,但是根本不起作用,然后呢我就手动控制RTS,CTS这2个信号,发信号前自己程序控制,所以任意2个I/O都可以使用了。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-10-18 13:49:52 | 显示全部楼层
    xiaopaohu123 发表于 2013-10-17 13:29
    是这样的,我虽然设置流控制功能了,但是根本不起作用,然后呢我就手动控制RTS,CTS这2个信号,发信号前自 ...

    哦,明白楼主的意思了~不过我这样设置貌似还是不起作用~这个串口通讯真是纠结死我了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-10-22 10:35:37 | 显示全部楼层
    eudora 发表于 2013-10-18 13:49
    哦,明白楼主的意思了~不过我这样设置貌似还是不起作用~这个串口通讯真是纠结死我了~ ...

    是的啊,我设置后也是不作用,害的我只好自己用I/O软件控制流控脚
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-4-2 16:02
  • 签到天数: 257 天

    连续签到: 1 天

    [LV.8]以坛为家I

     楼主| 发表于 2013-10-22 10:37:28 | 显示全部楼层
    有问题,我们可以交流
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-11-25 19:30 , Processed in 0.186163 second(s), 34 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.