通过串口发送300-400 ms脉冲

时间:2013-03-31 09:55:08

标签: ubuntu serial-port

作为标题,我需要通过串口发送300-400 ms的脉冲。我的传感器需要这样的脉冲来唤醒。我的传感器生产商提供的程序可以在Windows中执行。但是我需要在ubuntu中开发类似的程序,因为我的项目使用的是ubuntu。 任何指点也表示赞赏。

的问候,

1 个答案:

答案 0 :(得分:2)

首先,您需要确定要给出该脉冲的引脚。查看the Wikipedia page on RS232以查看存在哪些信号。尽管在Tx(发送数据)上发送一个相当不常见的脉冲是可行的,但我认为你需要通过RTS或DTR发送脉冲。

要做到这一点,你需要ioctl这就是怎么做的,假设你要脉冲DTR

int pulseDTR(int fd)
{
    int status;

    // get the current modem control lines status
    if (ioctl(fd, TIOCMGET, &status) == -1) {
        // handle the error
    }

    // Now set DTR high
    status |= TIOCM_DTR;
    // and apply  
    if (ioctl(fd, TIOCMSET, &status) == -1) {
        // handle the error
    }
    // wait a bit
    usleep (400*1000);
    // Now set DTR low
    status &= ~TIOCM_DTR;
    // and apply  
    if (ioctl(fd, TIOCMSET, &status) == -1) {
        // handle the error
    }

    return 0;
}

如果您需要脉冲RTS,只需将TIOCM_DTR替换为TIOCM_RTS

有关串行端口编程的更多信息,我建议使用Serial Programming Guide for POSIX Operating Systemsthe Linux serial Howto

编辑:基于OP的评论发送休息实际上是需要的。发送中断意味着Tx线被拉到逻辑0一段时间(而不是控制信号)。这在Linux serial programming howto中有所描述,完成如下:

使用ioctl:

   int ioctl( fd, TCSBRK, int arg );

使用tc *调用

   int tcsendbreak( fd, int arg );

请注意Linux serial programming howto

的评论
  

发送休息:这里的行动与传统的不同   ioctl()调用和POSIX调用。对于传统的电话,一个arg   '0'将UART的中断控制线设置为0.25秒。为了   POSIX命令,断行线设置为arg乘以0.1秒。

EDIT2:关于开源的好处是源代码可用:-)这是minicom源的逐字记录,它真的很棒,因为它显示了3种发送中断的方法:

/*
 * Send a break
 */
void m_break(int fd)
{
#ifdef USE_SOCKET
  if (portfd_is_socket)
    return;
#endif
#ifdef POSIX_TERMIOS
  tcsendbreak(fd, 0);
#else
#  ifdef _V7
#    ifndef TIOCSBRK
  {
    struct sgttyb sg, ng;

    ioctl(fd, TIOCGETP, &sg);
    ioctl(fd, TIOCGETP, &ng);
    ng.sg_ispeed = ng.sg_ospeed = B110;
    ng.sg_flags = BITS8 | RAW;
    ioctl(fd, TIOCSETP, &ng);
    write(fd, "\0\0\0\0\0\0\0\0\0\0", 10);
    ioctl(fd, TIOCSETP, &sg);
  }
#    else
  ioctl(fd, TIOCSBRK, 0);
  sleep(1);
  ioctl(fd, TIOCCBRK, 0);
#    endif
#  endif
#endif
} 
  1. 我猜Linux使用第一个选项tcsendbreak(fd, 0);
  2. 第三个选项也非常有趣,因为执行ioctl(fd, TIOCSBRK, 0);后跟一些睡眠调用后跟ioctl(fd, TIOCCBRK, 0);应该允许你发送一个精确调整长度的中断信号。
  3. 第二个选项实际上是非常好的,因为它显示了如何通过摆弄端口设置并发送一串零来模拟中断。它对于不实现break的系统总是有用。
  4. 那么,结论呢?首先使用tcsendbreak(fd, 0);,因为它是最简单的,如果没有给出好的结果,请尝试ioctl(fd, TIOCSBRK, 0); some sort of sleep ; ioctl(fd, TIOCCBRK, 0);。在一个理智的系统上,“模拟休息”不是必需的。