野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12836|回复: 2

STM32F429串口4的一个诡异问题

[复制链接]
发表于 2017-11-7 10:04:45 | 显示全部楼层 |阅读模式
在使用串口4的时候发现一个问题,查了好久不知道是什么原因,麻烦有知道的前辈们指点下。在串口4的中断中接收数据,如果我在接收一个字节后,立马把收到的这个字节发出去,就没有问题,如果我把数据放在缓冲区存起来,收完后在往回发,就卡死了,经过仿真,发现是SR寄存器的TC位一直是发送未完成(=0)
u8 Rxbuff[100];
u8 RxCnt=0;
u8 RxBit=0;

/*
   USART初始化
*/
void myUSART_Init(USART_TypeDef *USARTx,uint32_t USART_BaudRate)
{

        float fraction=0;
        u16 mantissa;
        if((USARTx==USART1)||(USARTx==USART6))
          fraction = 90000000/(USART_BaudRate*16);  //计算出USARTDIV
        else
       fraction = 45000000/(USART_BaudRate*16);  //计算出USARTDIV
        mantissa = fraction;              //计算出整数部分
        fraction = (fraction-mantissa)*16;//计算出小数部分
        mantissa<<=4;
        mantissa+=fraction;
  if(USARTx == USART1)
       RCC->APB2ENR|=1<<4;            //使能串口1时钟
  else if(USARTx == USART6)
       RCC->APB2ENR|=1<<5;            //使能串口6时钟
  else if(USARTx == USART2)
        RCC->APB1ENR|=1<<17;          //使能串口2时钟
  else if(USARTx == USART3)
        RCC->APB1ENR|=1<<18;          //使能串口3时钟
  else if(USARTx == UART4)
        RCC->APB1ENR|=1<<19;          //使能串口4时钟
  else if(USARTx == UART5)
        RCC->APB1ENR|=1<<20;          //使能串口5时钟
  else if(USARTx == UART7)
        RCC->APB1ENR|=1<<30;          //使能串口7时钟
  else if(USARTx == UART8)
        RCC->APB1ENR|=(u32)1<<31;          //使能串口8时钟

        //波特率设置
        USARTx->BRR = mantissa;

        USARTx->CR1&=~(1<<15);         //设置OVER8=0
        USARTx->CR1 &= ~(1<<12); //M位=0:1起始位 8数据位 n停止位
        USARTx->CR1 |= 1<<5;    //接收中断使能  RXNELE
        USARTx->CR1 |= 1<<4;    //空闲中断使能  IDLEIE=1
        USARTx->CR1 |= 1<<3;     //TE=1 发送使能
        USARTx->CR1 |= 1<<2;     //RE=1 使能接收器
        USARTx->CR1|=1<<13;             //UE=1串口使能
}



void Uart4_Init(void)
{
          /* UART4初始化 */
        RCC->AHB1ENR |= 1<<0;  //PA
        RCC->AHB1ENR |= 1<<5;  //PF
        Set_GPIO(GPIOA,GPIO_Pin_0|GPIO_Pin_1,GPIO_Mode_AF,GPIO_OType_PP,GPIO_Fast_Speed,GPIO_PuPd_UP);
        Set_GPIO_AF(GPIOA,0,8);
        Set_GPIO_AF(GPIOA,1,8);
        myUSART_Init(UART4,115200);
        MY_NVIC_PriorityGroupConfig(2);
        MY_NVIC_PriorityConfig(0,0,UART4_IRQn,2); // 抢占0 子0 分组0
}

void UART4_SendMultiByte(u8 *str)
{
        do
        {
                while(!(UART4->SR & 1<<6)); //仿真发现程序一直卡在这里
                UART4->DR = *str++;
        }while(*str != '\0');
}

/*
   UART4中断函数
*/
void UART4_IRQHandler(void)
{
  if(UART4->SR & 1<<5) //接收中断  RXNE=1
        {
                Rxbuff[RxCnt++] =UART4->DR;
//                while(!(UART4->SR & 1<<6));     //在这把收到的一个字节往回发是没有问题的
//                UART4->DR = Rxbuff[RxCnt-1];
        }
        if(UART4->SR &= 1<<4)  //空闲中断
        {
                Rxbuff[RxCnt] =UART4->DR;
                Rxbuff[RxCnt] = '\0';
                RxCnt = 0;
                RxBit =1;
                UART4_SendMultiByte(Rxbuff);//不管是在此处还是在主函数发送接收到的数据都会卡死
        }
}

回复

使用道具 举报

 楼主| 发表于 2017-11-7 10:05:40 | 显示全部楼层
如果我把UART4改成USART1是没有一点问题的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-7 10:58:02 | 显示全部楼层
已解决,改成如下方式就行,此方式用在USART上会丢失第一个字节
UART4->DR = *str++;
while(!(UART4->SR & 1<<6));
               
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-9-23 23:31 , Processed in 0.045017 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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