0

我正在用 C 语言为 Arduino Mega 2560 编写代码,我正在尝试通过串行端口进行双向通信。但是,只有将数据从 Arduino 发送到 PC 才有效——反之则不行。arduino 上的 RX LED 很快亮起,但我的代码没有接收到数据(连接到“pin 13”的 LED 没有亮起)。有谁知道如何解决这一问题?

这是在 arduino 上运行的代码:

#define USART_BAUDRATE 500000
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

static void serial_init(void) {
  // load upper 8 bits of the baud rate into the high byte of the UBRR register
  UBRR0H = (BAUD_PRESCALE >> 8);
  // load lower 8 bits of the baud rate into the low byte of the UBRR register
  UBRR0L = BAUD_PRESCALE;

  // 8data,1stopbit
  UCSR0C = (0 << UMSEL00) | (1 << UCSZ00) | (1 << UCSZ01);
  // turn on the transmission and reception circuitry
  UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (0 << UCSZ02);
}

static void sendbyte(uint8_t b) {
  // do nothing until UDR is ready for more data to be written to it
  while ((UCSR0A & (1 << UDRE0)) == 0) {};
  // memory was cleared - write to it
  UDR0 = b;
}

static void digi_init() {
  // configure port B7 (arduino digital port 13) as output and set it low
  PORTB = (0<<PB7);
  DDRB = (1<<DDB7);
}

static void digi_set(int val) {
  PORTB = (val<<PB7);
}

int main(void) {
  serial_init();
  digi_init();

  while (1) {
    if ((UCSR0A & (1 << RXC0)) == 1) {
      // we got some data, light up the LED!
      digi_set(1);
    }

    _delay_ms(50);
    sendbyte('.');
  }
}

这是在 PC 上运行的代码:

int main(int argc, char *argv[]) {
  char *serialdevicepath = "/dev/ttyACM0";

  fprintf(stderr, "Connecting to serial device ...\n");
  int serial_fd = open(serialdevicepath, O_RDWR | O_NOCTTY);
  struct termios config;
  if(tcgetattr(serial_fd, &config) < 0) exit(1);
  config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
  config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
  config.c_cflag &= ~(CSIZE | PARENB);
  config.c_cflag |= CS8;
  config.c_cc[VMIN]  = 1;
  config.c_cc[VTIME] = 0;
  if(cfsetispeed(&config, B500000) < 0 || cfsetospeed(&config, B500000) < 0) exit(1);
  if(tcsetattr(serial_fd, TCSAFLUSH, &config) < 0) exit(1);
  FILE *serial = fdopen(serial_fd, "r");

  setbuf(stdin, NULL);
  fcntl(0/*stdin*/, F_SETFL, O_NONBLOCK);
  setbuf(stdout, NULL);
  setbuf(stderr, NULL);
  setbuf(serial, NULL);

  while (1) {
    char c;
    while (read(0, &c, 1) == 1) {
      if (c != '+' && c != '-') continue;
      uint8_t val = (c == '+') ? 42 : 41;
      if (write(serial_fd, &val, 1) != 1) {
        assert(0);
      }
    }

    char b = fgetc(serial))&0xe0);
    fprintf(stderr, "read 0x%x\n", b);    
  }

  return 0;
}

(是的,我在 PC 上键入 <+> 以便它发送数据。另外,我尝试直接从代码中打开 LED 并且它起作用了。)

4

1 回答 1

2
if ((UCSR0A & (1 << RXC0)) == 1) 

该测试是错误的,它永远不会是 1。这里的 & 运算符将产生 0 或 (1 << RXC0)。改用这种方式:

if ((UCSR0A & (1 << RXC0)) != 0) 

或者在 C 中,您通常会这样写,因为任何非零值在逻辑上都是正确的:

if (UCSR0A & (1 << RXC0)) 
于 2013-01-11T18:47:59.733 回答