首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

请问串口程序有关问题

2012-02-13 
请教串口程序问题C/C++ code#include reg52.h#define uchar unsigned char#define uint unsigned intuns

请教串口程序问题

C/C++ code
#include <reg52.h>#define uchar unsigned char#define uint unsigned intunsigned char flag,a,i;uchar code table[]="I get ";void init(){    TMOD=0x20;     //确定T1的工作方式    TH1=0xfd;        //计算T1的初值,装载TH1,TL1    TL1=0xfd;    TR1=1;            //启动T1    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会被硬件置1,跳出循环,说明数据发送完毕            TI=0;            //            ES=1;            flag=0;        }    }}void ser() interrupt 4{    RI=0;                //接受数据完成后,内部硬件置1,进入串口中断函数后    a=SBUF;                //必须有软件清0    flag=1;                //将flag置1,方便在主程序中检测}

这个程序的功能是在上位机上用串口调试助手发送一个字符X,单片机收到后返回给上位机"I get X"
请问如何修改可以在上位机上用串口调试助手发送两个个字符X,单片机收到后返回给上位机"I get XX"

我弄了很久也没有弄出来了,麻烦各位了

[解决办法]
我觉得这个你的定义好通信协议,比如上位机发送一个X给单片机,不能是单独的一个X,而是一个完整的命令桢,打个比方,你以:#作为起始符 %作为结束符号,那么命令桢就是:#X% 不过单片机通信你的把它们转换为ASC码:23 58 25;单片机再收到了这个命令桢后,就可以分析出的出X,从而返回给上位机:I Get X

同样的道理,当上位机发送:#XX%给单片机,单片机分析得出:XX,返回给上位机:I Get XX
[解决办法]
问题的关键在于:介于通信起始符和结束符之间的内容!
通信协议对于串口通信很重要。
[解决办法]
先定义一个数组,然后在中断程序里每接收一个字符就赋给这个数组。发送的时候循环取出发给上位机就行了。
[解决办法]
粗略的看了下发送接收的代码,应该没问题的,初始化串口和配置方式代码就不知道了,因为很久没搞51了,

想问一下,具体的现象是什么?单片机什么都没接收到?还是单片机接收到了X,反馈给PC的时候,PC没收到?或者收到错误信息?

我觉得会不会是你PC串口配置和51的串口配置不对应,比如波特率,停止位,校验位等,,,,,,
[解决办法]
试试看。
...//你原来的程序

uchar a[2]; //定义变量中把a去了,加一个数组a[2]。如果是更长的字符,数组长度要相应改变

...//你原来的程序

void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0; //关闭串口中断,否则发送数据时同样申请中断,程序进入死循环
for(i=0;i<6;i++)
{
SBUF=table[i];
while(!TI);
TI=0;
}
for(i=0;i<2;i++) //发送数组内容
{
SBUF=a[i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
}
}
}

void ser() interrupt 4
{
uchar j;
for(j=0; j<2; i++) //接收两个字符

while(!RI);
RI=0;
a[i]=SBUF;
}
flag=1; //将flag置1,方便在主程序中检测
}


[解决办法]
C/C++ code
char revbuff[1000000]void ser() interrupt 4{    static int len=0;    RI=0;                //接受数据完成后,内部硬件置1,进入串口中断函数后     unsigned char a=SBUFF;    if(a=='\r'||a=='\n')    {flag=1;revbuff[len]=0;}    else        revbuff[len++]=a;                           }在main内部void main(){  ...  if(flag)   {    flag=0;    strcpy(buff+6,revbuff);    uartouts(buff);  }  ...}
[解决办法]
楼主用个数组不就可以了么?随便你收几个字符。
[解决办法]
C/C++ code

#ifndef _SERIAL_CONFIG_H_#define _SERIAL_CONFIG_H_#include "const.h"#include "oscfrequencydef.h"#ifndef OSC_FREQUENCY#error undefined OSC_FREQUENCY#endif/***********************************************************************仅限于串口方式1的工作模式,即1位起始位,8位数据位和1位停止位,无校验位波特率不倍增************************************************************************/typedef enum tagBAUD{    b_1200 = 1200,    b_2400 = 2400,    b_4800 = 4800,    b_9600 = 9600,    b_14400 = 14400,    b_19200 = 19200,    b_28800 = 28800,    b_38400 = 38400,    b_56000 = 56000,    b_57600 = 57600,        //注意:115200已经超过两个字节的范围    INVALID_BAUD,}BAUD;typedef void (*RECVPROC)(BYTE byte);BOOL OpenSerial(BAUD Baud, RECVPROC pRecvFunc);void SendData(const BYTE* pData, BYTE nSize);void CloseSerial();#endif 

热点排行