Formatovany tisk pro 8bit
Pavel Hudeček
edizon na seznam.cz
Neděle Duben 21 11:24:04 CEST 2024
Tak jsem si s tím pohrál, podařilo se, ale byl to porod, protože avr-g++
je asi nějaký nedodělaný.
Nějakou dobu to vypadalo, že v něm správně nefunguje ani přetížení funkcí
uartSendF(F("long \1---\r\n"), 123456L, 2);
uartSendF(F("float \1---\r\n"), 98765.4321, 2);
funkce deklarována pro long a float
u řádku s 98765.4321 error, že overload je ambignous
Takže následovala laborace s templaty a detekcí typu
//#include <type_traits>
//#include <typeinfo>
File not found, takže normálně to nejde jedním ani druhým způsobem.
Nakonec jsem vytvořil:
template <typename T> class clDetTyp {
public:
char det();
};
template <> char clDetTyp<unsigned int>::det() {
return 'u';
}
template <> char clDetTyp<int>::det() {
return 'i';
}
template <> char clDetTyp<long>::det() {
return 'l';
}
template <> char clDetTyp<float>::det() {
return 'f';
}
template <> char clDetTyp<double>::det() {
return 'd';
}
a použil:
template<typename T>
void uartSendF(const char *t, T val, uint8_t mist) {
clDetTyp<T> d;
if (d.det()=='f' ...
To funguje.
Ale vedlejším produktem je zjištění, že *když napíšu 123.456 není to
float, ale double*:-)
A teda ten "double" má sizeof 4 stejně jako float, což je na 8bitu
očekávané.
Ale WTF proč z des. čísla dělá "double" a ne float?
Takže zpátky na stromy: *Funguje i normální overload*:-)
avr-g++ teda není až takovej krám
uartSendF(F("long \1---\r\n"), 123456L, 2);
uartSendF(F("float \1---\r\n"), 98765.4321, 2);
uartSendF(F("text \1---\r\n"), "blabla");
uartSendF(F("textF blablabla\r\n"));
uartSend("textR blablabla\r\n");
Teď normálně vyplivne:
long 1234,56---
float 98765,43---
text blabla---
textF blablabla
textR blablabla
Jen je škoda, že ten *PSTR *(kterej jsem si předefinoval na F) *se nedá
rozpoznat*, takže mám uartSend na texty v RAM a uartSendF na flash.
------------------------ #include <avr/pgmspace.h> #define UART_sendDT
',' #define UART_sendPosChr 1 #define F PSTR // Poslat číslo na sériák,
na konci oddělit mist desetinným oddělovačem void cisloDT(long x,
uint8_t mist) { // =================================================
char t[10]; uint8_t n; if (x==0) {putchar2('0'); return;} for (n=0; n<10
&& x>0; n++) { t[n]=x % 10 + '0'; x/=10; } //uint8_t dp = n-1-mist; for
(n-=1; n<255; n--) { if (mist>0 && n==mist-1) putchar2(UART_sendDT);
putchar2(t[n]); } } // Poslat char* na sériák void uartSend(char *c) {
// ========================================= for (signed char n=0;
c[n]!=0; n++) putchar2(c[n]); } // Poslat PSTR na sériák void
uartSendF(const char *t) { // ---------------------------------- char c;
for (signed char n=0; (c=pgm_read_byte(&t[n]))!=0; n++) putchar2(c); }
// Poslat na sériák PSTR s vloženým char* void uartSendF(const char
*tFlash, char *tRam) { // ----------------- char c; for (char n=0;
n<255; n++) { c = pgm_read_byte(&tFlash[n]); if (c==0) break; else if
(c==UART_sendPosChr) uartSend(tRam); else putchar2(c); } } // Poslat na
sériák PSTR s vloženým cisloDT void uartSendF_(const char *t, long val,
uint8_t mist) { // --------- char c; for (char n=0; n<255; n++) { c =
pgm_read_byte(&t[n]); if (c==0) break; else if (c==UART_sendPosChr)
cisloDT(val, mist); else putchar2(c); } } // post-test overload - taky
funguje void uartSendFt(const char *t, float val, uint8_t mist) { float
m = 1.0; for (uint8_t n=0; n<mist; n++) m*=10.0; uartSendF_(t,
static_cast<long>(val*m), mist); } void uartSendFt(const char *t, double
val, uint8_t mist) { float m = 1.0; for (uint8_t n=0; n<mist; n++)
m*=10.0; uartSendF_(t, static_cast<long>(val*m), mist); } void
uartSendFt(const char *t, long val, uint8_t mist) { uartSendF_(t, val,
mist); } template <typename T> class clDetTyp { //
=========================== public: char det(); }; template <> char
clDetTyp<unsigned int>::det() { return 'u'; } template <> char
clDetTyp<int>::det() { return 'i'; } template <> char
clDetTyp<long>::det() { return 'l'; } template <> char
clDetTyp<float>::det() { return 'f'; } template <> char
clDetTyp<double>::det() { return 'd'; } template<typename T> void
uartSendF(const char *t, T val, uint8_t mist) { // ==============
clDetTyp<T> d; if (d.det()=='f' || d.det()=='d') { float m = 1.0; for
(uint8_t n=0; n<mist; n++) m*=10.0; uartSendF_(t,
static_cast<long>(val*m), mist); } else if (d.det()=='l') uartSendF_(t,
val, mist); else uartSendF_(t, static_cast<long>(val), mist); }
---------------------------------- cisloDT přejmenuju taky na uartSend.
uartSendF_přejmenuju na uartSendF.
Mám radši nechat ten template s detekcí typů, nebo udělat jen overloady? PH
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20240421/43e8b53b/attachment.htm>
Další informace o konferenci Hw-list