打印
[STM32F1]

STM32串口接收和发送程序,一直产生接收溢出错误

[复制链接]
10988|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang12zhe|  楼主 | 2014-5-29 13:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wang12zhe 于 2014-5-29 13:38 编辑

void USART_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
   //GPIO 和USART的相关时钟都已经使能, 这部分代码在其他部分,此处没贴出来
    /* Configure USART2 Tx (PA.02)\USART1 Tx (PA.09) as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_AF_PP;  复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure USART2 Rx (PA.03)/USART1 Rx (PA.10) as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);        
    /* Configure USART2 */
    USART_DeInit(USART2);
    //USART_InitStructure.USART_BaudRate = BaudLink[Sci2.BaudSel];
    USART_InitStructure.USART_BaudRate = 19200;
    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_None;
    USART_InitStructure.USART_Mode =USART_Mode_Rx|USART_Mode_Tx;
    /* Configure USART2 */
    USART_Init(USART2, &USART_InitStructure);
    /* Enable USART2 Receive and Transmit interrupts */
    USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//DISABLE
    USART_ITConfig(USART2, USART_IT_TXE, ENABLE);  //使能发送寄存器空中断,区分于发送完成中断
    /* Enable the USART2 */
    USART_Cmd(USART2, ENABLE);

}   




void sys_reset_time_handle(u8 uc_cmd,u16 us_count)   
{
  //if(TxCnt<5000)
  //TxCnt++;
  TxBuffer1[0]=0x01;
  TxBuffer1[1]=uc_cmd;
  TxBuffer1[2] = 0X00;
  TxBuffer1[3] = 0X8B;    //参数存储位置:P9.11  地址:155  
  TxBuffer1[4]=us_count >> 8;        
  TxBuffer1[5]=us_count & 0XFF;
  TxBuffer1[6]=GetCRC16(TxBuffer1,6);
  TxBuffer1[7]=GetCRC16(TxBuffer1,6)>>8;

  USART_ITConfig(USART2, USART_IT_TXE, ENABLE);  


}



    int main(void)
{
  u16  us_reset_count;
  volatile u16  us_delay_count;
  u8   uc_update_ok=0;
  u8   uc_read_ok = 0;

    //设备初始化
    DeviceInit();  
    InitDelayTime = 200;

//===========增加看门狗复位次数处理=====
//思路:当系统上电后,读出DSP里存储的系统启动次数信息,加一后再传给DSP进行存储
//     注意需要增加该信息复位处理,实现系统启动次数的手动复位
//==============================
//

while(!uc_read_ok){   //使用while循环,直到读取数据正确
         Sci1.TxCouter = 0;
          Sci1.state.ParSet = 0;
    Sci1.state.CmdSet = 0;
    Sci1.state.ComType = 3;
  sys_reset_time_handle(0X03,0);//读出参数

while(uc_g_TX_time);    //uc_g_TX_time 在SysTick中断里减一,每个0.2ms触发一次SysTick中断
   uc_g_TX_time=40;

    if(RxBuffer1[1]==0x03){  //如果RxBuffer1[1]==0x03 表明接收数据正确
     us_reset_count = RxBuffer1[4];
     us_reset_count= us_reset_count<<8+ RxBuffer1[5];
            us_reset_count ++;   //复位次数加1
     uc_read_ok =1;
            while(!uc_update_ok){
           Sci1.state.ParSet = 0;
           Sci1.state.CmdSet = 1;
          Sci1.state.ComType = 6;
          sys_reset_time_handle(0X06,us_reset_count);
             us_delay_count=5000;
             while(us_delay_count--){
              if(0==us_delay_count%1000){
                IWDG_ReloadCounter();//喂狗
            }      
      }
       if(RxBuffer1[1]==0x06){
           uc_update_ok = 1;
      }
     }
  }else{
    Sci1.state.RxEnFlag =0;
          }
}




void USART2_IRQHandler(void)
{
       u8 datatemp;

  if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)    //接收溢出中断
     {

       (u16)(USART2->DR & (u16)0x01FF);   
     }

  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //产生接收中断
  {
    USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清除中断标志位
    /* Read one byte from the receive data register */
    datatemp = USART_ReceiveData(USART2);

    //testbuff[cnt++] = datatemp;
    //if(cnt>7) cnt = 0;

    if( Sci1.state.RxEnFlag==1 )
    {
      if( Sci1.RxCouter==0 )
      {
        if( Sci1.FrameTimeCnt>Sci1.FrameIntervalCnt1 )
        {
          Sci1.FrameTimeCnt = 0;
          if( (datatemp==Sci1.CtlAdd) )
          {
            *(Sci1.RxPoint+Sci1.RxCouter) = datatemp;
            Sci1.RxCouter++;
          }
          else
          {
            Sci1.RxCouter = 0;
          }
        }
        else
        {
          Sci1.RxCouter = 0;
          Sci1.FrameTimeCnt = 0;
        }
      }
      else if( Sci1.RxCouter>=Sci1.MaxCnt )
      {      
        if( Sci1.FrameTimeCnt>Sci1.FrameIntervalCnt1 )
        {
        }
        else
        {
          Sci1.RxCouter = 0;
          Sci1.FrameTimeCnt = 0;
        }
      }
      else
      {
        if( Sci1.FrameTimeCnt<Sci1.FrameIntervalCnt0 )
        {
          *(Sci1.RxPoint+Sci1.RxCouter) = datatemp;
          Sci1.RxCouter++;
          Sci1.FrameTimeCnt = 0;


        }
        else
        {
          Sci1.FrameTimeCnt = 0;
          Sci1.RxCouter=0;
        }
      }
    }
    else
    {
      Sci1.RxCouter = 0;
      Sci1.FrameTimeCnt = 0;   //源程序这里是== add wang 20140528
    }

  }
  if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)  //发送寄存器空中断
  {  
    wait_time=20;
    Sci1.state.TxEnFlag=1;
    if( Sci1.state.TxEnFlag==1 )
    {
      Sci1.state.RxEnFlag = 0;

      Sci1.TxMaxCnt = 8;
      if(Sci1.TxCouter ==  Sci1.TxMaxCnt)   //发送结束
      {
        Sci1.TxCouter = 0;
        Sci1.state.TxEnFlag = 0;
        Sci1.state.RxEnFlag = 1;
       // USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清除中断标志位      
        USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
        Sci1.state.RxEnFlag = 1;  // =============================能正常执行到这里,说明发送是正常结束的
     //   Sci1.state.RxOverFlag = 1;
      }   
      else  
      {
         USART_SendData(USART2,  *(Sci1.TxPoint+Sci1.TxCouter) ); //*(Sci1.TxPoint+Sci1.TxCouter)
         Sci1.TxCouter++;
      }
    }
  }
  if(USART_GetITStatus(USART2, USART_IT_ERR) != RESET)
  {
  //  USART_DeInit(USART2);
  }  
}

当发送正常结束后,就会产生接收溢出 中断 (ORE中断),而且正常情况下应该收到8个数据的,但是只产生一次接收溢出 中断 (ORE中断) ,
实在是没办法了,求解,





沙发
mmuuss586| | 2014-5-29 18:58 | 只看该作者
你这中断程序内容也太多了;
中断程序尽量简单;

你还在中断程序,嵌发送程序;

使用特权

评论回复
板凳
mmuuss586| | 2014-5-29 18:59 | 只看该作者
可能中断会响应不过来;
改下程序的结构看看;

使用特权

评论回复
地板
ar3000a| | 2014-5-29 19:25 | 只看该作者

    wait_time=20;
是什么意思? 哪里等待时间太长了。

使用特权

评论回复
5
wang12zhe|  楼主 | 2014-5-30 12:18 | 只看该作者
ar3000a 发表于 2014-5-29 19:25
wait_time=20;
是什么意思? 哪里等待时间太长了。


wait_time 是在SysTick自减的,
在一个函数里有对他的判断,但是现在这个函数根本没有调用,因此我认为这个变量没有什么实际的意义,

使用特权

评论回复
6
wang12zhe|  楼主 | 2014-5-30 12:19 | 只看该作者
mmuuss586 发表于 2014-5-29 18:59
可能中断会响应不过来;
改下程序的结构看看;

好的,这是别人的程序,我只是添加了一点想法,当死都不行,
打算自己写一个,做测试串口功能

使用特权

评论回复
7
ar3000a| | 2014-5-30 18:19 | 只看该作者
(u16)(USART2->DR & (u16)
0x01FF);
没有赋值? 看看汇编能不能产生读寄存器代码。

读一遍别人的代码好累。

使用特权

评论回复
8
runningwzf| | 2014-6-1 13:25 | 只看该作者
1、 (u16)(USART2->DR & (u16)0x01FF); 这句比较危险,不同的优化级别生成的代码不一样
2、 发送保持器空中断里面没有清除中断标志位

建议楼主简化中断服务程序,同时不建议使用发送保持器空中断,可以用DMA的方法代替

使用特权

评论回复
9
runningwzf| | 2014-6-1 13:30 | 只看该作者
在ORE处理中,建议楼主要清除掉ORE位
楼主的中断服务程序结构是
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
}
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET){
}
...
建议改成:
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
}
else if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET){
}
...

使用特权

评论回复
10
it_yrj| | 2017-4-19 12:37 | 只看该作者
接收溢出中断关了 未使用

使用特权

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

本版积分规则

101

主题

205

帖子

1

粉丝