由于课题的原因被强迫用了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();
Inverter.Comm=LISTENING;
//关定时器TIM5
TIM_Cmd(TIM5, DISABLE);
USART_ITConfig(InverterUart,USART_IT_RXNE,ENABLE);
RS485Read();
Delay(200,Inverter.Comm);//既定延时400ms,若Inverter.Comm的值变化则退出
ResetInverterComm();
Inverter.Comm=TIME_OUT;
//接收缓冲中数据长度为0,则表示超时无应答
if(Inverter.Length==0)
{
Inverter.Error=TIME_OUT; //("变频器应答超时");
return ;
}
Inverter.Comm=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<l;i+=2)
{
tmp=Inverter.RecvBuf;
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);
Inverter.Comm=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);
}
}
转载
|