通过串口发送300-400毫秒脉冲

问题描述 投票:0回答:1

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

问候,

ubuntu serial-port
1个回答
3
投票

首先,您需要确定要在哪个引脚上提供该脉冲。 请查看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

有关串行端口编程的更多信息,我推荐POSIX操作系统串行编程指南Linux串行Howto

编辑:根据OP的评论,发送休息实际上是需要的。 发送中断意味着 Tx 线在一定时间内被拉至逻辑 0(而不是控制信号)。 这在 Linux 串行编程指南 中进行了描述,并按如下方式完成:

使用ioctl:

   int ioctl( fd, TCSBRK, int arg );

使用 tc* 调用

   int tcsendbreak( fd, int arg );

请注意Linux串行编程指南

的评论

发送休息:此处的操作与常规操作不同
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. 第二个选项实际上非常漂亮,因为它展示了如何通过摆弄端口设置并发送一串零来模拟中断。 它在不实现中断的系统上总是有用的。

所以,结论? 首先尝试使用

tcsendbreak(fd, 0);
,因为它是最简单的,如果效果不佳,请尝试
ioctl(fd, TIOCSBRK, 0); some sort of sleep ; ioctl(fd, TIOCCBRK, 0);
。 在健全的系统上,“模拟中断”应该是不必要的。

© www.soinside.com 2019 - 2024. All rights reserved.