STM32HAL库自己写modbus

modbus有的人自己移植lib  modbus,有人自己移植freemodbus  ,日后博主会依次为大家做实验,去用上述两种方法实现,本次先分享自己写的modbus,话不多说上代码。

先是写出串口接收中断部分的代码。

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	extern uint8_t buff1[100];	//接收的数据包
	extern int buff1stat;		//接收数据包当前位
	extern uint8_t RxByte;		//中断接收暂存位置
	extern int RE4851_flag;			//接收结束标志符
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);	//中断启动使能标识
  /* USER CODE BEGIN USART1_IRQn 1 */
	buff1[buff1stat]=RxByte;	//将暂存内容放入接收数据包
	buff1stat++;				//数据包位置后移1位
	HAL_UART_Receive_IT(&huart1,&RxByte,1);	//重新启动接收中断,等待下一位数据到来
	if(buff1[1]==0x03)			//判断功能码,功能码位0x30则为读寄存器,请求数据包应为8位
	{
		if(buff1stat==8)		//数据到8位接收结束符置1,清除接收数据包当前位
		{
			buff1stat=0;
			RE4851_flag=1;
		}
	}
	if(buff1[1]==0x10)			//判断功能码,功能码位0x30则为读寄存器,请求数据包应为9+Code Length位
	{
		if(buff1[6]!=0x00)		//当Code Length位不为0 且数据到9+Code Length位时,接收结束符置1,清除接收数据包当前位
		{
			if(buff1stat==9+buff1[6])
			{
				buff1stat=0;
				RE4851_flag=1;
			}
		}
		
	}
  /* USER CODE END USART1_IRQn 1 */
}

接下来将解析上述结束数据的每一位数据

void  modbus_onebit(char a)
{
	switch (e.stat)
	{
	case 0:               // SLAVE ID
//		slave_id=DeviceAddr;
//		if (a == slave_id)
			e.stat = 1;
		break;
	case 1:
		if(a==0x03)
			e.stat = 2;
		if(a==0x10)
			e.stat=12;
		break;
	case 2:
		addr[cnt] = a;
		cnt++;
		e.stat = 3;	
		break;
	case 3:
		addr[cnt] = a;
		cnt++;
		if (cnt > 3)
		{
			cnt = 0;
			startaddr= addr[1];
			bufflen= addr[3];
			e.stat = 4;
		}
		break;
	case 4:
		e.stat = 5;
		break;
	case 5:
		if(n==bufflen)
		e.stat = 100;
		break;
	case 6:
		e.stat = 6;
		break;
	case 7:
		e.stat = -1;
		break;
	case 8:
		e.stat = 100;
		break;
/********D′è??à????′??÷********/	
	case 12:
		addr[cnt]=a;
		cnt++;
	if(cnt>4)
	{
		cnt=0;
		startaddr= addr[1];
		bufflen= addr[4];
		e.stat = 13;	//×a′?íê±?
	}	
	break;
	case 13:
		if(n==bufflen)
		e.stat = 100;
		break;


	}
}

接下来分析接收到的功能码



void ReadHoldRegister(uint8_t buffIN[100],uint8_t buffOUT[100])
{
	int i,j;
	e.stat = 0;
	for (i = 0; i < 10; i++)
	{
		modbus_onebit(buffIN[i]);
		
		if (e.stat == 100)
		{

		}
		if (e.stat == 0)
		{

		}
		if (e.stat == 1)
		{
			buffOUT[i]= buffIN[i];
		}
		if (e.stat == -1)
		{
			
		}
		if (e.stat == 2)
		{
			buffOUT[i] = buffIN[i];
		}
		if (e.stat == 3)
		{			
		}
		if (e.stat == 4)
		{
			buffOUT[2] = bufflen*2;
		}
		if (e.stat == 5)
		{
			for (j = 0,n=0; j < bufflen * 2; j= j + 2,n++)
			{
				buffOUT[3 + j] =  (DB_R[n+startaddr] >> 8) & 0x00FF;
				buffOUT[3 + j+1] = DB_R[n+startaddr]& 0x00FF;	
			}
		}
		
		if (e.stat == 12)
		{
			buffOUT[i] = buffIN[i];
		}
		if (e.stat 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值