我的 uart 读取有问题(在树莓派上)。它工作正常,但它在循环中停止并等待数据......我做了一个选择O_NDELAY
,但即使如此也停止了。
我使用两个终端窗口:
- 一个用于uart程序
在第二个我写:
echo '123445' > /dev/ttyAMA0
(树莓派 uart 端口)
完整代码如下。
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
int main(int argv, char * argc[])
{
// Setting Up The UART
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios cfg;
//get existing configuration setup
tcgetattr(uart0_filestream, &cfg);
//fcntl(deviceFD, F_SETFL, FNDELAY);
fcntl(uart0_filestream, F_SETFL, 0);
////set both incoming and outgoing baud rates...
cfsetispeed(&cfg, B115200);
cfsetospeed(&cfg, B115200);
cfg.c_cflag |= (CLOCAL | CREAD);
////8N1 (8 data bits, No parity, 1 stop bit)
cfg.c_cflag &= ~PARENB;
cfg.c_cflag &= ~CSTOPB;
cfg.c_cflag &= ~CSIZE;
cfg.c_cflag |= CS8;
cfg.c_cflag &= ~CRTSCTS; //~CNEW_RTSCTS; //disable hardware flow control
//use RAW unbuffered data mode (eg, not canonical mode)
cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IGNBRK);
cfg.c_iflag &= ~(IGNPAR | IXON | IXOFF | IXANY);
//raw (unprocessed) output mode
cfg.c_oflag &= ~OPOST;
tcsetattr(uart0_filestream, TCSANOW, &cfg);
//Transmitting Bytes
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'H';
*p_tx_buffer++ = 'e';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'o';
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
if (count < 0)
{
printf("UART TX error\n");
}
}
//Receiving Bytes
//----- CHECK FOR ANY RX BYTES -----
while(1) {
printf("loop\n");
if (uart0_filestream != -1)
{
// Read up to 255 characters from the port if they are there
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//An error occured
printf("UART RX error\n");
}
else if (rx_length == 0)
{
//No data waiting
printf("no data UART RX test commit\n");
}
else
{
//Bytes received
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
//break;
}
}
sleep(1);
}
//Closing the UART if no longer needed
//----- CLOSE THE UART -----
close(uart0_filestream);
return 0;
}