是否可以在Linux中使用9位串行通信?

时间:2010-06-30 14:38:38

标签: linux serial-port 9-bit-serial

RS-232通信有时使用9位字节。这可用于与总线上的多个微控制器通信,其中8位是数据,而额外位表示地址字节(而不是数据)。非活动控制器仅为地址字节生成中断。

Linux程序可以通过串行设备发送和接收9位字节吗?怎么样?

6 个答案:

答案 0 :(得分:5)

termios系统不直接支持9位操作,但可以通过使用CMSPAR标志进行操作来模拟某些系统。它没有记录,我没有出现在所有实现中。

以下是有关如何完成9位仿真的详细说明的链接:

http://www.lothosoft.ch/thomas/libmip/markspaceparity.php

答案 1 :(得分:3)

9位数据是RS-485的标准部分,用于多点应用。基于16C950器件的硬件可能支持9位,但前提是UART用于950模式(而不是用于RS-232的更常见的450/550模式)。

可以找到16C950的说明here

This页面总结了Linux RS-485支持,它支持更新的内核(> = 3.2 rc3)。

答案 2 :(得分:2)

即使现实世界的UART没有,也可以进行9位数据成帧。 在Windows和Linux下找到了一个也可以使用它的库。 见http://adontec.com/9-bit-serial-communication.htm

答案 3 :(得分:2)

基本上他想要的是从linux盒输出数据,然后发送它,比如说带有一堆max232 ic的2线总线 - >一些微控制器用uart或软件rs232实现

只要各个微控制器(例如,在同一个PCB上,而不是在不同的建筑物中)之间没有电压效能问题,直到最大输出(ttl)负载为止,人们就可以离开单独的max232电平转换器max232(或克隆,或电阻和反相器/晶体管)ic。

无法找到MARK或SPACE奇偶校验的linux termios设置(我确定硬件uarts实际上支持,只是没有linux tty实现),所以我们只是稍微破解实际的奇偶校验生成。

8个数据位,2个停止位的长度与8个数据位相同,1个奇偶校验位,1个停止位。 (其中第一个停止位是逻辑1,负线电压)。

然后,将使用第9位作为指示,其他8位是单个或一组微控制器的地址,然后将下一个字节作为某种命令或数据,它们是'寻址”。

这提供了8位transparant,虽然单向流量,意味着在同一总线上解决“很多事情”(实际上是256个不同的事物组)。这是一种方式,因为当你想要做2路时,你需要2个线对,或者在多个频率上进行调制,或者实现分离检测以及其中的全部。

PIC单片机可以与ehm'一些技巧'进行9位串行通信(第9位实际上在另一个寄存器中;)

现在......考虑到这个事实,在linux和喜欢它不是 - 那么简单......

您是否考虑过简单地为'地址字'(您需要9位的那个)开启奇偶校验;然后将其设置为奇数或偶数,计算它以便选择正确的一个来制作第9个(奇偶校验)位'1',奇偶校验打开,8位'数据',然后关闭奇偶校验并打开2个停止位。 (就微控制器而言,它仍然保持9位字长;)......很久以前,但据我所知,停止位与事物时序中的数据位一样长。

这适用于任何可以进行8位输出,带奇偶校验和2个停止位的操作。其中包括pc硬件和linux。 (和dos等)

pc硬件还可以选择只为所有单词打开或关闭'奇偶校验'(如果我没有实际计算它),如果我从'后面的日子'中正确回忆

此外,pic数据表所述的第9位,实际上是RS-232规范中的奇偶校验位。只是你可以自由关闭或打开它。 (无论如何,在PIC上 - 在Linux中它比这复杂一点)

(linux上没有一些termios设置无法解决,我认为......只需打开和关闭它......我们已经让那些东西做了更奇怪的东西;)

pic微控制器实际上完全相同,只是它没有像数据表中的“它实际是什么”那样呈现。他们实际上称之为“第9位”以及类似的东西。在PC上,因此在Linux上,它的工作原理与此类似。

无论如何,如果这个东西应该“双向”运行,那么祝你好运用2对接线或找出一些方法来进行碰撞检测,这比得到9比特要困难得多。

无论哪种方式,它都不过是高估的移位寄存器。如果电脑上的uart不想这样做(我怀疑),只是滥用DTR引脚只是手动移出数据,或者滥用打印机端口做同样的操作,或挂机移位寄存器到打印机端口...但是使用奇偶校验技巧它应该可以正常工作。

   #include<termios.h>
   #include<stdio.h>
   #include<sys/types.h>
   #include<sys/stat.h>
   #include<fcntl.h>
   #include<unistd.h>
   #include<stdint.h>
   #include<string.h>
   #include<stdlib.h>

   struct termios com1pr;
   int com1fd;

   void bit9oneven(int fd){
   cfmakeraw(&com1pr);
   com1pr.c_iflag=IGNPAR;
   com1pr.c_cflag=CS8|CREAD|CLOCAL|PARENB;
   cfsetispeed(&com1pr,B300);
   cfsetospeed(&com1pr,B300);
   tcsetattr(fd,TCSANOW,&com1pr);
   };//bit9even

   void bit9onodd(int fd){
   cfmakeraw(&com1pr);
   com1pr.c_iflag=IGNPAR;
   com1pr.c_cflag=CS8|CREAD|CLOCAL|PARENB|PARODD;
   cfsetispeed(&com1pr,B300);
   cfsetospeed(&com1pr,B300);
   tcsetattr(fd,TCSANOW,&com1pr);
   };//bit9odd

   void bit9off(int fd){
   cfmakeraw(&com1pr);
   com1pr.c_iflag=IGNPAR;
   com1pr.c_cflag=CS8|CREAD|CLOCAL|CSTOPB;
   cfsetispeed(&com1pr,B300);
   cfsetospeed(&com1pr,B300);
   tcsetattr(fd,TCSANOW,&com1pr);
   };//bit9off

   void initrs232(){
   com1fd=open("/dev/ttyUSB0",O_RDWR|O_SYNC|O_NOCTTY);
   if(com1fd>=0){
   tcflush(com1fd,TCIOFLUSH);
   }else{printf("FAILED TO INITIALIZE\n");exit(1);};
   };//initrs232

   void sendaddress(unsigned char x){
   unsigned char n;
   unsigned char t=0;
   for(n=0;n<8;n++)if(x&2^n)t++;
   if(t&1)bit9oneven(com1fd);
   if(!(t&1))bit9onodd(com1fd);
   write(com1fd,&x,1);
   };

   void main(){

   unsigned char datatosend=0x00; //bogus data byte to send
   initrs232();
   while(1){
   bit9oneven(com1fd);
   while(1)write(com1fd,&datatosend,1);
   //sendaddress(223); // address microcontroller at address 223;
   //write(com1fd,&datatosend,1); // send an a
   //sendaddress(128); // address microcontroller at address 128;
   //write(com1fd,&datatosend,1); //send an a
   }
   //close(com1fd);
   };

有点工作..也许有些事情是错误的,但确实会发送9位。 (CSTOPB设置2个停止位,意味着在8位透明数据上第9位= 1,在寻址模式下第9位= 0;)

另请注意,实际的rs232线路电压水平与您的软件“读取”相反(这与您的PIC微控制器从晶体管或逆变器或max232克隆获得的'反向'5v ttl电平相同我知道了)。 (逻辑1为-19v或-10v(pc),逻辑0为+ 19 / + 10),停止位为负电压,如1,且长度相同。

位出0-7(在这种情况下:8;)...所以起始位 - &gt; 0,1,2,3,4,5,6,7,

它有点hacky但它​​似乎适用于范围。 enter image description here

答案 4 :(得分:1)

  

Linux程序可以通过串行设备发送和接收9位字节吗?

标准UART硬件(8251等)不支持9位数据模式。

答案 5 :(得分:0)

我还为9位UART仿真做了完整的演示(基于偶数/奇数奇偶校验)。你可以找到它here

git上提供的所有来源。

您可以轻松地为您的设备进行调整。希望你喜欢。