usart Klasse

This commit is contained in:
Tristan Krause 2019-03-29 11:12:31 +01:00
parent c1564064ac
commit 70e85ab8e9
13 changed files with 327 additions and 26 deletions

View file

@ -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)

View file

@ -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)
{

View file

@ -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

Binary file not shown.

View file

@ -29,4 +29,4 @@ protected:
std::string msg_;
};
#endif
#endif // DRIVEREXCEPTION_H

35
drv/timeoutexception.h Normal file
View 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
View 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
View 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

Binary file not shown.

33
drv/usartexception.h Normal file
View 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

BIN
main

Binary file not shown.

View file

@ -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();

BIN
main.o

Binary file not shown.