打印
[51单片机]

c8051f021单片机串口发送接收问题(UART0)

[复制链接]
5373|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
15056048066|  楼主 | 2015-5-5 10:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 15056048066 于 2015-5-5 16:23 编辑

       (PC用串口助手向单片机发送1个字符串,单片机接收后发回PC)UART0的通信,向单片机发送一个16进制字符串“AA  AA  01  02  FF FF”,收到后把这个字符串回发。现在的问题是,手动一个一个发,单片机可以进入UART0中断,并把字符串回发。如果1次发送2个字符或是以上,就结果是就第一个字符接收正确;而且,单看进去中断的次数,单片机都跟不上发数的次数。晶振是22.1184M,波特率是115200,后来换成9600,结果一样。如果只是单片机向上位机发送一个已知的数组,串口助手接收到的数也是正确的。       目的是实现上位机和单片机通讯,主机发送的命令格式为 6 个字节 ,包括字头、地址、功能和字尾;如“AA  AA  01  02  FF FF”,从机收到后回复相应的字符串。主要是判断接收到的字符串是不是发送的,所以就把字符串再发回主机,现在的问题是发送应该没问题,因为可以发送已知的字符串,但接收再发回的就有问题,问题应该出在接收上了,不知道这样分析可以吗?


相关帖子

沙发
15056048066|  楼主 | 2015-5-5 10:03 | 只看该作者
程序如下:
uchar flag;                                        //uart0接收到数据的标志位
uint xdata re[6];                                 //接收缓存数组

while(1)
        {
                while(flag)
                        {
                                if((re[0]==0xaa )&&(re[1]==0xaa)&&(re[2]==0x01)&&(re[3]==0x02)&&(re[4]==0xff)&&(re[5]==0xff))
                                {
                                        //LED=~LED;
                               
                                LED=0;
                                delay_(1500);
                                LED=1;         
                                delay_(1500);
                                }
                                                                                                            
                                for(j=0;j<6;j++)
                                {                                                               
                                                //printf("%02bX\n",0xff);
                                            //printf("%02bx\n",re[j]);
                                                putchar(re[j]);
                                                re[j]='\0'; //清空字符,方便下次接收                                               
                                }                                                                   
                       
                                flag=0;       
                        }
        }


void uart0_ISR() interrupt 4

{                                
        static int m= 0;                          //循环变量
        static char jishu=0;                          //循环变量                                                                                          
                        
                        if(SCON0&0x01)
                        {
                                SCON0&=0xfe;
                                if(SBUF0!='\r')
                                {
                                        if(SBUF0==0xaa)                                  //if(SBUF0!='\r')
                                        {
                                                jishu=1;
                                        }                 
                                        if(jishu==1)                                 
                                        {
                                                re[m]=SBUF0;
                                                putchar(0x99);
                                                m++;
                                        }                       
                                        if(m>=6)
                                        {
                                                  m=0;
                                                  jishu=0;                                
                                                  flag=1;
                                        }
                                }
               
                        }       

                 
       
}

使用特权

评论回复
板凳
ningling_21| | 2015-5-5 10:41 | 只看该作者
很明显是程序的问题导致

使用特权

评论回复
地板
15056048066|  楼主 | 2015-5-5 10:50 | 只看该作者
ningling_21 发表于 2015-5-5 10:41
很明显是程序的问题导致

求解,问题出在哪了呢?

使用特权

评论回复
5
ningling_21| | 2015-5-5 11:46 | 只看该作者
15056048066 发表于 2015-5-5 10:50
求解,问题出在哪了呢?

[size=18.0180187225342px]改一下试试
[size=18.0180187225342px]

[size=18.0180187225342px]void uart0_ISR() interrupt 4

[size=18.0180187225342px]{                                 
[size=18.0180187225342px]        static int m= 0;                          //循环变量
[size=18.0180187225342px]        static char jishu=0;                          //循环变量                                                                                          
[size=18.0180187225342px]                        
[size=18.0180187225342px]                        if(SCON0&0x01)
[size=18.0180187225342px]                        {
[size=18.0180187225342px]                                SCON0&=0xfe;
[size=18.0180187225342px]                              
[size=18.0180187225342px]                               SBUF0==SBUF0;                                  //if(SBUF0!='\r')
[size=18.0180187225342px]                        
[size=18.0180187225342px]                        }        

[size=18.0180187225342px]}

使用特权

评论回复
6
ayb_ice| | 2015-5-5 11:52 | 只看该作者
putchar函数不正确吧,要关掉中断

使用特权

评论回复
7
15056048066|  楼主 | 2015-5-5 12:31 | 只看该作者

好像不行啊,可以进中断,但是接收这接不到回发数据

使用特权

评论回复
8
ningling_21| | 2015-5-5 12:59 | 只看该作者
15056048066 发表于 2015-5-5 12:31
好像不行啊,可以进中断,但是接收这接不到回发数据

发送完成的中断处理也要加上

使用特权

评论回复
9
15056048066|  楼主 | 2015-5-5 13:00 | 只看该作者
ayb_ice 发表于 2015-5-5 11:52
putchar函数不正确吧,要关掉中断

char putchar (char c)
{
             IE&=0xef;                                                  //ES=0;         UART0 使能位                                                                               
      SBUF0 = c;                          // Send character
      while (!TI0);                       // Wait for transmit complete
      TI0 = 0;
      //SBUF0 = c;                          // Send character
      IE|=0x10;                                                          //ES=1;         UART0 使能位   
      return c;
}


在里面把ES0清0后,又置1,和刚才一样,请看一下,这样有问题吗

使用特权

评论回复
10
15056048066|  楼主 | 2015-5-5 14:50 | 只看该作者
ningling_21 发表于 2015-5-5 12:59
发送完成的中断处理也要加上

void uart0_ISR() interrupt 4
{                                
        static int m= 0;                          //循环变量
        static char jishu=0;                          //循环变量                                                                                  
                        
                        if(SCON0&0x01)                        //接收到数据,RI0=1
                        {
                                SCON0&=0xfe;                //RI0=0
                                SBUF0==SBUF0;
                                //putchar(0x99);
                                LED=1;
                        }       
                               
                        if(SCON0&0x02)                        //接收完数据,TI0=1
                        {
                                SCON0&=0xfd;                //TI0=0
                                //putchar(0x99);
                                LED=0;
                        }

}

主函数while(1); 在那等待,还是只能接到数据进中断,发数的中断进不去。

使用特权

评论回复
11
ningling_21| | 2015-5-5 14:56 | 只看该作者
15056048066 发表于 2015-5-5 14:50
void uart0_ISR() interrupt 4
{                                
        static int m= 0;                          //循环变量

SBUF0==SBUF0;

这么简单的问题不能改一下吗

使用特权

评论回复
12
15056048066|  楼主 | 2015-5-5 15:10 | 只看该作者
ningling_21 发表于 2015-5-5 14:56
SBUF0==SBUF0;

这么简单的问题不能改一下吗

不好意思啊,现在可以接到数,可是回到最开始的状态了,单个发数,接收没问题;发送aa  aa,接收AA F5;发送01  02,接收01 E0 ;发送ff  ff,接收FF;发送aa  aa  01 02 ff ff ,接收AA B5 02 FF .那这个问题到底出在哪了,这里谢谢耐心解答啦

使用特权

评论回复
13
ayb_ice| | 2015-5-5 15:59 | 只看该作者
15056048066 发表于 2015-5-5 10:03
程序如下:
uchar flag;                                        //uart0接收到数据的标志位
uint xdata re[6];                                 //接收缓存数组

还是把具体要求先说清楚吧,

通信格式也没有说清楚,是标准字符串吗

使用特权

评论回复
14
15056048066|  楼主 | 2015-5-5 16:24 | 只看该作者
ayb_ice 发表于 2015-5-5 15:59
还是把具体要求先说清楚吧,

通信格式也没有说清楚,是标准字符串吗

目的是实现上位机和单片机通讯,主机发送的命令格式为 6 个字节 ,包括字头、地址、功能和字尾;如“AA  AA  01  02  FF FF”,从机收到后回复相应的字符串。主要是判断接收到的字符串是不是发送的,所以就把字符串再发回主机,现在的问题是发送应该没问题,因为可以发送已知的字符串,但接收再发回的就有问题,问题应该出在接收上了,不知道这样分析可以吗?

使用特权

评论回复
15
ayb_ice| | 2015-5-5 17:02 | 只看该作者
15056048066 发表于 2015-5-5 16:24
目的是实现上位机和单片机通讯,主机发送的命令格式为 6 个字节 ,包括字头、地址、功能和字尾;如“AA   ...

那收任意字节后立刻回发不就行了吗

使用特权

评论回复
16
15056048066|  楼主 | 2015-5-5 19:25 | 只看该作者
ayb_ice 发表于 2015-5-5 17:02
那收任意字节后立刻回发不就行了吗

现在问题感觉是,如果串口助手一次发送6个字节过来,uart0的中断只能进去3次,好像处理速度跟不上。单个字符就没问题

使用特权

评论回复
17
xuyaqi| | 2015-5-5 20:50 | 只看该作者
多找一些例程来学习吧

使用特权

评论回复
18
15056048066|  楼主 | 2015-5-5 21:05 | 只看该作者
xuyaqi 发表于 2015-5-5 20:50
多找一些例程来学习吧

好吧:handshake

使用特权

评论回复
19
mmuuss586| | 2015-5-5 21:50 | 只看该作者
中断程序搞这么长,尽量短;
我们以前用C8051F,115200波特率,发4K的数据都没事;

使用特权

评论回复
20
ayb_ice| | 2015-5-6 08:00 | 只看该作者
15056048066 发表于 2015-5-5 19:25
现在问题感觉是,如果串口助手一次发送6个字节过来,uart0的中断只能进去3次,好像处理速度跟不上。单个 ...

你那个串口中断处理有点问题,要先将串口数据取出来,再清中断标志

        U8 t;
       
        if(RI){
                t = SBUF;
                RI = 0;
               
                if(t == xxx){
                        ...
                }
        }

使用特权

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

本版积分规则

1

主题

17

帖子

0

粉丝