基于ATmega16的Modbus通訊技術(shù)計(jì)算機(jī)、單片機(jī)(M16)收、發(fā)自如。
unsigned int cal_crc(unsigned char *ptr, unsigned int len)
{
unsigned int crc=0xffff;
unsigned char i;
while(len!=0)
{
crc^=*ptr;
for(i=0;i<8;i++)
{
if((crc&0x0001)==0) crc=crc>>1;
else
{
crc=crc>>1;
crc^=0xa001;
}
}
len-=1;
ptr++;
}
return crc;
}
void fenli(unsigned int data,unsigned int data1)
{
send_data[data1]=(unsigned char)(data);
send_data[data1+1]=(unsigned char)(data>>8);
}
unsigned int zhuhe(unsigned char data1,unsigned char data)
{
unsigned int t;
t=data1;
t=(t<<8)+data;
return t;
}
void send_run(void)
{
if(send_sp>num_send-1)
{
send_sp=0;
flag_send=0;
}
else
{
UDR=send_data[send_sp];
send_sp++;
}
num_stop=0;
}
void error(unsigned char data)
{
unsigned char add;
num_send=5;
send_data[1]=0x11;
send_data[2]=data;
add=cal_crc(send_data,3);
fenli(add,3);
}
void data_act(void)
{
unsigned int add,i,n;
send_data[0]=address;
add=zhuhe(recieve_data[2],recieve_data[3]);
add=add*2-2; /*µØÖ·*/
if(add>49) error(2);
else
{
if(recieve_data[1]==3)
{
n=zhuhe(recieve_data[4],recieve_data[5]); /*³¤¶È*/
num_send=6+n;
send_data[1]=recieve_data[1]; /*¹¦ÄÜ*/
send_data[2]=recieve_data[4];
send_data[3]=recieve_data[5]; /*³¤¶È*/
for(i=0;i<n;i++)
send_data[i+4]=variable_data[i+add];
n=4+n;
i=cal_crc(send_data,n);
fenli(i,n);
}
else if(recieve_data[1]==6)
{
num_send=num_recieve;
for(i=1;i<num_recieve;i++)
send_data[1]=recieve_data[1];
}
else error(1);
}
}
unsigned char crc_recieve(unsigned char data)
{
unsigned int crc0,crc1;
crc0=cal_crc(recieve_data,num_recieve);
crc1=zhuhe(recieve_data[data-1],recieve_data[data-2]);
if(crc0=crc1) return 1;
else return 0;
}
void time1compatt(void)
{
unsigned char flag;
if(flag_send==2) send_run();
num_stop+=1;
if(num_stop>3)
{
if(flag_send==1)
{
flag=crc_recieve(num_recieve);
if(flag==1)
{
data_act();
flag_send=2;
num_recieve=0;
}
}
num_stop=0;
}
}
#pragma interrupt_handler usrt_resieve:12
void usrt_resieve(void)
{
recieve_data[num_recieve]=UDR;
num_recieve+=1;
num_stop=0;
flag_send=1;
}
單片機(jī)與PC機(jī)通訊調(diào)試步驟:
1:確定PC機(jī)通訊沒(méi)問(wèn)題,方法:把PC機(jī)串口的數(shù)據(jù)發(fā)送腳與數(shù)據(jù)接收腳連在一起,看接收的數(shù)據(jù)是不是發(fā)送的數(shù)據(jù)
2:確認(rèn)接線的正確性
3:PC機(jī)與單片機(jī)雙方協(xié)議一定
我建議你:一不一步來(lái)
1:先發(fā)送一個(gè)字節(jié)數(shù)據(jù),看對(duì)不對(duì)
2:在發(fā)送一串?dāng)?shù)據(jù),看對(duì)不對(duì)
3:你發(fā)送,對(duì)方應(yīng)答,你再接收,看對(duì)不對(duì)
4:才做校驗(yàn)。