打印
[STM8]

【UART1】如何收到完整的内容后再发送数据

[复制链接]
5320|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
stm_zy|  楼主 | 2009-11-18 12:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 stm_zy 于 2009-11-18 13:51 编辑

最近在用STM8s103进行串口通讯调试。
使用UART1,利用中断进行收发,主要代码(中断处理部分)如下

/*发送中断处理代码*/
@interrupt void USART_TX(void)
{
    /* 将一个字节写入发送寄存器,并将发送缓冲区指针向后移动一个字节*/
    /*TxBuffer是定义的8字节的字符串,TxCounter是定义的无符号字符变量,用来计数*/
    UART1->DR = TxBuffer[TxCounter++];
    /*如果发送的字节数等于发送缓冲区长度(8字节)*/
    /*BufferSize是常量8*/
    if (TxCounter == BufferSize)
    {
         /* 禁止发送中断 */
         UART1->CR2 &= (~UART1_CR2_TIEN);
         TxCounter = 0;
    }
    return;
}
/*接收中断处理代码*/
@interrupt void USART_RX(void)
{
    u8 dummy = UART1->SR;
    /*如果状态寄存器标识了接收寄存器中有数据,且接收数据长度小于指定长度*/
    if ( (dummy & 0x20) && (RxCounter < BufferSize) )
    {
     /* 从接收数据寄存器中读取一个字节 */
     RxBuffer[RxCounter++] = UART1->DR;
    }
    else
    {
         if (RxCounter == BufferSize)
         {
             /*当接收的数据长度符合要求时,使能发送中断,进行数据发送*/
             UART1->CR2 |= UART1_CR2_TIEN;
         }
         RxCounter = 0;
        /*禁止接收中断*/
        //UART1->CR2 &= (~UART1_CR2_RIEN);
    }
    return;
}

预期目的:
    MCU作为下位机,由电脑(作为主机)串口发送数据给MCU。只要MCU的UART1接收到完整的数据(比如8个字节)后,立即从UART1返回数据(也是8个字节)给发送者,未收到数据时或接收数据不完整均不发送任何数据。主机数据不是连续发送的,但这一帧数据(8个字节)是连续发送的。MCU要侦测是否是完整帧,不是完整帧就丢弃。
问题:
    如何保持接收寄存器处于待命状态,等待主机发送指令,为何程序中的dummy&0x20一直有信号,根据STM8s控制器参考手册中说明,读取状态寄存器后再读取接收数据寄存器状态寄存器中的RXNE应该为0,即读取完指定长度的数据后,该位不应该再为1,接收中断处于待命状态,MCU也不会主动发送任何数据.
    实际情况:从复位开始要接收到9个字节后才能返回数据,以后每收到1个字节就返回发送缓冲区的所有字节。
备注:
主程序在初始化时完成后,打开了接收中断。
有谁有好的方法达到预期目的吗?还请不吝赐教。
沙发
香水城| | 2009-11-18 14:19 | 只看该作者
程序逻辑有问题!

当(dummy & 0x20)!=0 并且 RxCounter >= BufferSize 时,没有读DR,接收标记不能被清除。

使用特权

评论回复
板凳
stm_zy|  楼主 | 2009-11-18 14:29 | 只看该作者
程序逻辑有问题!

当(dummy & 0x20)!=0 并且 RxCounter >= BufferSize 时,没有读DR,接收标记不能被清除。
香水城 发表于 2009-11-18 14:19

又试过读取DR,问题依旧。

使用特权

评论回复
地板
香水城| | 2009-11-18 14:50 | 只看该作者
请你改成这样的结构:

if  (dummy & 0x20)
     /* 从接收数据寄存器中读取一个字节 */
     RxBuffer[RxCounter++] = UART1->DR;

if (RxCounter >= BufferSize)
   ......

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
stm_zy + 1 感谢热心帮助!
5
stm_zy|  楼主 | 2009-11-18 15:36 | 只看该作者
请你改成这样的结构:

if  (dummy & 0x20)
     /* 从接收数据寄存器中读取一个字节 */
     RxBuffer[RxCounter++] = UART1->DR;

if (RxCounter >= BufferSize)
   ......
香水城 发表于 2009-11-18 14:50

这样改过之后,只要接收数据够8字节,发送就会一直进行,不会自动停止。

使用特权

评论回复
6
香水城| | 2009-11-18 16:00 | 只看该作者
这是因为你一直没有停止发送。

使用特权

评论回复
7
stm_zy|  楼主 | 2009-11-27 07:50 | 只看该作者
经过这几天的琢磨,终于搞定了。结贴。
ST啊,真折磨人。
连例子程序都没讲清楚串口的使用,还让大家用,晕~~~~~

使用特权

评论回复
8
ploto| | 2009-12-3 15:24 | 只看该作者
建议楼主演习一下状态机。不然稍微复杂一点就死定了。

使用特权

评论回复
9
276069874| | 2014-2-11 10:56 | 只看该作者
请问楼主是怎么解决的啊?求解释

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

60

帖子

0

粉丝