OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4066|回复: 2

发送中断库函数形式变寄存器形式后,程序无法进接收中断

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
26
金钱
26
注册时间
2013-12-13
在线时间
0 小时
发表于 2014-10-26 11:16:41 | 显示全部楼层 |阅读模式
5金钱
写了个程序。通过一个通迅接口使得PC与下位机进行数据的收发。 发送中断用库函数形式时。有的通迅接口能正确传递数据,有的通迅接口无法正确传送。于是将发送中断变更为寄存器形式。 结果,只有第一次可以通过通迅接口正常接收与发送数据。接下来就无反应了。 经Debug,发现是程序无法进入接收中断。
这是为什么呢? 请多多指教。
void USART1_IRQHandler(void)
{
  //if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  if(USART1->SR&(1<<5))
  {
  // USART_ClearITPendingBit(USART1,USART_IT_RXNE);//steven
    USART1->SR&=~(1<<5);
    /* received data */
    USART_GetInputString();
  }
  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)  //就是这里。库函数形式。无法正确收发数据。如果变成if((USART1->SR&(1<<7))==1)。就只实现一次正确的收发。debug,发现无法进入接收中断
   {   
    /* Write one byte to the transmit data register */
    USART_SendBufferData();
  }
  
         else if(USART1->SR&(1<<6)) //(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
                 {
                       
                        //USART_ClearITPendingBit(USART1, USART_IT_TXE);         // 清除
           USART1->SR&=~(1<<7);
                        //  USART_ClearFlag(USART1,USART_FLAG_TC);
                         USART1->SR&=~(1<<6);
                 CR=1;
                 CT=0;
        //         USART1->CR1|=1<<5;
                 }
   
  
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
26
金钱
26
注册时间
2013-12-13
在线时间
0 小时
 楼主| 发表于 2014-10-26 21:14:58 | 显示全部楼层
接收中断里面的程序如下:
void USART_GetInputString()
{
     u8 mychar=0;
     
 mychar=USART1->DR;
   
 switch(receiveState)
  {
         
  case 0:               //头
     if(mychar==0x40)
   {
                   receiveState=1;
 
   ByteCount=0;
   checksum=0;
   

   }
    else
{
  receiveState=0;//状态机复位
}
      break;

  case 1:          //设备地址头高4位
     if(mychar==HexToAscii(SLAVE_ID>>4))
   {
      receiveState=2;
   checksum^=mychar;
   }
  else
{
  receiveState=0;//状态机复位
}
     break;
   case 2:          //设备地址头低4位
     if(mychar==HexToAscii(SLAVE_ID&0x0f))
   {
      receiveState=3;
   checksum^=mychar;
   }
  else
{
  receiveState=0;//状态机复位
}
     break;
 
    case 3: 
if(mychar==0x41)    //命令&标志
{
receiveState=4;
checksum^=mychar;
}
else
{
  receiveState=0;
}
     break;
case 4://到这个位置,读写分离
{
switch(mychar)   //读命令
 { case 0x30:

    receiveState=5;
  checksum^=mychar;
  //printf("\r\nthat is %x",mychar);
 
break;

case 0x31:    //写命令
  receiveState=14;
  checksum^=mychar;
                
     break;
               default: 
    receiveState=0;
      break;
  }
}
     break;
/*Read command*/  
case 5://读命令30    数据地址
 if(mychar==0x30)
  {
    receiveState=6;
  checksum^=mychar;
  //  printf("\r\nthat is %x",mychar);
  }
 else
  {
    receiveState=0;
  }
     break;
case 6: //30
 if(mychar==0x30)
  {
    receiveState=7;
  checksum^=mychar;
//  printf("\r\nthat is %x",checksum);
  }
 else
  {
    receiveState=0;
  }
     break;
case 7: //4 //from this ,dynamic & static 
     {
 switch(mychar)  
 { case 0x43:
receiveState=8;
  checksum^=mychar;
  g_cmd=1; //动态读标志  
break;

case 0x44:
   
 receiveState=11;
   checksum^=mychar;
   
   g_cmd=2;  //静态读标志
     break;
               default: 
    receiveState=0;
      break;
 }
}
      break;
/*AYNAMIC READ*/   
  
case 8: //dynamic
  if(mychar==0x30)//30动态读低4位 
   {
     receiveState=9;
  checksum^=mychar;
 //   printf("\r\nthat is %x",mychar);
   }
  else
{
  receiveState=0;

}
      break;
     case 9:  //动态读数据长度判断高4位
     if(mychar==0x31)
      {
        receiveState=10;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
//    printf("\r\nthat is %x",mychar);
 
   }
  else
{
  receiveState=0;
}
      break;
 case 10:  //动态读数据长度判断低4位
     if(mychar==0x32)
      {
        receiveState=44;//转到校验判断程序
  checksum^=mychar;
  ByteCount<<=4;
  ByteCount+=AsciiToHex(mychar);

   }
  else
{
  receiveState=0;
}
      break;
              /*B:STATIC READ*/
              case 11:
       //static
  if(mychar==0x32)//30静态读低4位 
   {
     receiveState=12;
  checksum^=mychar;
   }
  else
{
  receiveState=0;
}
      break;
     case 12:  //静态读数据长度判断高4位
     if(mychar==0x31)
      {
        receiveState=13;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
//printf("\r\nthat is %x",mychar);
   }
  else
{
  receiveState=0;
}
      break;
 case 13:  //静态读数据长度判断低4位
     if(mychar==0x30)
      {
        receiveState=44;//转到校验判断程序
  checksum^=mychar;
 ByteCount<<=4;
 //printf("\r\nthat isfist %x",ByteCount);
  ByteCount+=AsciiToHex(mychar);
// printf("\r\nthat is %x",checksum);OK
   }
  else
{
  receiveState=0;
}
      break;
      /*Write command*/
 case 14:
  //写命令30    数据地址
 if(mychar==0x30)
  {
    receiveState=15;
  checksum^=mychar;
  }
 else
  {
    receiveState=0;
  }
     break;
case 15: //30
 if(mychar==0x30)
  {
    receiveState=16;
  checksum^=mychar;
 // printf("\r\nthe eveis%x",checksum);OK
  }
 else
  {
    receiveState=0;
  }
     break;
 case 16:
        {
  switch(mychar)   //清零地址(累积量)
  {
   case 0x43:
  receiveState=17;
  checksum^=mychar;
  g_cmd=4;  //清零标志位
break;
 
  case 0x44: //各个参数写地址
  
       receiveState=21;
checksum^=mychar;
     break;
case 0x45://测零功能调用地址
       receiveState=40;
checksum^=mychar;

     break;
  default:  
    receiveState=0;  
     break;
  }
  }
     break;
 case 17:
     if(mychar==0x45)    //清零开始
      {
        receiveState=18;
  checksum^=mychar;
  } 
     else
  {
    receiveState=0;
  }
     break;
 case 18:  //清零(累积量)的字节数,高4位
       if(mychar==0x30)
      {
        receiveState=19;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 19:  //清零(累积量)的字节数,低4位
       if(mychar==0x34)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
//  printf("\r\nthe clearsumis%x",checksum);//OK
  } 
     else
  {
    receiveState=0;
  }
     break;

case 21:  //写参数各个系数数据地址末4位
        {
    switch(mychar)  //写系数
        {

 case 0x32: 
          receiveState=22;
  checksum^=mychar;
 g_cmd=5;//系数标志位
  break;
       
  case 0x36: //写恒定速度
  
     receiveState=25;
  checksum^=mychar;
  g_cmd=6; //速度标志位
          break;
  case 0x38: //写流量限值
  
     receiveState=28;
  checksum^=mychar;
  g_cmd=7; //流量限值标志位
          break;
  case 0x41: //写零点
  
     receiveState=31;
  checksum^=mychar;
  g_cmd=8;//静态零点标志位
          break;
                 case 0x43: //写测零时间
  
     receiveState=34;
  checksum^=mychar;
  g_cmd=9; //测零时间标志位
         break;
         case 0x45: //写空态界限
  
     receiveState=37;
  checksum^=mychar;
 g_cmd=10;//空态界限标志位
          break;
  
 default:  
    receiveState=0;  
 break;
    }
  }
 break;
 case 22:  //具体写系数的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=23;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 23:  //写系数的字节数长度,低4位
       if(mychar==0x34)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
 // printf("OK");
  }
     break;

 case 25:  //具体写速度的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=26;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 26:  //写速度的字节数长度,低4位
       if(mychar==0x32)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
  }
     break;
 
case 28:  //具体写流量限值的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=29;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 29:  //写流量限值的字节数长度,低4位
       if(mychar==0x32)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
  }
     break;

 case 31:  //具体写零点的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=32;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 32:  //写零点的字节数长度,低4位
       if(mychar==0x32)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
  }
     break;
    
 case 34:   
   //具体写测零时间的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=35;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 35:  //写测零时间的字节数长度,低4位
       if(mychar==0x32)
      {
        receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
  }
     break;

 case 37:   
  //具体写空态界限的字节数长度  高4位
      if(mychar==0x30)
      {
        receiveState=38;
  checksum^=mychar;
  ByteCount=AsciiToHex(mychar);
  ByteCount<<=4;
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 38:  //写空态界限的字节数长度,低4位
       if(mychar==0x32)
      {
        //receiveState=39;
    receiveState=43;
  checksum^=mychar;
  ByteCount+=AsciiToHex(mychar);
  } 
     else
  {
    receiveState=0;
  }
     break;

    /***************测零与CPU复位功能的调用*******************/
case 40:
     if(mychar==0x30)
      {
        receiveState=41;
  checksum^=mychar;
  } 
     else
  {
    receiveState=0;
  }
     break;
  //此处是为了增加测零与CPU复位功能的区别而修改
            case 41:  //测零(累积量)的字节数,30 32
       if(mychar==0x30)
      {
        receiveState=42;
  checksum^=mychar;
 
  
  } 
     else
  {
    receiveState=0;
  
  }
     break;
 case 42:  //测零(累积量)的字节数,30   32
       if(mychar==0x32)
      {
        receiveState=47;
  checksum^=mychar;
 
  } 
     else
  {
    receiveState=0;
  }
     break;

            case 47:
    if(mychar==0x30)
      {
        receiveState=48;
  checksum^=mychar;
 
  } 
     else
  {
    receiveState=0;
  }
     break;
    case 48:
    if(mychar==0x30)
      {
        receiveState=49;
  checksum^=mychar;
 
  } 
     else
  {
    receiveState=0;
  }
     break;
case 49:
    if(mychar==0x30)
      {
        receiveState=50;
  checksum^=mychar;
 
  } 
     else
  {
    receiveState=0;
  }
     break;
case 50:
 
    {
switch(mychar)  //表明调用的是测零功能。
     {
     case 0x31:
         g_cmd=3;//测零标志位
     receiveState=44;
   checksum^=mychar;
       break;
    
    case 0x32:

  g_cmd=11;  //    cpu复位标志位
       receiveState=44;
  checksum^=mychar;
  break;
default:
 receiveState=0;
 break;
}
}
   break;

  /**************数据接收端*******************/  
 case 43:  
 USART_Rx_Buffer[USART_Rx_ptr_in++]=mychar;
   
checksum^=mychar;

if(USART_Rx_ptr_in==(ByteCount<<1))  //当协议中,数据长度为定长时。
{
                           receiveState=44;
   
}
   break;
   
/***********CRC&END*************************/   
 case 44: //动态读命令的异或校验值得比较
       if((HexToAscii(checksum>>4))==mychar)//higt 4 bit
        {
        receiveState=45;
     }
   else  
{
//Error();//
    USART_Rx_Buffer_Clear();
receiveState=0;

}
      break;
 case 45: //动态读命令的异或校验值得比较
       if((HexToAscii(checksum&0x0f))==mychar)//low 4 bit
        {
        receiveState=46;//下一步就是帧的结束位
        }
   else 
{
//Error();
USART_Rx_Buffer_Clear();
receiveState=0;

}
      break;

 case 46:
      if(mychar==0x0D)
       {
          


Analyze_command();
   
   
       }
   
      USART_Rx_Buffer_Clear();
    receiveState=0;
 
 break;
  default:
        break;
  }

        
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-10-26 22:43:14 | 显示全部楼层
建议你先搞通串口(接收与发送)再说。
贴这么长代码,没几个有耐心去看完的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 21:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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