OpenEdv-开源电子网

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

串口接收一次数据之后不能接收第二次

[复制链接]

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
发表于 2017-12-28 09:05:07 | 显示全部楼层 |阅读模式
20金钱
用的F3的板子,在调试串口的时候,串口的发送是没问题的,但是在接收数据的时候,第一次接收也是正确的,但是之后再接收的时候,程序在“while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);”一直循环,走不出去,也就读不了数据了,程序也没办法接着走下去。请问有没有大佬遇到过这种问题,可以帮忙解决一下,万分感谢!!!


串口初始化如下:
void USART_Config(void)
{
  USART_InitTypeDef USART_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStruct;

  /* Enable GPIOB clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB , ENABLE);

  /* Enable USART1 APB clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  /* USART2 Pins configuration **************************************************/
  //GPIO_DeInit(GPIOB);

  /* Configure pins as AF pushpull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;//GPIO_PuPd_UP                                                                                
  GPIO_Init(GPIOB, &GPIO_InitStructure);         
        
   /* Connect pin to Periph */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_7);   
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_7);

  USART_DeInit(USART1);
  USART_InitStructure.USART_BaudRate = 115200;
  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;
  USART_Init(USART1, &USART_InitStructure);

    /* USART enable */
  USART_Cmd(USART1, ENABLE);                                                                                                        
        
        
        
    /*·······串口时钟配置·············******************************/
  USART_ClockStructInit(&USART_ClockInitStruct);
USART_ClockInit(USART1,&USART_ClockInitStruct);        


}

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

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 09:06:29 | 显示全部楼层
我用的是F3的板子,代码基本上是从例程里复制过来的,结果就是MCU发送没问题,接收只能接收一次数据,然后标志位就不清零了。我用示波器看了,MCU接收端口的输入信号波形是对的,希望有经验的大佬解决一下,谢谢!!!
回复

使用道具 举报

0

主题

207

帖子

0

精华

高级会员

Rank: 4

积分
959
金钱
959
注册时间
2017-5-27
在线时间
108 小时
发表于 2017-12-28 09:11:43 | 显示全部楼层
/* Configure pins as AF pushpull */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//GPIO_PuPd_NOPULL;//GPIO_PuPd_UP                                                                                   GPIO_Init(GPIOB, &GPIO_InitStructure);         
回复

使用道具 举报

0

主题

207

帖子

0

精华

高级会员

Rank: 4

积分
959
金钱
959
注册时间
2017-5-27
在线时间
108 小时
发表于 2017-12-28 09:12:21 | 显示全部楼层
lanlzp 发表于 2017-12-28 09:11
/* Configure pins as AF pushpull */   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;   GPIO_ ...

为什么都配推挽模式呢?
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 09:39:49 | 显示全部楼层
lanlzp 发表于 2017-12-28 09:12
为什么都配推挽模式呢?

串口的配置我都是从例程里面抄过来的,我这里的问题时因为配置的模式不对吗?谢谢
回复

使用道具 举报

0

主题

207

帖子

0

精华

高级会员

Rank: 4

积分
959
金钱
959
注册时间
2017-5-27
在线时间
108 小时
发表于 2017-12-28 10:27:30 | 显示全部楼层
一条咸鱼 发表于 2017-12-28 09:39
串口的配置我都是从例程里面抄过来的,我这里的问题时因为配置的模式不对吗?谢谢

串口RX应该配成浮空输入呀
回复

使用道具 举报

0

主题

7

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
400
金钱
400
注册时间
2017-3-8
在线时间
95 小时
发表于 2017-12-28 10:27:47 | 显示全部楼层
可能没有清中断标志?
回复

使用道具 举报

0

主题

113

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3321
金钱
3321
注册时间
2017-12-14
在线时间
406 小时
发表于 2017-12-28 10:44:12 | 显示全部楼层
我觉得你应该把接收那部分的程序发出来
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 16:34:03 | 显示全部楼层
lanlzp 发表于 2017-12-28 10:27
串口RX应该配成浮空输入呀

我刚刚按照您说的方法试了一下,结果也是不行的。这里配置成AF备用模式,好像是因为这两个引脚是复用功能,所以这样配置的。
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 16:35:42 | 显示全部楼层
半月琴 发表于 2017-12-28 10:27
可能没有清中断标志?

我这里没有使用中断接收。但是我后来写了一个中断,也有清除中断标志位的操作,最后还是不能实现
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 16:36:48 | 显示全部楼层
feichangkunge 发表于 2017-12-28 10:44
我觉得你应该把接收那部分的程序发出来

这是我后来写的接收中断的程序,麻烦您看一下,谢谢。

void USART1_IRQHandler (void)
{
  uint8_t ucTemp;
        //USART_ClearITPendingBit(USART1,USART_IT_RXNE);
        if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
        {               
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                ucTemp = USART_ReceiveData(DEBUG_USARTx);
    USART_SendData(DEBUG_USARTx,ucTemp);   
        }         
}
回复

使用道具 举报

1

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2011-12-1
在线时间
110 小时
发表于 2017-12-28 17:03:57 | 显示全部楼层
要这样子,肯定是可以的。
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)         //USART_IT_RXNE 接收数据寄存器非空标志位
    {               
                Value=USART_ReceiveData(USART1);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);          //发送完成标志位 ,没有发送完成继续等待发送完              
    }
专业从事软硬件设计,毕业设计,C51/AVR/MSP430/STM32等单片机软硬件制作与定制。有需求的可以联系我。QQ:3436737049淘宝店铺:龙隽电子科技
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-28 19:36:29 | 显示全部楼层
xlong_06 发表于 2017-12-28 17:03
要这样子,肯定是可以的。
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)         //USART_IT_RXNE 接收 ...

请问您这个是写到中断里面的吗?我将中断里面的程序换成您的,但是还是不行,在if判断的时候回传的值是RESET,不能进入if语句,也就没有执行接收的那条语句。请问我这个是芯片出问题了么
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-12-29 00:09:13 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2011-12-1
在线时间
110 小时
发表于 2017-12-29 09:34:11 | 显示全部楼层
一条咸鱼 发表于 2017-12-28 19:36
请问您这个是写到中断里面的吗?我将中断里面的程序换成您的,但是还是不行,在if判断的时候回传的值是RE ...

你换个串口试下吧,要是不行的话,一个是你串口初始化不行,要么就是你的硬件有问题。
专业从事软硬件设计,毕业设计,C51/AVR/MSP430/STM32等单片机软硬件制作与定制。有需求的可以联系我。QQ:3436737049淘宝店铺:龙隽电子科技
回复

使用道具 举报

9

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2017-12-12
在线时间
19 小时
发表于 2017-12-29 14:51:48 | 显示全部楼层
本帖最后由 123精灵123 于 2017-12-29 14:53 编辑

你这是什么功能程序?   对应正点原子的哪个例程?
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-29 15:49:24 | 显示全部楼层
xlong_06 发表于 2017-12-29 09:34
你换个串口试下吧,要是不行的话,一个是你串口初始化不行,要么就是你的硬件有问题。

换了USART2还是一样的效果,初始化的话我试过好多次,并且还把青风的例程初始化拷贝过来了,还是没效果。最新的进展是
“uint8_t UART_Recive(void)
{       
        while(!(USART1->ISR & (1<<5)));//等待接收到数据
        return(USART1->RDR);                         //读出数据
}”
里面的“while(!(USART1->ISR & (1<<5)));”一直在循环,照理来说“RXNE”寄存器位不是应该是硬件清零的吗?我这边一直有数据发过去,但是为什么就是一直不能置位呢?非常期待您能够给予帮助,非常感谢!!
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2017-12-29 15:51:04 | 显示全部楼层
123精灵123 发表于 2017-12-29 14:51
你这是什么功能程序?   对应正点原子的哪个例程?

就是最普通的串口发送和接收的功能,不过我用的是F373的芯片,不是在正点买的
回复

使用道具 举报

0

主题

207

帖子

0

精华

高级会员

Rank: 4

积分
959
金钱
959
注册时间
2017-5-27
在线时间
108 小时
发表于 2018-1-2 14:31:46 | 显示全部楼层
换个芯片或者开发板试试
回复

使用道具 举报

9

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2017-12-12
在线时间
19 小时
发表于 2018-1-2 15:40:01 | 显示全部楼层
本帖最后由 123精灵123 于 2018-1-2 15:43 编辑
一条咸鱼 发表于 2017-12-29 15:51
就是最普通的串口发送和接收的功能,不过我用的是F373的芯片,不是在正点买的

你可以参考一下关于这段串口配置的代码,中断不用可以注释。  串口的引脚主要为发送引脚:USART1_TX   GPIOA.9,接收引脚:USART1_RX   GPIOA.10。
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
         
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟
  
        //USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX          GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

        USART_InitStructure.USART_BaudRate = bound;//串口波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        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;        //收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1

}
回复

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2017-10-12
在线时间
33 小时
 楼主| 发表于 2018-1-5 20:05:04 | 显示全部楼层
xlong_06 发表于 2017-12-29 09:34
你换个串口试下吧,要是不行的话,一个是你串口初始化不行,要么就是你的硬件有问题。

最近把串口调通了,解读寄存器之后发现是发生了过载错误,把中断函数改成下面这样能够完成接受数据,但是不知道为什么会发生过载错误,希望您可以帮忙解答一下,谢谢您啦!!

void USART1_IRQHandler (void)
{

       
        if(USART_GetITStatus(USART1,USART_IT_ORE)!=RESET)
        {               
                usart_read = USART_ReceiveData(USART1);//  usart_read是全局变量
                USART_ClearITPendingBit(USART1,USART_IT_ORE);
   
        }
       
        if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
        {               
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                usart_read = USART_ReceiveData(USART1);
        }         
}
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-19 22:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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