打印
[CW32F003系列]

用SPI可变位数实现模拟非标串口

[复制链接]
250|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhanan|  楼主 | 2025-4-21 21:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
做了一个项目,单片机控制700个步进电机,每个步进电机有3bit数据,每次需要连续发送2100bit数据。
步进电机离单片机有十几米远,需要抗干扰能力强的通讯方式,所以选择485通讯。
但是标准串口都是8bit的,可发送两个3bit,有2bit空闲,有点可惜。
看了CW32的SPI,位数可变,最大16位,并且可以单工只发,用来做一个非标串口非常不错,一帧数据可以发送4个步进电机数据12bit。
实际又加了一个控制位,最高位为0表示数据,为1表示命令,共13位,再加上起始位0和停止位1,共15位。
没用晶振,用HSI振荡器即可满足波特率精度要求,3M波特率啊,CW32F003主频24M。

使用特权

评论回复
沙发
zhanan|  楼主 | 2025-4-21 21:26 | 只看该作者
SPI初始化:
  GPIOC->AFRL = 0x0300; // PC2复用SPI_MOSI输出
  SPI->CR1 = 0x7A54; // 单工只发15位,高位先发,3M波特率
  SPI->DR =0xFFFF; // 发送后MOSI高电平,模拟串口空闲时输出高电平

使用特权

评论回复
板凳
zhanan|  楼主 | 2025-4-21 21:27 | 只看该作者
发送程序:  
// SPI模拟串口发送13位数据,高位先发
// 注意这是阻塞式,非阻塞可用中断实现。
void spi_tx(u16 data)
{
  while((SPI->ISR & 0x01)==0); // 等上次的发完
  SPI->DR = (data<<1)+1; // 加上停止位发送
}

使用特权

评论回复
地板
zhanan|  楼主 | 2025-4-21 21:28 | 只看该作者
程序中调用:
void fsbjdjsj(u8 nms) // 发送步进电机数据
{

  spi_tx(0x1811); // 发送跳行信号(同步信号)

  ...数据整理

  for
  {
    spi_tx(data[i]); // 连续发送步进电机数据
  }
  ...
}

使用特权

评论回复
5
coody| | 2025-4-22 21:03 | 只看该作者
串口就可以了,8个电机数据24bits,刚好放在3个字节中。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

194

帖子

0

粉丝