⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m16modbus.c

📁 很好的串口通信程序,采用MODBUS规约.
💻 C
字号:
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]); /*3¤?è*/
			num_send=6+n;
			send_data[1]=recieve_data[1];  /*1|?ü*/
			send_data[2]=recieve_data[4];
			send_data[3]=recieve_data[5];  /*3¤?è*/
			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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -