求一51系列单片机C程序,最好是简单易懂,有注释。 程序目的:通过串口控制单片机,如发送0x00 0

x01 单片机接收到之后将0x01赋值给P0 发送0x01 0x03 单片机收到后则将0x03赋值给P1,以此类推。也就是说前面的数据为地址,决定后面数据复制给谁!
求程序!
#definde uchar unsigned char
uchar cont=0;
uchar data,com;
uchar flag=0;
sbit out1=P0^1;
sbit out2=P0^2;
sbit out3=P0^3;

void init()
{
TMOD=0x20;
TH1=0xfd;
TH1=TL1;
SM0=0;
SM1=1;
REN=1;
EA=1;
ES=1;

}
void UARTInterrupt() interrupt 4
{

RI=0;
TI=0;
cont++;
if(cont==1)//为1时进入
{
com=SBUF;

}
else
{
data=SBUF;
cont=0;
flag=1;
}
}
void main()
{
init();
while(1)
{
if(flag)
{
switch(com)
{
case 0x01:
switch(data)
{
case 0x01:
out1=~out1;
break;
case 0x02:
out2=~out2;
break;
case 0x03:
out3=~out3;
break;
}
break;
case 0x02:
P1=data;
break;
case 0x03:
P2=data;
break;
case 0x04:
P3=data;
break;
}
}
}
}

//11.0592MHz
//9600波特率

#include <reg51.h>
void InitUART(void)//串口初始化
{
TMOD = 0x20;//定时器方式2 8位自动重装
SCON = 0x50;//定时器1为串口提供时钟
TH1 = 0xFD;//初值9600bps
TL1 = TH1;
PCON = 0x00;//波特率不加倍(如果为0x80代表波特率加倍)
EA = 1;//打开总中断
ES = 1;//打开串口中断
TR1 = 1;//定时器1开始计数
}
void SendOneByte(unsigned char c)//发送字节
{
SBUF = c; //赋值给SBUF启动发送
while(!TI); //等待发送完成
TI = 0; //清零发送完成标志位
}
void SendString(unsigned char *p)//发送字符串
{
while(*p) //如果p的内容不等于0
{
SendOneByte(*p++); //从串口发送一字节数据,并且p的地址自增1
}
}
void main(void)//主函数
{
InitUART();//初始化串口
while(1); //死循环(等待串口中断)
}
void UARTInterrupt(void) interrupt 4//串口中断
{
unsigned char temp;//定义临时变量
static unsigned char cont; //定义静态变量(用于保存状态)
if(RI) //串口收到数据
{
RI = 0;//清零接收标志位
temp=SBUF;//获取收到的数据
if(!cont)//如果cont为0 (表示第一次接收数据)
{
if(temp<4)//收到的数据小于4(单片机只有P0-P3所以大于3的不做处理)
{
cont=1;//首先cont赋1
cont=cont<<temp;//进行移位 收到的数据=0代表cont=0x01;收到的数据=1代表cont=0x03;避开0表示收到第一次数据
}
else//如果大于4
{
SendString("选择端口错误!只能为P0-P3\r\n");//向电脑反馈信息 大于4提示选择端口错误
}
}
else//cont不为0代表已经收到第一次数据
{
switch(cont)//选择输出口
{
case 0x01://如果是0x01,P0口输出第二次数据
P0=temp;break;
case 0x02://如果是0x02,P1口输出第二次数据
P1=temp;break;
case 0x04://如果是0x04,P2口输出第二次数据
P2=temp;break;
case 0x08://如果是0x08,P3口输出第二次数据
P3=temp;break;
}
cont=0;//清零cont 准备下一次接收数据
}
}
else//如果不是接收到数据(发送数据完成中断)
TI = 0;//清零发送标志位
}

顺便帮你写个控制软件吧。追问

cont移位操作在程序中有什么作用呢?
还有就是在串口中断中,执行的语句较多,是否会引起第一次串口中断还没有执行完,下一个串口中断申请已经开始?
我模仿你的语句加上实际情况改写了一下程序,请帮忙看看是否有问题,能不能达到目的?

追答

cont位移操作是作为标示符,并没有特殊意义。也就是让cont不等于0认为是第二次接收数据。

9600波特率处理这点还不至于堵塞中断通道。单片机是按微秒级运算的,串口的速度是1/9600*10
1秒 ÷ 9600位 x 8位数据1起始位1停止位 = 0.0010417s = 1.04ms
1.04ms已经足够单片机处理完这些内容了

看上去可以

温馨提示:答案为网友推荐,仅供参考