我正在尝试在RedPitaya(运行Ubuntu)上读出传感器。
传感器(RLS的RM08旋转编码器)使用SSI协议。我将时钟线连接到数字输出引脚,将数据线连接到我的Uart RX-PIN。
我现在要我的程序做的是:通过我的函数“ clock_signal()”发送时钟信号后,我希望传感器通过RX-Pin将8位数据发送到UART。
但是,当使用以下代码读取RX缓冲区时,我只会收到消息“再次!”。这意味着它无法读取缓冲区,因为变量rx_length似乎为<0。
希望您能为我解决这个问题-预先感谢!
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h> //Used for UART
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include "redpitaya/rp.h"
static int release();
static int uart_read();
static int clock_signal();
int uart_fd = -1;
#define bitsToRead 8
static int set_interface_attribs(int uart_fd, int speed)
{
struct termios tty;
if (tcgetattr(uart_fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(uart_fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
void set_mincount(int uart_fd, int mcount)
{
struct termios tty;
if (tcgetattr(uart_fd, &tty) < 0) {
printf("Error tcgetattr: %s\n", strerror(errno));
return;
}
tty.c_cc[VMIN] = mcount ? 1 : 0;
tty.c_cc[VTIME] = 5; /* half second timer */
if (tcsetattr(uart_fd, TCSANOW, &tty) < 0)
printf("Error tcsetattr: %s\n", strerror(errno));
}
static int clock_signal()
{
// Initialization of API
if (rp_Init() != RP_OK)
{
fprintf(stderr, "Red Pitaya API init failed!\n");
return EXIT_FAILURE;
}
printf("clock started \n");
//Set PIN DIO1_N to OUTPUT
rp_DpinSetDirection(RP_DIO1_N, RP_OUT);
//The first high/low transition (point 1) stores the current position data in a parallel/serial
converter and the monoflop is triggered
rp_DpinSetState(RP_DIO1_N,1);
usleep(50);
rp_DpinSetState(RP_DIO1_N,0);
usleep(0.2);
for(int i=1; i<=bitsToRead; i++)
{
rp_DpinSetState(RP_DIO1_N,1); //Setzt Digitalen Pin1 auf High
usleep(0.2);
rp_DpinGetState(RP_DIO1_N, &state1);
printf("%i DIO1 high %u \n", i,state1); //Checkt ob State geaendert
rp_DpinSetState(RP_DIO1_N,0); //Setzt DPin1 auf LOW
usleep(0.2);
rp_DpinGetState(RP_DIO1_N, &state1);
printf("%i DIO1 low %u \n", i, state1);
//Get BIT
//rp_DpinGetState(RP_DIO2_N, &state2);
//printf("BIT %i: %u \n", i, state2);
//Get AI1-Value
}
//3 auf 4: Transmit data to UART
rp_DpinSetState(RP_DIO1_N,1); //Setzt Digitalen Pin1 auf High
usleep(15); //Delay for Controller to read positional data (Datasheet), 15microsec
printf("Data sent to UART \n");
return 0;
}
static int uart_read() //can't read
{
// Don't block serial read
fcntl(uart_fd, F_SETFL, FNDELAY);
if(uart_fd == -1){
fprintf(stderr, "Failed to read from UART.\n");
return -1;
}
unsigned char rx_buffer[bitsToRead];
int rx_length = read(uart_fd, (void*)rx_buffer, bitsToRead);
if (rx_length < 0){
// No data yet avaliable, check again
if(errno == EAGAIN){
fprintf(stderr, "AGAIN!\n");
// Error differs
}else{
fprintf(stderr, "Error!\n");
return -1;
}
}else if (rx_length == 0){
fprintf(stderr, "No data waiting\n");
// Print data and exit while loop
}else{
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
}
return 0;
}
static int release(){
tcflush(uart_fd, TCIFLUSH);
close(uart_fd);
return 0;
}
int main()
{
char *portname = "/dev/ttyPS1";
uart_fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (uart_fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
set_interface_attribs(uart_fd, B115200);
//set_mincount(uart_fd, 0); /* set to pure timed read */
/*Flush Buffer
sleep(2); //required to make flush work, for some reason
tcflush(uart_fd,TCIOFLUSH);
*/
// CLOCK
clock_signal();
// Sample read
if(uart_read() < 0)
{
printf("Uart read error\n");
return -1;
}
/* CLOSING UART */
release();
return 0;
}