ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU
查看: 407|回复: 23
收起左侧

[STM8] 使用中断进行串口通信时候一个字节可以通信,多字节就.....

[复制链接]
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-21 17:55 | 显示全部楼层 |返回版面|阅读模式
使用中断进行串口通信时候一个字节可以通信,多字节发送出来的数据就不对了,什么原因呢?感觉RxBuffer[ UART_RX_NUM] = UART1_ReceiveData8();这一段数据存不进去,求教



INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18){
   u8 Res,i,len1;

if(UART1_GetITStatus(UART1_IT_RXNE)!= RESET)                     
        UART1_ClearITPendingBit(UART1_IT_RXNE);
          RxBuffer[ UART_RX_NUM] = UART1_ReceiveData8();
          UART_RX_NUM++;

      while(( UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
          for(i=0;i<UART_RX_NUM;i++)
           {
             UART1_Send_Byte(RxBuffer[i]);
           }

            UART_RX_NUM=0;  


}

     

481

主题

2万

帖子

7万

积分

版主

发表于 2017-4-21 18:20 | 显示全部楼层 |返回版面
UART1_Send_Byte(RxBuffer[i]);
这个函数里面怎么写的呢
欢迎进入21IC论坛
电子工程师技术交流群:16519783,124545085;
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-21 21:22 | 显示全部楼层 |返回版面
mmuuss586 发表于 2017-4-21 18:20
UART1_Send_Byte(RxBuffer);
这个函数里面怎么写的呢

这个就是库函数里发送8字节的函数 我直接调用的他
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-21 23:08 | 显示全部楼层 |返回版面
      while(( UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
          for(i=0;i<UART_RX_NUM;i++)
           {
             UART1_Send_Byte(RxBuffer[i]);/*----------------------------数据互相覆盖了*/
           }
     

25

主题

2483

帖子

7676

积分

高级工程师

发表于 2017-4-21 23:42 | 显示全部楼层 |返回版面
楼主的代码跟谁学的,这么666
本人熟悉STM32、PIC、AVR等嵌入式软件开发;联系方式:524716771.
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 08:40 | 显示全部楼层 |返回版面
yklstudent 发表于 2017-4-21 23:42
楼主的代码跟谁学的,这么666

自己在摸索,哪里的问题呢
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 08:47 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-21 23:08
while(( UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
          for(i=0;i

我试了发送一个字节可以正常,两个就数据不对了,是发送不能用这个函数吗?求教
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 08:57 | 显示全部楼层 |返回版面
歇斯底里 发表于 2017-4-21 21:22
这个就是库函数里发送8字节的函数 我直接调用的他

void UART1_Send_Byte(u8 byte)
{
    UART1_SendData8(byte);//UART1发送8位数据
    while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET);//等待发送完成
}
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 09:10 | 显示全部楼层 |返回版面
你的逻辑有问题。
接收到第一个字节你发送1字节,
接收到第二个字节你发送2字节,会导致后面接收的数据被覆盖掉(它在等待发送完成,不能及时接收)
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 09:26 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-22 09:10
你的逻辑有问题。
接收到第一个字节你发送1字节,
接收到第二个字节你发送2字节,会导致后面接收的数据被覆 ...

那就是while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET) 等待发送完成的不要吗
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 09:54 | 显示全部楼层 |返回版面
歇斯底里 发表于 2017-4-22 09:26
那就是while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET) 等待发送完成的不要吗

关键不是它。
而是,你在一个ISR里面有后果未知的等待行为。
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 09:55 | 显示全部楼层 |返回版面
void UART1_Send_Byte(u8 byte)
{
    UART1_SendData8(byte);//UART1发送8位数据
    while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET);//等待发送完成
}
这段里面也有等待。
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 10:15 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-22 09:54
关键不是它。
而是,你在一个ISR里面有后果未知的等待行为。

我试了把ISR里等待不要直接收到就发送出去 然后发送函数里也不要等待,  看得结果好像还是被覆盖了,发多个字节的时候
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 10:32 | 显示全部楼层 |返回版面
歇斯底里 发表于 2017-4-22 10:15
我试了把ISR里等待不要直接收到就发送出去 然后发送函数里也不要等待,  看得结果好像还是被覆盖了,发多 ...

收一个字节,发多个字节-------发送的时间肯定不够你难道就没有想过?
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 11:30 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-22 10:32
收一个字节,发多个字节-------发送的时间肯定不够你难道就没有想过?

难道是接受完给个延时吗,然后在发送
     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 11:32 | 显示全部楼层 |返回版面
歇斯底里 发表于 2017-4-22 11:30
难道是接受完给个延时吗,然后在发送

如果对方不受你控制,就不能延时

1

主题

84

帖子

252

积分

中级技术员

发表于 2017-4-22 15:11 | 显示全部楼层 |返回版面
发送每个字节之前都要查发送是否完成,while(UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET);//等待发送完成
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 16:23 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-22 11:32
如果对方不受你控制,就不能延时

我这样修改了下,在中断里写接收到了2个字节的数据 就把标志位flagTxd置1,主函数里判断flagTxd是否置1,然后把数据给发出来,这样是收发没问题的,但是 if(UART_RX_NUM==2)这个计数的条件 我换成大于等1他就是一个字节正常收发,大于等于2他就是两个字节正常收发,多了少了都发的接受错误的数据,感觉 RX_MUN没有在2个函数同步操作,我想不通原因,纠结了好久



INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
      //u8 Res,i;
      if(UART1_GetITStatus(UART1_IT_RXNE)!= RESET)                     
          RxBuffer[ UART_RX_NUM++] = UART1_ReceiveData8();
         if(UART_RX_NUM==2)
         {
          flagTxd=1;
         }
        UART1_ClearITPendingBit(UART1_IT_RXNE);



int main( void )
{
     u8 i,len1;
  //u8 ad[4],i;
  //fp32 cc=3.14;
  sysInit();
   while(1)
  {
     
   if(flagTxd==1)
       {
        // len1=UART_RX_NUM;        //得到此次接收到的数据长度
       //UART1_Send_Byte(len1);
  
         
      for(i=0;i<UART_RX_NUM;i++)
        {
           UART1_Send_Byte(RxBuffer);
          }
         delay_us(50);
  
          UART_RX_NUM=0;       
          flagTxd=0;
         
       }


     

104

主题

8142

帖子

2万

积分

技术总监

发表于 2017-4-22 16:31 | 显示全部楼层 |返回版面
UART_RX_NUM,flagTxd 这些变量,都在ISR和main两边有读写操作,容易产生同步问题。
特别的,flagTxd 在main里面从检测到,到使用结束,过了很长时间,出问题的机会大大增加。
     

21

主题

69

帖子

217

积分

中级技术员

 楼主| 发表于 2017-4-22 16:54 | 显示全部楼层 |返回版面
戈卫东 发表于 2017-4-22 16:31
UART_RX_NUM,flagTxd 这些变量,都在ISR和main两边有读写操作,容易产生同步问题。
特别的,flagTxd 在mai ...

那这样有什么好的解决方法吗,求教
您需要登录后才可以回帖 登录 | 注册 手机登录

本版积分规则

分享 快速回复 返回顶部 返回列表