stm32-rs485简易架构

下面分享一个rs485多线管理的库,
一共分为一下几个部分
1,结构体定义
2,注册
3,发送
4,接收
5,回调

typedef struct 
{
 uint8_t sendbuff[20];
 uint32_t len;
}T_stuRS485SendBuff;

typedef struct
{
 revFunc m_rs485RevFunc;
 uint8_t m_rs485Address;
 uint8_t m_lenIndex;
 uint8_t m_lenCount;
 uint8_t m_readStatus;
 uint8_t m_readCount;
}stuRs485Manage;

其次是注册部分,

注册函数如下

void regRs485Dev(revFunc revDataFunc,uint8_t address,uint8_t index)
{
 for(int i = 0 ; i < RS485_COUNT_LEN ; i ++)
 {
  if(sg_rs485Manage[i].m_readStatus == NONE_RS485)
  {
   sg_rs485Manage[i].m_rs485RevFunc = revDataFunc;
   sg_rs485Manage[i].m_rs485Address = address;
   sg_rs485Manage[i].m_lenCount = index;
   sg_rs485Manage[i].m_readStatus = INIT_RS485;
   break;
  }
 }
}

注册函数就是初始化一个结构体成员变量,赋值485的地址还有回调函数,等信息。

发送部分:

void loopRs485Sendbuff()
{
 static uint32_t timeCount = 0;
 if(HAL_GetTick() - timeCount < 100 && sg_rs485SendFlg != 0)
 {
  return;
 }
 timeCount = HAL_GetTick();
 osEvent  evt = osMailGet(mailRs485Manager, 1);
 if(evt.status == osEventMail)
 {
  T_stuRS485SendBuff *rptr;
  rptr = evt.value.p;
  _rs485SendBuff(rptr->sendbuff,rptr->len);
  osMailFree(mailRs485Manager, rptr);
  sg_rs485SendFlg = 1;
 }
}

void rs485SendBuffFifo(uint8_t *buff,uint32_t len)
{
 mRs485Ptr = osMailAlloc(mailRs485Manager, 2);       // Allocate memory
 if(mRs485Ptr != NULL)
 {
  memcpy(mRs485Ptr->sendbuff,buff,len);
  mRs485Ptr->len = len;
  osMailPut(mailRs485Manager, mRs485Ptr);
 }
}

void _rs485SendBuff(uint8_t *buff,uint32_t len)
{
 RS485_SEND_MODE(); 
 if(sg_flagSw == 0)
 {
  return;
 }
 HAL_UART_Transmit(&RS485_USART,buff,len,0Xff);
 //osDelay(5);
 RS485_REV_MODE(); 
}

采用的是一个缓冲发送,确保不会导致包错乱。

接受部分

void revRs485Data(uint8_t *buff,int32_t len)
{
 static uint8_t address = 0;
 if(len > 0)
  address = buff[0];
 for(int j = 0; j < len ; j ++)
 {
  for(int i = 0; i < RS485_COUNT_LEN ; i ++)
  {
   if(sg_rs485Manage[i].m_readStatus == BEGIN_RS485)
   {
    sg_rs485Manage[i].m_readCount += 1;
    if(sg_rs485Manage[i].m_rs485RevFunc != 0)
     sg_rs485Manage[i].m_rs485RevFunc(buff + j,1);
    else
     DEBUG_WARNING("not init rs485 dev,%x\r\n",sg_rs485Manage[i].m_rs485Address);
    if(sg_rs485Manage[i].m_readCount >= sg_rs485Manage[i].m_lenCount)
    {
     sg_rs485Manage[i].m_readStatus = END_RS485;
     //DEBUG_NORMAL("RS485 ansy finish %x\r\n",sg_rs485Manage[i].m_rs485Address);
     sg_rs485SendFlg = 0;
    }
    break;
   }
   else if(address == sg_rs485Manage[i].m_rs485Address && sg_rs485Manage[i].m_readStatus != NONE_RS485)
   {
    sg_rs485Manage[i].m_readCount = 0;
    sg_rs485Manage[i].m_readStatus = BEGIN_RS485;
    sg_rs485Manage[i].m_readCount += 1;
    if(sg_rs485Manage[i].m_rs485RevFunc != 0)
     sg_rs485Manage[i].m_rs485RevFunc(buff + j,1);
    else
     DEBUG_WARNING("not init rs485 dev\r\n");
    //DEBUG_WARNING("read len = %d\r\n,read count = %d\r\n",sg_rs485Manage[i].m_lenCount,sg_rs485Manage[i].m_readCount);
    if(sg_rs485Manage[i].m_readCount >= sg_rs485Manage[i].m_lenCount)
    {
     sg_rs485Manage[i].m_readStatus = END_RS485;
    }
    break;
   }
  }
 } 
}

首先遍历接收到的数据,
然后进行地址匹配,匹配成功,就开始接受数据,

解析部分为回调函数,我是实现了一个状态机,一个字节一个字节的解析数据。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值