PC与单片机串口通信问题 求教?

xiaoereee 2017-07-07 05:51:46
1,通过串口向单片机发送 此格式数据 ff fe 01 00 00 00 fd fc 单片机得到第三位01命令,执行一个动作。
2,当单片机检测到P1有变化时,通过串口发送0xff,0xfe,0x00(用P1替换),0x00,0x00,0x00,0xfd,0xfd到电脑。
第一个功能可以实现,
第二个问题 电脑串口得到数据不能完整,只有一个ff 再当P1有变化时串口就没有数据发出。
一下是代码

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
/********************************************************************
初始定义
*********************************************************************/

unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容
int i;


/*定义八位出为单片机P2口*/
sbit K1=P2^0;
sbit K2=P2^1;
sbit K3=P2^2;
sbit K4=P2^3;
sbit K5=P2^4;
sbit K6=P2^5;
sbit K7=P2^6;
sbit K8=P2^7;

/*定义八位入为单片机P1口*/
sbit SB1=P1^0;
sbit SB2=P1^1;
sbit SB3=P1^2;
sbit SB4=P1^3;
sbit SB5=P1^4;
sbit SB6=P1^5;
sbit SB7=P1^6;
sbit SB8=P1^7;

void delay(int t)
{
while(t--);
}



/*------------------------------------------------
函数声明
------------------------------------------------*/
void SendStr(unsigned char *s);
void SendByte(unsigned char da);

/*------------------------------------------------
串口初始化
------------------------------------------------*/
void InitUART (void)
{
PCON = 0x00;
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = 0xFd;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}



/*------------------------------------------------
主函数
------------------------------------------------*/
//int m;
//int flag=0;
//unsigned char ss;
int judge[8];
unsigned char ZTS[8]={0xff,0xfe,0x00,0x00,0x00,0x00,0xfd,0xfd};
int cnt=0;
int ZT;
void main (void)
{
ZT=P1;
//res=0;
InitUART();

ES= 1;//打开串口中断

while (1)
{ if(ZT!=P1)
{
ZTS[2]=P1;
SendStr(ZTS);
ZT=P1;
}

if(judge[0]==0xFF&&judge[1]==0xFE&&judge[6]==0xFD&&judge[7]==0xFC)
{

dat=judge[2];
switch(dat)
{


uchar k;
k=10;
case 0xff: P2=0X00;delay(k);dat=0xee;break; // 全开
case 0x00: P2=0XFF;delay(k);dat=0xee;break; // 全关

case 0x01: K1=0;delay(k);dat=0xee;break; // 第一路开
case 0x02: K2=0;delay(k);dat=0xee;break; // 第二路开
case 0x03: K3=0;delay(k);dat=0xee;break; // 第三路开
case 0x04: K4=0;delay(k);dat=0xee;break; // 第四路开
case 0x05: K5=0;delay(k);dat=0xee;break; // 第五路开
case 0x06: K6=0;delay(k);dat=0xee;break; // 第六路开
case 0x07: K7=0;delay(k);dat=0xee;break; // 第七路开
case 0x08: K8=0;delay(k);dat=0xee;break; // 第八路开

case 0xFE: K1=1;delay(k);dat=0xee;break; // 第一路关
case 0xFD: K2=1;delay(k);dat=0xee;break; // 第二路关
case 0xFC: K3=1;delay(k);dat=0xee;break; // 第三路关
case 0xFB: K4=1;delay(k);dat=0xee;break; // 第四路关
case 0xFA: K5=1;delay(k);dat=0xee;break; // 第五路关
case 0xF9: K6=1;delay(k);dat=0xee;break; // 第六路关
case 0xF8: K7=1;delay(k);dat=0xee;break; // 第七路关
case 0xF7: K8=1;delay(k);dat=0xee;break; // 第八路关

case 0x55: ZTS[2]=P1;delay(k);SendStr(ZTS);dat=0xee;break; // 读输入口状态
case 0xAA: ZTS[2]=P2;delay(k);SendStr(ZTS);dat=0xee;break; // 读输出口状态

case 0x11: P2=~P2;delay(k);dat=0xee;break; // 输出口取反

default:break; // 跳出
}
}

}
}



/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void SendByte(unsigned char da)
{
SBUF = da;
while(!TI);
TI = 0;
}
/*------------------------------------------------
发送一个字符串
------------------------------------------------*/
void SendStr(unsigned char *s)
{
while(*s!='\0')// \0 表示字符串结束标志,通过检测是否字符串末尾
{
SendByte(*s);
delay(50);
s++;
}
}




/*------------------------------------------------
串口中断程序
------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char Temp; //定义临时变量

if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
Temp=SBUF; //读入缓冲区的值

judge[cnt++]=Temp;

//报头不满足或者一个协议帧发送完毕
if(cnt==8||judge[0]!=0xFF)
cnt=0;
SBUF=Temp;
//TI=1;
}
if(TI)
TI=0;
}
...全文
286 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
source03 2017-07-11
  • 打赏
  • 举报
回复
要按第2楼的回复,把根据发送内容改为根据发送长度作为退出while的判断条件。
of123 2017-07-10
  • 打赏
  • 举报
回复
问题在你的 PC 端应用代码上,没有等待足够的时间,接收一个字节就返回了。 如果你的协议能够使 PC 端预知单片机发送的字节数,就循环等待,直至接收到所有字节。 如果不知道,那么可能要用到“结束字节”:一个不在你的实意字符中使用的字节,仅表示传输结束。 如果连结束字节都腾不出来,那就只能使用超时了。
worldy 2017-07-08
  • 打赏
  • 举报
回复
int CurIdx=1; //发送缓冲区第一字节发送必须由主程序启动 /*------------------------------------------------ 串口中断程序 ------------------------------------------------*/ void UART_SER (void) interrupt 4 //串行中断服务程序 { unsigned char Temp; //定义临时变量 if(RI) //判断是接收中断产生 { RI=0; //标志位清零 Temp=SBUF; //读入缓冲区的值 judge[cnt++]=Temp; //报头不满足或者一个协议帧发送完毕 if(cnt==8||judge[0]!=0xFF) cnt=0; SBUF=Temp; //TI=1; } if(TI) { TI=0; if(CurIdx<MaxSendLen) SBUF=SendBuf[CurIdx++];//SendBuf发送数据缓冲区,CurIdx这个变量指示当前的发送序号 else { SendFinished=True; //这个标志可以用于主程序检测是否发送完成 CurIdx=1;//发送完毕,恢复序号 } } } 其他的代码,
zgl7903 2017-07-08
  • 打赏
  • 举报
回复
unsigned char ZTS[8]={0xff,0xfe,0x00,0x00,0x00,0x00,0xfd,0xfd}; 这里就包含0, 而发送 SendStr 中遇0结束,因此数据包发送不完整 void SendData(unsigned char *s, unsigned char iLen) { while(iLen-- > 0)// \0 表示字符串结束标志,通过检测是否字符串末尾 { SendByte(*s++); } } //调用 SendData(ZTS, sizeof(ZTS));

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧