发个STM32的MODBUS主节点程序

发个STM32的MODBUS主节点程序
发个STM32的MODBUS主节点程序

发个STM32的MODBUS主节点程序

由于课题的原因被强迫用了STM32(本来打算2440的),因此认识阿莫电子,看到了版上一众高手,并学了不少知识。在课题中很多芯片资料的细节都是来源于阿莫电子,快毕业了,潜水了太久,就分享一点STM32的程序,反正很多都是从坛子里学的,我只是整理下拿来用了,献丑了。

处理器STM32F103ZET6是买论坛上一摄像头大师的(感谢免费帮我修了次3232),软件用的KEIL3.5。

我的MODBUS是驱动变频器的,做主节点用,主要实现03功能号和06功能号。

#define RS485Read (GPIO_WriteBit(GPIOG, GPIO_Pin_13,Bit_RESET))

#define RS485Write (GPIO_WriteBit(GPIOG, GPIO_Pin_13,Bit_SET))

//MODBUS的06功能号,读多个寄存器

void ReadInverter(UINT16 Addr,UINT8 N,UINT16 *Values)

{

UINT8 i,l;

UINT16 tmp;

UINT16 *p;

//在发送缓冲里面填数据

Inverter.SendBuf[0]=InverterAddr;

Inverter.SendBuf[1]=ReadID;

Inverter.SendBuf[2]=Addr>>8;

Inverter.SendBuf[3]=Addr&0XFF;

Inverter.SendBuf[4]=0;

Inverter.SendBuf[5]=N;

//计算CRC16,填入发送缓冲尾

CalCRC(Inverter.SendBuf,6,Inverter.SendBuf+6);

//置RS485发送状态

RS485Write();

//发送数据缓冲

Uart_Send(InverterUart,Inverter.SendBuf,8);

//清发送缓冲

PurgeRecvBuf();

https://www.360docs.net/doc/2d8844523.html,m=LISTENING;

//关定时器TIM5

TIM_Cmd(TIM5, DISABLE);

USART_ITConfig(InverterUart,USART_IT_RXNE,ENABLE);

RS485Read();

Delay(200,https://www.360docs.net/doc/2d8844523.html,m);//既定延时400ms,若https://www.360docs.net/doc/2d8844523.html,m的值变化则退出ResetInverterComm();

https://www.360docs.net/doc/2d8844523.html,m=TIME_OUT;

//接收缓冲中数据长度为0,则表示超时无应答

if(Inverter.Length==0)

{

Inverter.Error=TIME_OUT; //("变频器应答超时");

return ;

}

https://www.360docs.net/doc/2d8844523.html,m=FINISHED;

//长度校验

if(Inverter.RecvBuf[2]!=Inverter.Length-5)

{

Inverter.Error=FrameErr;

return ;//("变频器数据长度错误");

}

CalCRC(Inverter.RecvBuf,Inverter.Length-2,CRC16);

//CRC校验

if(*(UINT16 *)(CRC16)!=*(UINT16 *)(Inverter.RecvBuf+Inverter.Length-2)) {

Inverter.Error=CheckErr;

return ;//("变频器校验错误");

}

else if(Inverter.RecvBuf[1]==ReadID+0X80)

{

//("变频器读错误,错误号在第三个字节");

switch(Inverter.RecvBuf[2])

{

case Invalid_Func:i =Invalid_Func; break;

case Invalid_Addr:i =Invalid_Addr; break;

case Invalid_Data:i =Invalid_Data; break;

case InverterErr :i =InverterErr ; break;

case InverterBusy:i =InverterBusy; break;

case CheckErr :i =CheckErr ; break;

default :i =UnknowErr ; break;

}

Inverter.Error=i;

return ;

}

//校验一切正常,变频器操作成功

else if(Inverter.RecvBuf[1]==ReadID)

{

l=Inverter.RecvBuf[2]+3;

p=(UINT16 *)Values;

//接收数据

for(i=3;i

{

tmp=Inverter.RecvBuf[i];

tmp=tmp<<8;

tmp=tmp+Inverter.RecvBuf[i+1];

*p=tmp;

p++;

}

Inverter.Error=MODBUS_OK;//("读入参数成功:");

return ;

}

//校验一切正常,变频器操作失败

else if(Inverter.RecvBuf[1]!=ReadID&&Inverter.RecvBuf[1]!=ReadID+0X80) {

Inverter.Error=UnknowErr;//("变频器应答错误");

return ;

}

return ;

}

void TIM5_IRQHandler(void)

{

if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)

{

TIM_ClearITPendingBit(TIM5, TIM_IT_Update);

TIM_ClearFlag(TIM5, TIM_IT_Update);

https://www.360docs.net/doc/2d8844523.html,m=FINISHED;

TIM_Cmd(TIM5, DISABLE);

USART_ITConfig(InverterUart,USART_IT_RXNE,DISABLE);

}

}

void USART3_IRQHandler(void)

{

if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)

{

USART_ClearITPendingBit(USART3, USART_IT_RXNE);

if(Inverter.Length<=17)

{

Inverter.RecvBuf[Inverter.Length]=USART_ReceiveData(USART3);

Inverter.Length++;

}

TIM_Cmd(TIM5, ENABLE);

TIM_SetCounter(TIM5,0x0000);

}

}

相关主题
相关文档
最新文档