usart Klasse
This commit is contained in:
parent
c1564064ac
commit
70e85ab8e9
2
Makefile
2
Makefile
|
@ -10,7 +10,7 @@ COMPILER_PATH = g++
|
|||
OUTPUT = main
|
||||
CFLAGS = -std=c++14 -O3
|
||||
LDFLAGS =
|
||||
OBJECTS = main.o drv/b15f.o drv/plottyfile.o drv/dot.o
|
||||
OBJECTS = main.o drv/usart.o drv/b15f.o drv/plottyfile.o drv/dot.o
|
||||
|
||||
COMPILE = $(COMPILER_PATH) $(CFLAGS)
|
||||
|
||||
|
|
20
drv/b15f.cpp
20
drv/b15f.cpp
|
@ -31,7 +31,7 @@ void B15F::init()
|
|||
|
||||
std::cout << "OK" << std::endl;
|
||||
|
||||
delay(1);
|
||||
delay_ms(1);
|
||||
|
||||
std::cout << PRE << "Teste Verbindung... " << std::flush;
|
||||
uint8_t tries = 3;
|
||||
|
@ -65,7 +65,7 @@ void B15F::reconnect()
|
|||
uint8_t tries = RECONNECT_TRIES;
|
||||
while(tries--)
|
||||
{
|
||||
delay(RECONNECT_TIMEOUT);
|
||||
delay_ms(RECONNECT_TIMEOUT);
|
||||
|
||||
discard();
|
||||
|
||||
|
@ -86,7 +86,7 @@ void B15F::discard(void)
|
|||
for(uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
writeByte(RQ_DISC); // sende discard Befehl (verwerfe input)
|
||||
delay((16000 / BAUDRATE) + 1); // warte mindestens eine Millisekunde, gegebenenfalls mehr
|
||||
delay_ms((16000 / BAUDRATE) + 1); // warte mindestens eine Millisekunde, gegebenenfalls mehr
|
||||
}
|
||||
tcflush(usart, TCIFLUSH); // leere Eingangspuffer
|
||||
}
|
||||
|
@ -219,7 +219,9 @@ bool B15F::analogWrite0(uint16_t value)
|
|||
try
|
||||
{
|
||||
writeByte(RQ_AA0);
|
||||
delay_ms(1);
|
||||
writeInt(value);
|
||||
delay_ms(1);
|
||||
|
||||
uint8_t aw = readByte();
|
||||
return aw == MSG_OK;
|
||||
|
@ -253,6 +255,7 @@ uint16_t B15F::analogRead(uint8_t channel)
|
|||
try
|
||||
{
|
||||
writeByte(RQ_ADC);
|
||||
delay_ms(1);
|
||||
writeByte(channel);
|
||||
return readInt();
|
||||
}
|
||||
|
@ -316,13 +319,13 @@ bool B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset
|
|||
|
||||
|
||||
void B15F::writeByte(uint8_t b)
|
||||
{
|
||||
{
|
||||
if(write(usart, &b, 1) != 1)
|
||||
throw DriverException("Fehler beim Senden. (byte)");
|
||||
}
|
||||
|
||||
void B15F::writeInt(uint16_t v)
|
||||
{
|
||||
{
|
||||
if(write(usart, reinterpret_cast<char*>(&v), 2) != 2)
|
||||
throw DriverException("Fehler beim Senden. (int)");
|
||||
}
|
||||
|
@ -434,10 +437,15 @@ bool B15F::readBlock(uint8_t* buffer, uint16_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
void B15F::delay(uint16_t ms)
|
||||
void B15F::delay_ms(uint16_t ms)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||
}
|
||||
|
||||
void B15F::delay_us(uint16_t us)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(us));
|
||||
}
|
||||
|
||||
B15F& B15F::getInstance(void)
|
||||
{
|
||||
|
|
51
drv/b15f.h
51
drv/b15f.h
|
@ -15,6 +15,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include "driverexception.h"
|
||||
#include "timeoutexception.h"
|
||||
|
||||
class B15F
|
||||
{
|
||||
|
@ -39,25 +40,55 @@ public:
|
|||
uint16_t analogRead(uint8_t);
|
||||
bool analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count);
|
||||
|
||||
// Serielle Verbindung
|
||||
inline void writeByte(uint8_t);
|
||||
inline void writeInt(uint16_t);
|
||||
inline uint8_t readByte(void);
|
||||
inline uint16_t readInt(void);
|
||||
inline bool readBlock(uint8_t* buffer, uint16_t offset);
|
||||
/**
|
||||
* Lässt den Treiber für eine angegebene Zeit pausieren
|
||||
* \param ms Verzögerung in Millisekunden
|
||||
*/
|
||||
void delay_ms(uint16_t ms);
|
||||
|
||||
/**
|
||||
* Lässt den Treiber für eine angegebene Zeit pausieren
|
||||
* \param us Verzögerung in Microsekunden
|
||||
*/
|
||||
void delay_us(uint16_t us);
|
||||
|
||||
void delay(uint16_t);
|
||||
|
||||
/**
|
||||
* Liefert eine Referenz zur aktuellen Treiber-Instanz
|
||||
* @throws DriverException
|
||||
*/
|
||||
static B15F& getInstance(void);
|
||||
|
||||
private:
|
||||
int usart = -1;
|
||||
uint16_t timeout = 100; // ms
|
||||
uint16_t timeout = 1000; // ms
|
||||
uint16_t block_timeout = 1; // ms
|
||||
int TEST = 0;
|
||||
|
||||
static B15F* instance;
|
||||
|
||||
|
||||
/***********************************************
|
||||
* Grundfunktionen für die serielle Verbindung *
|
||||
***********************************************/
|
||||
|
||||
/**
|
||||
* Übergibt ein Byte an die USART Schnittstelle
|
||||
*/
|
||||
void writeByte(uint8_t);
|
||||
|
||||
/**
|
||||
* Übergibt ein Integer an die USART Schnittstelle
|
||||
*/
|
||||
void writeInt(uint16_t);
|
||||
|
||||
/**
|
||||
* Übergibt ein Integer an die USART Schnittstelle
|
||||
* \throws TimeoutException
|
||||
*/
|
||||
uint8_t readByte(void);
|
||||
uint16_t readInt(void);
|
||||
bool readBlock(uint8_t* buffer, uint16_t offset);
|
||||
|
||||
|
||||
// CONSTANTS
|
||||
const std::string PRE = "[B15F] ";
|
||||
|
@ -66,7 +97,7 @@ private:
|
|||
constexpr static uint8_t MSG_FAIL = 0xFE;
|
||||
constexpr static uint16_t RECONNECT_TIMEOUT = 64; // ms
|
||||
constexpr static uint8_t RECONNECT_TRIES = 3;
|
||||
constexpr static uint32_t BAUDRATE = 38400;
|
||||
constexpr static uint32_t BAUDRATE = 115200;
|
||||
constexpr static uint8_t CRC7_POLY = 0x91;
|
||||
|
||||
// REQUESTS
|
||||
|
|
BIN
drv/b15f.o
BIN
drv/b15f.o
Binary file not shown.
|
@ -29,4 +29,4 @@ protected:
|
|||
std::string msg_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // DRIVEREXCEPTION_H
|
||||
|
|
35
drv/timeoutexception.h
Normal file
35
drv/timeoutexception.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef TIMEOUTEXCEPTION_H
|
||||
#define TIMEOUTEXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
|
||||
// SOURCE: https://stackoverflow.com/a/8152888
|
||||
|
||||
class TimeoutException: public std::exception
|
||||
{
|
||||
public:
|
||||
explicit TimeoutException(const char* message, int timeout) : TimeoutException(std::string(message), timeout)
|
||||
{
|
||||
}
|
||||
|
||||
explicit TimeoutException(const std::string& message, int timeout) : msg(message), timeout(timeout)
|
||||
{
|
||||
if(!msg.length())
|
||||
msg = "Timeout reached (" + std::to_string(timeout) + ")";
|
||||
}
|
||||
|
||||
virtual ~TimeoutException() throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string msg;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
#endif // TIMEOUTEXCEPTION_H
|
74
drv/usart.cpp
Normal file
74
drv/usart.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "usart.h"
|
||||
|
||||
USART::USART(std::string device) : device(device)
|
||||
{
|
||||
}
|
||||
|
||||
void USART::openDevice()
|
||||
{
|
||||
file_desc = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
if(file_desc <= 0)
|
||||
throw USARTException("Fehler beim Öffnen des Gerätes");
|
||||
|
||||
struct termios options;
|
||||
int code = tcgetattr(file_desc, &options);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Lesen der Geräteparameter");
|
||||
|
||||
options.c_cflag = CS8 | CLOCAL | CREAD;
|
||||
options.c_iflag = IGNPAR;
|
||||
options.c_oflag = 0;
|
||||
options.c_lflag = 0;
|
||||
options.c_cc[VTIME] = timeout;
|
||||
code = cfsetspeed(&options, baudrate);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Setzen der Baudrate");
|
||||
|
||||
code = tcsetattr(file_desc, TCSANOW, &options);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Setzen der Geräteparameter");
|
||||
|
||||
clearOutputBuffer();
|
||||
clearInputBuffer();
|
||||
}
|
||||
|
||||
void USART::closeDevice()
|
||||
{
|
||||
int code = close(file_desc);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Schließen des Gerätes");
|
||||
}
|
||||
|
||||
void USART::clearInputBuffer()
|
||||
{
|
||||
int code = tcflush(file_desc, TCIFLUSH);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Leeren des Eingangspuffers");
|
||||
}
|
||||
|
||||
void USART::clearOutputBuffer()
|
||||
{
|
||||
int code = tcflush(file_desc, TCOFLUSH);
|
||||
if(code)
|
||||
throw USARTException("Fehler beim Leeren des Ausgangspuffers");
|
||||
}
|
||||
|
||||
uint32_t USART::getBaudrate()
|
||||
{
|
||||
return baudrate;
|
||||
}
|
||||
|
||||
uint8_t USART::getTimeout()
|
||||
{
|
||||
return timeout;
|
||||
}
|
||||
|
||||
void USART::setBaudrate(uint32_t baudrate)
|
||||
{
|
||||
this->baudrate = baudrate;
|
||||
}
|
||||
|
||||
void USART::setTimeout(uint8_t timeout)
|
||||
{
|
||||
this->timeout = timeout;
|
||||
}
|
102
drv/usart.h
Normal file
102
drv/usart.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef USART_H
|
||||
#define USART_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include "usartexception.h"
|
||||
|
||||
class USART
|
||||
{
|
||||
public:
|
||||
USART(std::string device);
|
||||
|
||||
/*************************************************
|
||||
* Methoden für die Verwaltung der Schnittstelle *
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* Öffnet die USART Schnittstelle
|
||||
* \throws USARTException
|
||||
*/
|
||||
void openDevice(void);
|
||||
|
||||
/**
|
||||
* Schließt die USART Schnittstelle
|
||||
* \throws USARTException
|
||||
*/
|
||||
void closeDevice(void);
|
||||
|
||||
/**
|
||||
* Verwirft Daten, die bereits im Puffer liegen, aber noch nicht gelesen wurden
|
||||
* \throws USARTException
|
||||
*/
|
||||
void clearInputBuffer(void);
|
||||
|
||||
/**
|
||||
* Verwirft Daten, die bereits im Puffer liegen, aber noch nicht gesendet wurden
|
||||
* \throws USARTException
|
||||
*/
|
||||
void clearOutputBuffer(void);
|
||||
|
||||
/*************************************************/
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
* Methoden für die Datenübertragung *
|
||||
*************************************/
|
||||
|
||||
/**
|
||||
* Sendet ein Byte über die USART Schnittstelle
|
||||
* \param b das zu sendende Byte
|
||||
* \throws USARTException
|
||||
*/
|
||||
void writeByte(uint8_t b);
|
||||
|
||||
/*************************************/
|
||||
|
||||
|
||||
|
||||
/***************************************
|
||||
* Methoden für einstellbare Parameter *
|
||||
***************************************/
|
||||
|
||||
/**
|
||||
* Liefert die eingestellte Baudrate
|
||||
* <b>Änderungen werden erst nach einem open() wirksam</b>
|
||||
*/
|
||||
uint32_t getBaudrate(void);
|
||||
|
||||
/**
|
||||
* Liefert den eingestellten Timeout (in Dezisekunden)
|
||||
* <b>Änderungen werden erst nach einem open() wirksam</b>
|
||||
*/
|
||||
uint8_t getTimeout(void);
|
||||
|
||||
/**
|
||||
* Setzt die Baudrate
|
||||
* <b>Änderungen werden erst nach einem open() wirksam</b>
|
||||
*/
|
||||
void setBaudrate(uint32_t baudrate);
|
||||
|
||||
/**
|
||||
* Setzt den Timeout (in Dezisekunden)
|
||||
* <b>Änderungen werden erst nach einem open() wirksam</b>
|
||||
*/
|
||||
void setTimeout(uint8_t timeout);
|
||||
|
||||
/***************************************/
|
||||
|
||||
private:
|
||||
|
||||
std::string device; // Gerätepfad
|
||||
int file_desc = -1; // Linux Dateideskriptor
|
||||
uint32_t baudrate = 9600;
|
||||
uint8_t timeout = 10; // in Dezisekunden
|
||||
};
|
||||
|
||||
|
||||
#endif // USART_H
|
BIN
drv/usart.o
Normal file
BIN
drv/usart.o
Normal file
Binary file not shown.
33
drv/usartexception.h
Normal file
33
drv/usartexception.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef USARTEXCEPTION_H
|
||||
#define USARTEXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
// SOURCE: https://stackoverflow.com/a/8152888
|
||||
|
||||
class USARTException: public std::exception
|
||||
{
|
||||
public:
|
||||
explicit USARTException(const char* message) : msg(message)
|
||||
{
|
||||
}
|
||||
|
||||
explicit USARTException(const std::string& message) : msg(message)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~USARTException() throw ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* what() const throw ()
|
||||
{
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
#endif // USARTEXCEPTION_H
|
34
main.cpp
34
main.cpp
|
@ -1,4 +1,6 @@
|
|||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "drv/usart.h"
|
||||
#include "drv/b15f.h"
|
||||
#include "drv/plottyfile.h"
|
||||
|
||||
|
@ -35,9 +37,9 @@ void kennlinieErsterQuadrant()
|
|||
drv.analogWrite1(u_gs);
|
||||
|
||||
drv.analogSequence(0, &ba[0], 0, 1, &bb[0], 0, 0, delta, sample_count);
|
||||
drv.delay(10);
|
||||
drv.delay_ms(10);
|
||||
drv.discard();
|
||||
drv.delay(10);
|
||||
drv.delay_ms(10);
|
||||
|
||||
for(uint16_t k = 0; k < sample_count+1; k++)
|
||||
{
|
||||
|
@ -110,18 +112,34 @@ void beispielFunktionen()
|
|||
{
|
||||
B15F& drv = B15F::getInstance();
|
||||
|
||||
/*
|
||||
|
||||
for(uint16_t i = 0; i < 256; i++)
|
||||
{
|
||||
drv.digitalWrite0(i);
|
||||
drv.delay(50);
|
||||
}*/
|
||||
drv.delay_ms(100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
for(double d = 0; d < M_PI*2; d += .1)
|
||||
{
|
||||
uint16_t v = (sin(d) * 511 + 511);
|
||||
drv.analogWrite0(v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t schwelle_unten = 1023;
|
||||
for(uint16_t i = 0; i < 1024; i++)
|
||||
{
|
||||
drv.analogWrite0(i);
|
||||
drv.delay(1);
|
||||
drv.delay_ms(1);
|
||||
if(drv.digitalRead0() & 0x01)
|
||||
{
|
||||
drv.discard();
|
||||
|
@ -142,7 +160,6 @@ void beispielFunktionen()
|
|||
for(uint16_t i = 1023; i > 0; i--)
|
||||
{
|
||||
drv.analogWrite0(i);
|
||||
drv.delay(1);
|
||||
if(!(drv.digitalRead0() & 0x01))
|
||||
{
|
||||
drv.discard();
|
||||
|
@ -165,7 +182,8 @@ void beispielFunktionen()
|
|||
int main()
|
||||
{
|
||||
|
||||
beispielFunktionen();
|
||||
USART usart("/dev/ttyUSB0");
|
||||
usart.openDevice();
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue