51单片机串口通信程序问题 20
最近项目中要编写一个单片机串口通讯程序,采用的AT89S52型单片机,利用C51编写的程序如下所示。想实现的功能是:PC机发送数据给单片机,单片机接受后存储到一个全局数组...
最近项目中要编写一个单片机串口通讯程序,采用的AT89S52型单片机,利用C51编写的程序如下所示。想实现的功能是:PC机发送数据给单片机,单片机接受后存储到一个全局数组里面。通过定义char型全局数组,将PC机发送过来的数据作为数组地址,选择数组中的元素,并赋值给端口。由于采用串口接受数据后立马返还给PC的方式,PC端接受数据正常。但测试时发现端口的值都没有更改,程序工作异常。希望大家能给看看这个程序,指出毛病在什么地方,不甚感谢。还有一个问题就是:C51中数组a[j],j可以为uchar型变量来选择数组中的元素吗?以前试过好像可以选择,但这个程序貌似又不可以,糊涂了。
程序:
/* 包含头文件 */
#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit Mode_Con= P3^2;
sbit clk_lock= P3^3;
sbit oe1= P3^4;
sbit oe2=P3^5;
sbit LE= P3^6;
/*全局变量*/
uint i=0;//接受数据位置控制字
uchar Reg_Data;//待发送数据寄存变量
uchar Rx_Data[4]; //接受数据存储数组
uchar Tw_Data[21] ={0xfd,0xf7,0xf0,0xe8,0xe0,0xd9,0xd1,0xc9,0xc1,0xba,0xb2,0xaa,0xa3,0x9b,0x93,0x8c,0x84,0x7c,0x75,0x6d,0x65};
uchar Toff_Data[21]={0xfe,0xf7,0xf0,0xe8,0xe0,0xd9,0xd1,0xc9,0xc2,0xba,0xb2,0xab,0xa3,0x9b,0x93,0x8c,0x84,0x7c,0x75,0x6d,0x65};
uchar Ip_Data[]= { 0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
/*串口初始化*/
void Init_Com(void)
{
P1=0x00;
SCON=0X50; //设置串口工作方式为1
PCON=0x00; //波特率不加倍
TMOD=0x20; //定时器T1工作方式2
TH1=0XFD; //定时器初值:9600波特率
TL1=0XFD;
TR1=1; //启动定时器1
EA=1; //开中断
ES=1; //允许串口中断
}
/*串口中断处理函数*/
void serial_r() interrupt 4 using 1
{
uchar j,k;
if(RI)
{
RI=0;
Rx_Data[i]=SBUF;
SBUF=Rx_Data[i];
i++;
if(TI)
TI=0;
if(i==4)
{
i=0;
k=0;
EA=0; //关中断
if(Rx_Data[k++]==1)
Mode_Con=1;
else
Mode_Con=0;
j=Rx_Data[k++];
Reg_Data=Tw_Data[j]; LE=1;
P0=Reg_Data;
j=Rx_Data[k++];
Reg_Data=Tw_Data[j];
LE=1;
P1=Reg_Data;
j=(Rx_Data[k++]);
P2=Ip_Data[j];
EA=1;
}
}
}
/* 主函数 */
void main()
{
P2=0x00;
Mode_Con=0;
Init_Com(); while(1){}
} 展开
程序:
/* 包含头文件 */
#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit Mode_Con= P3^2;
sbit clk_lock= P3^3;
sbit oe1= P3^4;
sbit oe2=P3^5;
sbit LE= P3^6;
/*全局变量*/
uint i=0;//接受数据位置控制字
uchar Reg_Data;//待发送数据寄存变量
uchar Rx_Data[4]; //接受数据存储数组
uchar Tw_Data[21] ={0xfd,0xf7,0xf0,0xe8,0xe0,0xd9,0xd1,0xc9,0xc1,0xba,0xb2,0xaa,0xa3,0x9b,0x93,0x8c,0x84,0x7c,0x75,0x6d,0x65};
uchar Toff_Data[21]={0xfe,0xf7,0xf0,0xe8,0xe0,0xd9,0xd1,0xc9,0xc2,0xba,0xb2,0xab,0xa3,0x9b,0x93,0x8c,0x84,0x7c,0x75,0x6d,0x65};
uchar Ip_Data[]= { 0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
/*串口初始化*/
void Init_Com(void)
{
P1=0x00;
SCON=0X50; //设置串口工作方式为1
PCON=0x00; //波特率不加倍
TMOD=0x20; //定时器T1工作方式2
TH1=0XFD; //定时器初值:9600波特率
TL1=0XFD;
TR1=1; //启动定时器1
EA=1; //开中断
ES=1; //允许串口中断
}
/*串口中断处理函数*/
void serial_r() interrupt 4 using 1
{
uchar j,k;
if(RI)
{
RI=0;
Rx_Data[i]=SBUF;
SBUF=Rx_Data[i];
i++;
if(TI)
TI=0;
if(i==4)
{
i=0;
k=0;
EA=0; //关中断
if(Rx_Data[k++]==1)
Mode_Con=1;
else
Mode_Con=0;
j=Rx_Data[k++];
Reg_Data=Tw_Data[j]; LE=1;
P0=Reg_Data;
j=Rx_Data[k++];
Reg_Data=Tw_Data[j];
LE=1;
P1=Reg_Data;
j=(Rx_Data[k++]);
P2=Ip_Data[j];
EA=1;
}
}
}
/* 主函数 */
void main()
{
P2=0x00;
Mode_Con=0;
Init_Com(); while(1){}
} 展开
4个回答
展开全部
楼主,发送与接收不要放在同一个中断服务程序中,Rx_Data[i]=SBUF;
SBUF=Rx_Data[i];
这两句不应放在同一个中断服务程序中啊,都放在main()
{
while(1)
{
SBUF=Rx_Data[i];
…………
}
}
Rx_Data[i]=SBUF,放在中断服务程序中;
SBUF=Rx_Data[i];
这两句不应放在同一个中断服务程序中啊,都放在main()
{
while(1)
{
SBUF=Rx_Data[i];
…………
}
}
Rx_Data[i]=SBUF,放在中断服务程序中;
追问
PC端发送数据采用的是十进制发送数据。我在i=4时,设置了一个标志全局变量Flag=1,在主函数的while循环中,if(Flag==1) SBUF=Rx_Data[i];把四个数据依次发送回PC端,但是PC端接受不到数据了。有个问题就是,单片机默认接受和发送数据都是16进制的吗?
展开全部
看了半天还是没能理解你到底要实现个什么功能,不过串口接收里面发送时用
while(!TI); TI=0;
用if的话只会判断一次就接着下面运行。
while(!TI); TI=0;
用if的话只会判断一次就接着下面运行。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
就作者的意图,貌似 是想通过PC选择读取单片机内数据
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询