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

k4ymrczo  于 2022-11-22  发布在  其他
关注(0)|答案(1)|浏览(171)

作为标题,我需要通过串口发送一个300-400毫秒的脉冲。我的传感器需要这样的脉冲来唤醒。我的传感器的生产商提供的程序可以在Windows中这样做。但我需要在ubuntu中开发一个类似的程序,因为我的项目是使用ubuntu。任何指向也是赞赏。
敬祝商祺,

8ftvxx2r

8ftvxx2r1#

首先,您需要确定要在哪个引脚上给予脉冲。请查看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
EDIT:根据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调用。对于常规调用,参数'0'将UART的中断控制行设置为0.25秒。对于POSIX命令,中断行设置为参数乘以0.1秒。
EDIT 2:开源最大的好处是源代码是可用的:-)这是来自minicom源代码的逐字记录,它真的很棒,因为它显示了3种发送break的方法:

/*
 * 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);
1.第三个选项也很有趣,因为执行ioctl(fd, TIOCSBRK, 0);,然后执行一些sleep调用,最后执行ioctl(fd, TIOCCBRK, 0);,应该可以发送一个长度经过微调的break信号。
1.第二个选项实际上非常漂亮,因为它展示了如何通过调整端口设置和发送一串零来模拟中断。
那么,结论是什么呢?首先尝试使用tcsendbreak(fd, 0);,因为它是最简单的,如果没有给出好的结果,尝试ioctl(fd, TIOCSBRK, 0); some sort of sleep ; ioctl(fd, TIOCCBRK, 0);。在一个正常的系统上,“模拟中断”应该是不必要的。

相关问题