【问题标题】:UART Receiving keyboard input doesn't workUART接收键盘输入不起作用
【发布时间】:2016-09-05 21:59:18
【问题描述】:

我无法读取通过 UART 从笔记本电脑发送到微控制器的数据。传输部分工作正常 - 我可以毫无问题地将数据发送到我的笔记本电脑,但回显数据或从笔记本电脑读取键盘输入数据不起作用。我尝试使用轮询和 Rx 中断例程来实现读取,但没有成功。我使用的微控制器是 ATMEGA2560,我通过 FTD1232 USB 到 TTL 串行转换器连接到我的笔记本电脑。

我使用 Putty 作为串行通讯终端,使用 Arduino IDE 进行编程。

我假设问题不在于基于以下的硬件 - 我尝试初始化不同的 USART 并尝试使用不同的 COM 端口,以及另一个 USB 到 TTL 转换器,各种电线,但结果是相同的。我还连接了另一个电源,为所有设备提供足够的电压。

当发生 Rx 中断时(当我在终端中键入内容时),我试图通过打开 LED 来获得至少一个响应。

~

#define F_CPU 16000000UL //16MHz
#define BAUD 115200UL //bps
#define BAUD_PRESCALER (((F_CPU/(BAUD*8UL)))-1) //Table 101, page 212

volatile uint8_t temp;

void UART_init(){
  //Set baud rate
  UBRR0H = (uint8_t)(BAUD_PRESCALER >> 8); //Higher portion of the baud rate
  UBRR0L = (uint8_t)BAUD_PRESCALER; //Lower portion of the baud rate

  //Enable Receiver and Transmitter
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  //Set frame format: 8-bit format, 1 stop bit, no parity
  UCSR0C |= (3 << UCSZ00);
  UCSR0C &= ~(1 << USBS0); //clear for 1 stop bit

  //Set Double Speed Asynchronous mode
  UCSR0A |= (1 << U2X0);

  UCSR0B |= (1 << RXCIE0); //Enables interrupt rxc
}

uint8_t UART_getchar(){
  //Wait for RXC flag
  while(!(UCSR0A & (1 << RXC0))){};
  return UDR0;
}

//Arduino setup()
void setup(){
  pinMode(8, OUTPUT);
  UART_init();
  sei();
}

//Arduino loop()
void loop(){
  delay(500);
  UART_putchar('a');
}

ISR(USART0_RX_vect){
  temp = UDR0;
  digitalWrite(8, HIGH);
}

这是一个冗长的帖子,但我试图具体并发布整个代码。我用于 ATMEGA2560 的数据表可以在 here 找到。

我的腻子设置:

COM Port Settings

【问题讨论】:

  • 我假设您已经验证了您的 LED 代码(即可以随意打开/关闭)。您是否在轮询模式下尝试过 recv(即不使用/依赖中断)来验证包括 recv 引脚/电线在内的所有设备的连接性?当轮询工作时,然后调试中断。我检查了你的初始化,似乎还可以,但如果你使用显式赋值而不是 OR/AND,我会更高兴。确保您不错误地设置了 9 位模式 [参见第 219 页] 请注意,第 3 个 USCZ 位在 UCSRB [并且 not UCSRC像下面的两个]。并且,请参阅从第 227 页开始的寄存器位定义。对照文档交叉检查 .h。
  • Arduino 不是 C!请参阅 How to Ask 并提供 minimal reproducible example,而不仅仅是 sn-ps。
  • 选择一个:轮询或 RX ISR。不要忘记 Arduino Serial 也在使用 ISR。
  • @CraigEstey LED 正在正常工作。唯一有效的函数是 putchar 和 putstring 函数。 polled 中的 recv 根本没有显示生命迹象 - 与中断相同。

标签: arduino interrupt uart serial-communication atmega


【解决方案1】:

我刚刚在我的 Mega 板上对其进行了测试,它在不启用中断的情况下工作正常(简单环回):

#define BAUD 115200UL
#define BAUD_PRESCALER (((F_CPU/(BAUD*8UL)))-1)

volatile uint8_t temp;

void UART_init(){
  //Set baud rate
  UBRR0H = (uint8_t)(BAUD_PRESCALER >> 8); //Higher portion of the baud rate
  UBRR0L = (uint8_t)BAUD_PRESCALER; //Lower portion of the baud rate

  //Enable Receiver and Transmitter
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
  //Set frame format: 8-bit format, 1 stop bit, no parity
  UCSR0C |= (3 << UCSZ00);
  UCSR0C &= ~(1 << USBS0); //clear for 1 stop bit

  //Set Double Speed Asynchronous mode
  UCSR0A |= (1 << U2X0);
//  UCSR0B |= (1 << RXCIE0); //Enables interrupt rxc
}

uint8_t UART_getchar(){
  //Wait for RXC flag
  while(!(UCSR0A & (1 << RXC0))){};
  return UDR0;
}

void UART_putchar(uint8_t data){
  //Do nothing until UDR is ready
  while(!(UCSR0A &(1 << UDRE0))){};
  UDR0 = data;
}

void UART_putstring(uint8_t *data){
  while(*data != 0x00){
    UART_putchar(*data);
    data++;
  }
}

//Arduino setup()
void setup(){
  pinMode(8, OUTPUT);
  UART_init();
  sei();
}

//Arduino loop()
void loop(){
  UART_putchar(UART_getchar());
}

/*ISR(USART0_RX_vect){
  temp = UDR0;
  digitalWrite(8, HIGH);
}*/

RX 中断必须被禁用,否则串行中断向量正在发生并且 polled get char 不能工作,因为 ISR 读取字符

【讨论】:

  • 问题显然出在我使用的 FTDI(两者)中。当我只连接用于编程板的 USB 电缆运行我的代码时,一切正常,但如果我尝试通过 FTDI 进行通信,则只有传输工作。我会进一步研究。谢谢你:)
  • 如果您使用的是 USART0,板载 USB-Serial 也在哪里连接,我并不感到惊讶。如果它不适用于其他 USART,那就太奇怪了。无论如何,你可以通过连接它的 TX 和 RX 来测试你的 FTDI 芯片来做简单的环回测试。
猜你喜欢
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多