搜索
bottom↓
回复: 25

51串口问题求助

[复制链接]

出0入0汤圆

发表于 2013-11-18 21:16:15 | 显示全部楼层 |阅读模式
程序大部分已经ok了。单片机发送abcd,pc接收到abcd。没问题。
一句话发送没问题,但是接收好像有点问题。
接收一个字符ok,多个字符就不对了,有时候只接收到第一个字符,有时候是其他字符,有时候是乱码。
--------------------------------------------------------------------------------------------------------
说下我的思路,pc发送字符给单片机,然后单片机直接回传值给pc。比方说pc发送a给单片机,那么此时单片机就把收到的a发给pc。
如果发送一个字符,ok。
此时pc发送abcd,就出错了。pc接收到的不是abcd,有可能是a,有可能是其他东西,但是可以肯定pc接收到的也是4个字符,这种问题原因是什么?
以下是中断函数
void usarthandle() interrupt 4
{
              if(RI)
              {   
                            RI =0;
           P1 =SBUF;
            SendOneByte(P1);//接收到什么,直接发送回去

                     }
            if(TI)
            {
                        TI =0;
                        ucBusy =0;
            }

}
个人觉得应该是51单片机接收程式这边写的有问题,否则只可以接收到pc发过来的第一个字符,后面几个字符却乱码了。而且51单片机发送一串字符给pc,pc也接收正确,所以应该是单片机接收pc时出现了错误,求大神点拨点拨。到底51串口接收程式应该怎么写,需要考虑些什么东东。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-11-18 21:58:26 | 显示全部楼层
hpy168888 发表于 2013-11-18 21:17
先清零标志位了么

请问这里指的是清楚哪个标志位呢

出0入0汤圆

发表于 2013-11-18 22:40:51 | 显示全部楼层
//发送串口数据
void SendData(BYTE dat)
{
        while(busy);
        ACC=dat;
       
        busy=1;
        SBUF=ACC;
}

//发送字符串
void SendString(char *s)
{
        while(*s)
        {
                SendData(*s++);
        }
}

//UART中断服务函数
void Uart() interrupt 4 using 1
{
        if(RI)
        {
                RI=0;
               

        }
        if(TI)
        {
                TI=0;
                busy=0;       
        }
}

出0入0汤圆

 楼主| 发表于 2013-11-19 09:07:54 | 显示全部楼层
zh3251241 发表于 2013-11-18 22:40
//发送串口数据
void SendData(BYTE dat)
{

你说的是发送,可是我的问题是51接收有问题,你的程式没有涉及到接收的。我的发送也是ok的

出0入0汤圆

发表于 2013-11-19 09:14:58 | 显示全部楼层
开一个数组,先把接收的数据都存起来,然后再发送出去

出0入0汤圆

发表于 2013-11-19 09:34:52 | 显示全部楼层
在上位机用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“I get X”,波特率9600 8 n 1


#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar flag,a,i;
uchar code table[]="I get";


void init()
{
    TMOD=0X20;
    TH1=0XFD;
    TL1=0XFD;
    TR1=1;
    REN=1;
    SM0=0;
    SM1=1;
    EA=1;
    ES=1;
}

void main()
{
    init();
    while(1)
    {
        if(flag==1)
        {
            ES=0;
            for(i=0;i<6;i++)
            {
                SBUF=table[i];
                while(!TI);
                TI=0;
            }
            SBUF=a;
            while(!TI);
            TI=0;
             ES=1;
            flag=0;
        }
    }
}


void ser() interrupt 4
{
    RI=0;
    a=SBUF;
    flag=1;
}

出0入0汤圆

 楼主| 发表于 2013-11-19 10:51:15 | 显示全部楼层
dlmaowf 发表于 2013-11-19 09:14
开一个数组,先把接收的数据都存起来,然后再发送出去

这种方法有想到过,可是想想其实会有新的问题。若定义数组长度5,pc传7个字符,51单片机回传7个会比较麻烦。第一数组满5个,我们做个触发条件,回传给pc,剩下的2个怎么办,所以又得加触发条件,目前觉得timeout的时间可以加,但是这样做是不是显得稍微复杂了一点。

出0入0汤圆

发表于 2013-11-19 10:57:03 | 显示全部楼层
发送前,有1至2字节的缓存应该就行

出0入0汤圆

发表于 2013-11-19 11:26:03 | 显示全部楼层
是这个问题吧 SendOneByte(P1);

出0入54汤圆

发表于 2013-11-19 12:21:59 | 显示全部楼层
P1...........

出0入54汤圆

发表于 2013-11-19 12:22:38 | 显示全部楼层
zh3251241 发表于 2013-11-18 22:40
//发送串口数据
void SendData(BYTE dat)
{

ACC..............

出0入0汤圆

 楼主| 发表于 2013-11-19 13:08:05 | 显示全部楼层
zh3251241 发表于 2013-11-19 09:34
在上位机用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“I get X”,波特率9600 8 n 1

仿真了下不行,等晚上回去用单片机再确定下看看

出0入0汤圆

 楼主| 发表于 2013-11-19 13:12:14 | 显示全部楼层
tragedy 发表于 2013-11-19 11:26
是这个问题吧 SendOneByte(P1);

不是这个问题,源程序是这样的,BYTE ucTemp;
ucTemp =SBUF;
SendOneByte(ucTemp);
这也是不行的。
所以不是这边的问题,与P1没关系。P1是可读可写寄存器。

出0入0汤圆

发表于 2013-11-19 13:40:31 | 显示全部楼层
ypm 发表于 2013-11-19 13:12
不是这个问题,源程序是这样的,BYTE ucTemp;
ucTemp =SBUF;
SendOneByte(ucTemp);

我觉得是你发送程序的问题。

出0入0汤圆

发表于 2013-11-19 16:33:19 | 显示全部楼层
lusson 发表于 2013-11-19 12:22
ACC..............

本来是用P来判断校验的

出0入54汤圆

发表于 2013-11-19 17:30:13 | 显示全部楼层
zh3251241 发表于 2013-11-19 16:33
本来是用P来判断校验的

谁教你的C里面用ACC啊?

出0入0汤圆

发表于 2013-11-19 22:00:08 | 显示全部楼层
lusson 发表于 2013-11-19 17:30
谁教你的C里面用ACC啊?

//内核特殊功能寄存器        // 复位值   描述
sfr ACC         =   0xE0;   //0000,0000 累加器Accumulator
sfr B           =   0xF0;   //0000,0000 B寄存器
sfr PSW         =   0xD0;   //0000,0000 程序状态字
sbit CY         =   PSW^7;
sbit AC         =   PSW^6;
sbit F0         =   PSW^5;
sbit RS1        =   PSW^4;
sbit RS0        =   PSW^3;
sbit OV         =   PSW^2;
sbit P          =   PSW^0;
sfr SP          =   0x81;   //0000,0111 堆栈指针
sfr DPL         =   0x82;   //0000,0000 数据指针低字节
sfr DPH         =   0x83;   //0000,0000 数据指针高字节

出0入0汤圆

 楼主| 发表于 2013-11-19 22:02:35 | 显示全部楼层
zh3251241 发表于 2013-11-19 22:00
//内核特殊功能寄存器        // 复位值   描述
sfr ACC         =   0xE0;   //0000,0000 累加器Accumul ...

51里面有ACC寄存器,没错,还有stc官网是用acc寄存器的p位做奇偶校验位的判断的。

出0入0汤圆

 楼主| 发表于 2013-11-19 22:06:05 | 显示全部楼层
zh3251241 发表于 2013-11-19 09:34
在上位机用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“I get X”,波特率9600 8 n 1

回来用51烧录了验证下,结果貌似还是有问题,和仿真的结果是一样的。pc发送x ,只能接收到I get  ;然后没有了,然后pc再次发送s,然后pc回传就不会变,不知怎么回事。

出0入54汤圆

发表于 2013-11-20 08:33:28 | 显示全部楼层
zh3251241 发表于 2013-11-19 22:00
//内核特殊功能寄存器        // 复位值   描述
sfr ACC         =   0xE0;   //0000,0000 累加器Accumul ...

你列的这些全部别使用。
因为ACC之类的在C的运算中会使用到,如果你在C里面使用的话可能造成破坏。
积偶校验之类的请用C来实现 。

出0入0汤圆

发表于 2013-11-20 10:48:50 | 显示全部楼层
ypm 发表于 2013-11-19 22:06
回来用51烧录了验证下,结果貌似还是有问题,和仿真的结果是一样的。pc发送x ,只能接收到I get  ;然后 ...

有原理图吗 用的什么片子之类的

出0入0汤圆

发表于 2013-11-20 10:56:07 | 显示全部楼层
哎。。。早知道我也整个萌一点的头像。

出0入0汤圆

发表于 2013-11-20 11:09:12 | 显示全部楼层
  1. void Uartx(void) interrupt 4
  2. {
  3.         unsigned char ReData,SenData;
  4.        
  5.         if(RI == 1)       //RI½ÓÊÜÖжϱêÖ¾
  6.         {
  7.                 RI = 0;                      //Çå³ýRI½ÓÊÜÖжϱêÖ¾
  8.                 ReData = SBUF;  //SUBF½ÓÊÜ/·¢ËÍ»º³åÆ÷
  9.                 SenData=ReData;
  10.                 SBUF=SenData;          //SUBF½ÓÊÜ/·¢ËÍ»º³åÆ÷
  11.                 while(TI==0);
  12.                 TI=0;
  13.         }
  14. }
复制代码

出0入0汤圆

 楼主| 发表于 2013-11-20 17:13:25 | 显示全部楼层
zh3251241 发表于 2013-11-20 10:48
有原理图吗 用的什么片子之类的

这边只有仿真图,没有原理图,只有焊好的最小系统板子这样子。不过这个就算拍个照也没多大用。对了,用的是usb转串口线。
这边我把仿真图贴给你看下。然后再给你截张调试图。顺便说下,用数组缓冲的方式我已经可以达到我的要求了。目前貌似只有这种方法可以实现。

如果pc发送字符给单片机,此时效果是只能接收到I Get一次,然后再发送就不会响应了。
等今天晚上研究下数组缓冲方式,调好后上程序给你验证下。
用的芯片STC89次2rc。仿真和硬件烧录结果一样,都不行。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-20 17:24:19 | 显示全部楼层
weng645008699 发表于 2013-11-20 11:09

验证过,仿真能过,应该没什么大问题,NICE,看来可以结题了,赞一个。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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