Answers:
USB UART(例如FTDI)并不昂贵。您所有其他选择听起来像是它们将花费您更多的零件和时间,而不是可能花费您的〜13美元,并且不可靠或缓慢。只需选择快速且无故障的选项,例如:
http://www.dfrobot.com/index.php?route=product/product&product_product=id#147#.UOamLG-sh8E
Sparkfun也卖一个。实际上,也许您可以从旧的USB设备中取出一个,或者从不知道其用途的旧货店购买一个。
我搞砸了一个Arduino项目的SPI至UART适配器,因为没有现有的库,所以我写了自己的库。最后,它工作正常,但如果我可以只花15美元,就可以买到。实际上,考虑到要花费时间,我应该拥有一个带有4个串行端口的巨型设备。
或者,如果您想要大量的串行端口,则可以查看类似于232(尽管不兼容)的RS485串行,它支持多点连接,即一条线上的多个接口。
如果您决定跳过添加额外的硬件,而只是按位运行,那么这并不像想象中的那么困难。
首先,您的通信线程必须实时:
#include<sched.h>
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
if( sched_setscheduler( 0, SCHED_FIFO, ¶m ) == -1 )
{
perror("sched_setscheduler");
return -1;
}
从现在开始,您的线程将不会在每秒950ms的时间内被抢占*,除非它愿意(通过sched_yield()
或usleep()
)及时地返回控制权,这不会使它永远被抢占。在850MHz CPU的情况下,即使在最快速度下,位敲环也会在大多数时间处于空闲状态。
现在不幸的是,不时返回控制权的要求意味着您的线程正在休眠时,无论“反对方”发送的是什么,都将永远丢失。但是为此,您可以使用传输控制。为CTS线路分配更多的GPIO,在屈服之前将其拉低,在恢复控制时进行备份:
bcm2835_gpio_write(CTS_PIN, LOW);
usleep(10);
bcm2835_gpio_write(CTS_PIN, HIGH);
或(最好是恕我直言)使用XON / XOFF传输控制-睡眠前通过RS232发送XOFF字符,恢复操作后通过XON发送字符。这些的默认ASCII代码用于'\x13'
XOFF /“停止发送”和'\x11'
XON /“继续发送”。
当然,您的远程设备必须遵守这些规定。否则,某些数据将丢失。
USB到UART的桥接器价格便宜且容易获得,但时序特性却很糟糕。Newark出售带有嵌入式STM32F ARM处理器的“嵌入式Pi”板,您可以在上面编写裸机代码。该芯片上有三个UART,我认为它们可以非常快地运行。如果您要使用其中一个与Raspberry Pi进行通信,则会使其中两个可供其他用途。免责声明:我已经购买了其中一块板,但是到目前为止,仅使用Raspberry Pi本身直接满足I / O需求。
如果您需要许多较慢的UART,则嵌入式Pi板上的STM32F可能会处理很多数字,特别是如果您愿意编写一些Arm汇编语言。如果在一块板上有两组16个I / O引脚可用,则可能有16个同时运行的软件UART以相当不错的波特率同时工作(以3倍或5倍的波特率周期性中断,这会存储从接收端口到缓冲区的16位锁存值,并从缓冲区到发送端口输出16位预计算值;如果这样做,则只要软件UART的平均服务时间不太长,就可以偶尔出现最坏情况命中(例如,所有十六个端口同时接收一个字节)无关紧要。
这种方法实际上可以非常有效地解决接收问题,因为“普通情况”代码甚至不必查看各个UART。假设您以5x采样数据,并且缓冲区的最后47个字节在紧接其之前被复制。假设数据以升序写入缓冲区,则可以通过简单地说一下,检查16个通道中的任何一个通道是否已完全接收到任何字节:
bytes_ready = (armed_flag & data[rxptr] & ~data[rxptr-47] & ~data[rxptr-46] & ~data[rxptr-45] & ~data[rx_ptr-44]);
如果bytes_ready
为零,则未接收到任何数据。否则,例如,如果bytes_ready
设置了位2,则意味着可以在数据[rx_ptr-40],数据[rx_ptr-35],数据[rx_ptr-30]等的位2中找到接收到的数据字节。将数据清除armed_flag的位2,并安排在大约44个采样后将其重置。
这种方法将需要在完全接收一个字节数据的那些样本上进行一些工作(如果同时到达所有16个通道一个字节的数据,则可能需要大量工作),但是在大多数样本上,工作量将非常大。轻微。如果一个具有64个I / O引脚,则使用这种方法可以处理多达32个UART,而无需在“普通”情况下增加任何额外的工作。
像Picaxe这样的微控制器可以在一个引脚上接收串行数据,并在某个引脚上适当地输出串行数据。如果您准备告诉Picaxe输出哪个引脚,这将有效地为您提供更多串行输出。它也可以执行相同的操作,但是相反,因此它可以从多个设备接收串行数据并将其发送到Raspberry Pi。另一种选择是使连接的设备需要限定符。这意味着设备1将必须接收数据“ d1”,例如,在设备1侦听串行线上的其他数据之前。设备2可以将“ d2”作为其限定符。这意味着要向设备1说“ hello”,您只需要在UART线上发送“ d1hello”即可。
Picax的价格相当便宜,您可以在http://www.techsupplies.co.uk/上获得它们,它们有多种尺寸,并带有不同数量的针脚,依此类推。
Raspberry Pi 4现在最多支持4个UART接口,需要通过设备树覆盖来启用它。您可以找到操作方法以及目前在此处使用的引脚:
https://www.raspberrypi.org/forums/viewtopic.php?t=244827
RPi基金会仍在为此准备文档。
我有同样的问题。我需要连接2-4个GSM模块,并且找到了硬件解决方案:http : //www.instructables.com/id/SPI-to-4-x-UART-Bridge-MULTIUART/
该解决方案基于PIC24FJ64GA306。您可以用Atmel MCU替换PIC,但是必须创建新的PCB :)