请教各位关与485多机通讯问题,小弟用PIC单片机进行RS485多机通讯,1主机4从机,单独一对一通讯都是正常的,但是一起一对四通讯从机可以收到数据,但是主机手表到从机返回的数据,我是采用轮询的方式通讯,先对1号机通讯,1号机收到主机发来的数据后判断是否是本机地址,是本机地址后再返回一个数据,这样对1号机的查询结束后,再对2号进行查询,一直到4号。但是主机却收不到从机发来的数据,每个从机都分配步同的地址,不知是什么问题,折腾好几天了,还望各位大侠帮忙解决下,是什么问题引起的,谢谢!
主机通信主程序:
#include<pic.h>
#include"My_Hfile.h"
__CONFIG(0X0864);
__CONFIG(0X18ff);
volatile UCHAR Addr; //从机地址
volatile UCHAR Recv_Data[5]; //接收数据缓存
UCHAR Recv_idx; //接受数据缓存索引
UINT CRC; //CRC校验数据
//----LCD封面显示
UCHAR table1[]={"SL1 DATA:"};
UCHAR table2[]={"SL2 DATA:"};
UCHAR table3[]={"SL3 DATA:"};
UCHAR table4[]={"SL3 DATA:"};
//-------------------------------------------------------------------
bit F_T1,Recv_OK; //相关标识位
//-----------------------------------主程序-------------------------------------
void main()
{
UCHAR i;
__delay_ms(100); //等待足够的数据带从机完成初始化
port_init(); //端口初始化
lcd_init(); //LCD初始化
GOTO_XY(0,0); //显示位置设置,及显示内容
write_lcd(table1);
GOTO_XY(0,1);
write_lcd(table2);
GOTO_XY(0,2);
write_lcd(table3);
GOTO_XY(0,3);
write_lcd(table4);
Per_init(); //外设初始化
while(1)
{
//循环访问从机
for(Addr=0x01;Addr<=0X04;Addr++)
{
LED_send=0;
EN_485=1; //允许485发送(禁止接受)
__delay_ms(1);
Send_Byte(Addr); //发送从机地址
Send_Byte(COMMAND); //发送操作命令码
CRC=0XFFFF; //CRC校验复位
CRC16(Addr); //校验从机地址
CRC16(COMMAND); //校验操作命令码
Send_Byte(CRC); //发送CRC低8位
Send_Byte(CRC>>8); //发送CRC高8位
__delay_ms(1);
SET_TIMER1(15000); //设置帧间隔时间
F_T1=0;
Recv_OK=0; //接受成功标志先设0
EN_485=0; //允许485接受(禁止发送)
TMR0=5; //定时器0设定超时时间
TMR0IF=0;
// while(!Recv_OK);
while((!Recv_OK)&&(!F_T1)) ; //如果主机未接收到从机数据且为超时则等待
//------------------------------------------------------
//如果主机接受从机数据成功,则继续下面的处理
if(Recv_OK)
{
GIE=0; //关中断
Recv_OK=0; //接收成功标志设为0
CRC=0XFFFF; //CRC校验复位
for(i=0;i<5;i++) //对当前接收的数据校验
{
CRC16(Recv_Data[i]);
}
//校验成功时显示返回的数据
if(CRC==0X0000)
{
LED_recv=~LED_recv;
switch(Addr)
{
case 0x01:
{
GOTO_XY(9,0);
hex_asc(Recv_Data[2]);
break;
}
case 0x02:
{
GOTO_XY(9,1);
hex_asc(Recv_Data[2]);
break;
}
case 0x03:
{
GOTO_XY(9,2);
hex_asc(Recv_Data[2]);
break;
}
case 0x04:
{
GOTO_XY(9,3);
hex_asc(Recv_Data[2]);
break;
}
default:{
GOTO_XY(9,0);
write_data('E');
write_data('R');
write_data('R');
write_data('O');
write_data('R');
GOTO_XY(9,1);
write_data('E');
write_data('R');
write_data('R');
write_data('O');
write_data('R');
GOTO_XY(9,2);
write_data('E');
write_data('R');
write_data('R');
write_data('O');
write_data('R');
GOTO_XY(9,3);
write_data('E');
write_data('R');
write_data('R');
write_data('O');
write_data('R');
break;
}
}
}
}
//__delay_ms(10); //每完成一个从机数据处理后延时10ms
GIE=1; //再开中断
}
//__delay_ms(15); //每完成一轮扫描后等待10MS
}
}
//定时器中断及485接收中断程序
void interrupt ISR()
{
UCHAR temp;
//-----------------定时器1溢出中断--------------------------------------
if(TMR1IF)
{
TMR1IF=0;
F_T1=1;
}
//-----------------串口接收中断-------------------------------------------------
if(RCIF)
{
TEST1=~TEST1;
Recv_OK=0;
temp=RCREG;
if(Recv_idx==0)
{
if(temp==Addr)
{
Recv_Data[Recv_idx++]=temp; TEST2=~TEST2;
}
else
{
Recv_idx=0;
}
}
else if(Recv_idx==5)
{
Recv_idx=0;
Recv_OK=1;
}
else
{
Recv_Data[Recv_idx++]=temp;
}
}
}
从机主程序:
#include<pic.h>
#include"My_Hfile.h"
__CONFIG(0X0864);
__CONFIG(0X18ff);
volatile UCHAR Recv_Data[4]; //??????
volatile UCHAR Recv_idx; //????????
UCHAR Addr; //?????
UINT CRC; //CRC???
UCHAR return_data; //????????
bit F_T1,Recv_OK; //?????
//LCD????
UCHAR table1[]={"RECV BYTE1:"};
UCHAR table2[]={"RECV BYTE2:"};
UCHAR table3[]={"RECV BYTE3:"};
UCHAR table4[]={"RECV BYTE4:"};
//----------------------------???--------------------------------------------
void main()
{
UCHAR i,j;
Recv_OK=0; //????????0
port_init(); //?????
lcd_init(); //LCD???
//LCD???????????
GOTO_XY(0,0);
write_lcd(table1);
GOTO_XY(0,1);
write_lcd(table2);
GOTO_XY(0,2);
write_lcd(table3);
GOTO_XY(0,3);
write_lcd(table4);
Per_init();//?????
LED_recv=0;
while(1)
{
//???????????4???
if(Recv_OK)
{
Recv_OK=0;
GIE=0; //???
// __delay_ms(10);
//?????????0
CRC=0XFFFF; //CRC?????
for(i=0;i<4;i++) //CRC????????
{
CRC16(Recv_Data[i]);
}
//?????????????????5???????????????????2??CRC?
if(CRC==0X0000)
{
LED_recv=1;
EN_485=1; //485??????????
__delay_ms(1); //?????????????
GOTO_XY(11,0);
hex_asc(Recv_Data[0]);
GOTO_XY(11,1);
hex_asc(Recv_Data[1]);
GOTO_XY(11,2);
hex_asc(Recv_Data[2]);
GOTO_XY(11,3);
hex_asc(Recv_Data[3]);
RB5=~RB5;
if(Recv_Data[0]==Addr)
{
return_data=Addr|(0XF0|(j++));//???????
Send_Byte(Addr); //??????
Send_Byte(COMMAND); //?????
Send_Byte(return_data); //???????
CRC=0xFFFF; //CRC????
CRC16(Addr); //????
CRC16(COMMAND); //?????
CRC16(return_data); //???????
Send_Byte(CRC); //??CRC?8?
Send_Byte(CRC>>8); //??CRC?8?
__delay_ms(1);
EN_485=0; //????????485??
LED_recv=0;
}
}
GIE=1; //???
}
}
}
void interrupt ISR()
{
UCHAR temp;
//-----------------定时器1溢出中断--------------------------------------
if(TMR1IF)
{
TMR1IF=0;
F_T1=1;
}
//-----------------串口接收中断-------------------------------------------------
if(RCIF)
{
TEST1=~TEST1;
Recv_OK=0;
temp=RCREG;
if(Recv_idx==0)
{
if(temp==Addr)
{
Recv_Data[Recv_idx++]=temp; TEST2=~TEST2;
}
else
{
Recv_idx=0;
}
}
else if(Recv_idx==4)
{
Recv_idx=0;
Recv_OK=1;
}
else
{
Recv_Data[Recv_idx++]=temp;
}
}
} |