OpenEdv-开源电子网

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

串口接收缓冲区不能清零

[复制链接]

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
发表于 2018-9-19 21:18:42 | 显示全部楼层 |阅读模式
5金钱
大家好!小弟用正点原子的例程稍加改动了一下想用串口发命令控制单片机的IO口,用下面的程序能实现。但接收缓冲区不能清零只能覆盖,例如:先发“asddfer",后发”zxc"缓冲区的数据是"zxcdfer"。请各路大神指点一下,小弟在此表示万分感激!代码如下:
#include "sys.h"
#include "usart.h"
#include "string.h"

#if 1
#pragma import(__use_no_semihosting)            

struct __FILE
{
        int handle;
};

FILE __stdout;      

_sys_exit(int x)
{
        x = x;
}

int fputc(int ch, FILE *f)
{        
        while((USART1->SR&0X40)==0);
        USART1->DR = (u8) ch;      
        return ch;
}
#endif
#if EN_USART1_RX   
char USART_RX_BUF[USART_REC_LEN];   

u16 USART_RX_STA=0;   



void My_USART2_Init(void)
{
          GPIO_InitTypeDef  GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//ê1ÄüUSART1ê±Öó
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
       
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        USART_InitStructure.USART_BaudRate=115200;
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
        USART_InitStructure.USART_Parity=USART_Parity_No;
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
       
        USART_Init(USART2,&USART_InitStructure);
        USART_Cmd(USART2 ,ENABLE);

       
#if EN_USART1_RX       
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

       
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;               
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                       
        NVIC_Init(&NVIC_InitStructure);       
}
#endif
        void USART2_IRQHandler(void)
        {
      u8 Res;

        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {
                Res =USART_ReceiveData(USART2);//(USART1->DR);
               
                if((USART_RX_STA&0x8000)==0)
                {
                        if(USART_RX_STA&0x4000)
                        {
                                if(Res!=0x0a)USART_RX_STA=0;
                                else USART_RX_STA|=0x8000;       
                        }
                        else //»1ûêÕμ½0X0D
                        {       
                                if(Res==0x0d)USART_RX_STA|=0x4000;
                                else
                                {
                                        USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                                        USART_RX_STA++;
                                        if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
                                }                 
                        }
                }                    

        }               
}
#endif
u8 shibie()
{
        // u8 len=50;
         //u8 t;
         char str[]={"B1ON"};
         char abc[]={"B1OFF"};
         char bcd[]={"B2ON"};
         char cda[]={"B2OFF"};

         const char *a ,*b,*c,*d,*e;
         
  a=USART_RX_BUF;
//        clear();
  b=str;
        c=abc;
  d=bcd;
  e=cda;
        //len=USART_RX_STA&0x3fff;
//        for(t=0;t<len;t++)
//        {
//       
//          USART_RX_BUF[t]=0;
//       
//        }
//         
       
        if(!strcmp(a,b)) return 1;
       

    else if(!strcmp(a,c )) return 2;
    else if(!strcmp(a,d )) return 3;
          else if(!strcmp(a,e )) return 4;
          return 9;
}

//   void clear()
//         {
//            u8 t;
//                  u8 len=50;
//                  for(t=0;t<len;t++)
//        {
//       
//          USART_RX_BUF[t]=0;
//       
//          }
//         
//         }
         这段是usrat.文件。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"



int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
       
        delay_init(168);       
  My_USART2_Init();  
        JDQ_Init();                         
        while(1)
        {
                u8 val;
                        if(USART_RX_STA&0x8000)
                {               
                       
                       
                   USART_RX_STA=0;
                       
                }
       
   val=shibie();
       
                switch(val)
                {
                  case 1:
                   {
                                  GPIO_ResetBits(GPIOF,GPIO_Pin_1 );
                         }
                     break;
       case 2:
                   {
                                  GPIO_SetBits(GPIOF,GPIO_Pin_1 );
                         
                    case 3:
                   {
                                  GPIO_ResetBits(GPIOF,GPIO_Pin_3 );
                         }
                     break;
                     case 4:
                   {
                                  GPIO_SetBits(GPIOF,GPIO_Pin_3);
                         }
                     break;
                }
               
        }
}

       我本来想用clear 函数把串口缓冲区清空但不行,用了它之后一次都收不到。。。恳请各位大神帮忙。


最佳答案

查看完整内容[请看2#楼]

清零的事情,你得自己动手。 数组就是存储数据的,你都没操作数据清零,哪来的清零。 另外,你说的clear 是自己写的函数?这个问题,根本就没什么难度,仿真一下,分分钟的事情。 别纠结了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2018-9-19 21:18:43 | 显示全部楼层
清零的事情,你得自己动手。 数组就是存储数据的,你都没操作数据清零,哪来的清零。 另外,你说的clear 是自己写的函数?这个问题,根本就没什么难度,仿真一下,分分钟的事情。
别纠结了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2018-9-20 02:07:07 | 显示全部楼层
帮顶
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-20 08:02:48 | 显示全部楼层
本帖最后由 dxf728185893 于 2018-9-20 08:04 编辑

什么意思??不太懂。请明示。
回复

使用道具 举报

2

主题

756

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4163
金钱
4163
注册时间
2017-10-24
在线时间
251 小时
发表于 2018-9-20 08:46:24 | 显示全部楼层
dxf728185893 发表于 2018-9-20 08:02
什么意思??不太懂。请明示。

这个是帮你顶贴的意思。。。
有人回复你的帖子的时候,在板块中你的帖子因为有最新回复,所以就会暂时置顶显示,这样更容易被更多人看到。

你是学生吧。。。这些都是比较老旧的论坛上交流的词汇了。。。
十六进制带我飞。
回复

使用道具 举报

2

主题

756

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4163
金钱
4163
注册时间
2017-10-24
在线时间
251 小时
发表于 2018-9-20 08:49:42 | 显示全部楼层
没有必要把缓冲区清零,当完成一次接收之后,将USART_RX_STA这个变量清0即可。

因为这个变量中存储了当前已经使用的缓冲区字节个数,清零之后就会重新开始,从头对接收缓冲区进行写入操作。

另外日后发帖的时候请注意,使用编辑栏中的插入代码功能插入代码,并且删除不必要的注释添加必要的注释,有助于别人理解。不然这么长一段实在是不想看。
十六进制带我飞。
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-20 09:23:49 来自手机 | 显示全部楼层
谢谢提醒,以后会注意,也谢谢原子哥,我已经在while里面将那个全局变量清零,如果不清零的话只能接受一次。
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-20 09:33:21 来自手机 | 显示全部楼层
我要用USART_RX_BUF数组里面的数据,将USART_RX_STA清零应当不会清除数组里面的数据,只会让下次好接受数据吧。
回复

使用道具 举报

14

主题

204

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2443
金钱
2443
注册时间
2017-9-13
在线时间
559 小时
发表于 2018-9-20 09:34:17 | 显示全部楼层
这个不需要清零
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-20 09:46:53 来自手机 | 显示全部楼层
如果USART_RX_BUF数组不清零,第二次接受的会覆盖第一次接受的数据。例如:先发“asddfer",后发”zxc"缓冲区的数据是"zxcdfer
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-20 10:46:24 来自手机 | 显示全部楼层
如果接受完成了,程序应该会执行       if(USART_RX_STA&0x8000)                 {                                                                                      USART_RX_STA=0;                                          }         ,但我用单步追踪调试没有进入这段代码,这很奇怪如果没有进入的话USART_RX_STA就不会清零。就下能接受第二次,但实际上是能接受第二次。如果我把USART_RX_STA=0;这行注释掉,编译后程序就不会接受第二次,那证明这句代码是被执行了的,但为何单步调试进入不了这段代码。
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-21 09:38:46 来自手机 | 显示全部楼层
是我表述不够清楚吗?为何没有回我?在线急等!!!!
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-21 09:52:10 来自手机 | 显示全部楼层
是不是我没有将问题表述清楚?为何没人回答?在线急等!!!!
回复

使用道具 举报

34

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
857
金钱
857
注册时间
2018-9-16
在线时间
240 小时
发表于 2018-9-21 10:57:17 | 显示全部楼层
串口中断服务函数没清那个SR的标志位吧
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-21 11:38:42 来自手机 | 显示全部楼层
那个sr标志位读取数据时不是自动清掉了吗?
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-21 13:44:47 来自手机 | 显示全部楼层
多谢各位的回帖,还是希望原子哥能现身指点指点
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-22 08:44:29 来自手机 | 显示全部楼层
请各位帮助我解决问题,在下感激不尽!!!!
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-22 08:54:02 来自手机 | 显示全部楼层
我这个问题12年有人问过,跟我的问题一样,但好像没有得到解决。
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-22 10:13:37 来自手机 | 显示全部楼层
跪求原子哥出马!
回复

使用道具 举报

18

主题

323

帖子

1

精华

高级会员

Rank: 4

积分
935
金钱
935
注册时间
2017-12-11
在线时间
196 小时
发表于 2018-9-23 21:40:17 | 显示全部楼层
字符串 = "xxxxxx"+'\0';      发送字符串 "xxxxxx"+回车(0D 0A); 没有是不会接收完的;  更不会认为其有效;
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-12-29
在线时间
22 小时
 楼主| 发表于 2018-9-23 23:31:33 来自手机 | 显示全部楼层
谢谢大家回复,这个问题已给解决了
回复

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2019-5-16
在线时间
28 小时
发表于 2019-7-31 10:35:28 | 显示全部楼层
dxf728185893 发表于 2018-9-23 23:31
谢谢大家回复,这个问题已给解决了

楼主你的串口缓冲区不能清零问题解决了,怎么搞的?新人求带。
回复

使用道具 举报

3

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2022-6-23
在线时间
15 小时
发表于 2022-8-9 16:36:32 | 显示全部楼层
兄弟 请问一下,串口接收缓冲区不能清零这个你是怎么解决的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 09:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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