<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
A ještě jsem voliteně přidal ty taby:<br>
<br>
putcharTabsPoss[0] = 8;<br>
putcharTabsPoss[1] = 16;<br>
putcharTabsPoss[2] = 24;<br>
<br>
uartSendF(F("tt \t1 \t2 \t 3\r\n"));<br>
uartSendF(F("ttt \t1111 \t2222 \t333333\r\n"));<br>
uartSendF(F("ttt \t1111111 \t2222222 \t333333333\n\n\r\n"));<br>
<br>
putcharTabsPoss[0] = 10;<br>
putcharTabsPoss[1] = 20;<br>
putcharTabsPoss[2] = 30;<br>
<br>
uartSendF(F("tt \t1 \t2 \t3\r\n"));<br>
uartSendF(F("ttt \t1111 \t2222 \t333333\r\n"));<br>
uartSendF(F("ttt \t1111111 \t2222222 \t333333333\n\n\r\n"));<br>
<br>
výsledek je:<br>
<font face="monospace">tt 1 2 3<br>
ttt 1111 2222 333333<br>
ttt 1111111 2222222 333333333<br>
<br>
tt 1 2 3<br>
ttt 1111 2222 333333<br>
ttt 1111111 2222222 333333333</font><br>
<br>
a takhle vypadá putchar a související:<br>
<br>
------------------------<br>
<font face="monospace">#</font><font face="monospace">define
UART_sendTabExt 3<br>
<br>
#ifndef UART_sendTabExt // >0 Použít tabulku zadané
velikosti, s pozicema pro \t v putcharu<br>
#define UART_sendTabExt 0<br>
#endif<br>
<br>
#if (UART_sendTabExt==0)<br>
void putchar2(char c) { //
===============================================================<br>
#if (UART_num == 1) // 0 DPS / 1 kit<br>
while ((USART1.STATUS & USART_DREIF_bm) == 0);<br>
USART1.TXDATAL=c;<br>
#else<br>
while ((USART0.STATUS & USART_DREIF_bm) == 0);<br>
USART0.TXDATAL=c;<br>
#endif<br>
}<br>
#else //(UART_sendTabExt==0)<br>
<br>
#ifndef putcharTabsPoss<br>
uint8_t putcharTabsPoss[UART_sendTabExt];<br>
#endif<br>
<br>
void putchar2(char c) { // ==============================<br>
static volatile uint8_t lastPos = 0;<br>
<br>
<br>
if (c=='\n' || c=='\r') lastPos=0;<br>
else if (c=='\t') {<br>
uint8_t n;<br>
for (n=0; n<UART_sendTabExt; n++) if
(putcharTabsPoss[n]>lastPos) break;<br>
if (n<UART_sendTabExt) {<br>
while (lastPos < putcharTabsPoss[n]) putchar2(' ');<br>
}<br>
return;<br>
}<br>
<br>
#if (UART_num == 1) // 0 DPS / 1 kit<br>
while ((USART1.STATUS & USART_DREIF_bm) == 0);<br>
USART1.TXDATAL=c;<br>
if (c=='\n' || c=='\r') lastPos=0;<br>
#else // (UART_num == 1)<br>
while ((USART0.STATUS & USART_DREIF_bm) == 0);<br>
USART0.TXDATAL=c;<br>
#endif // (UART_num == 1)<br>
lastPos++;<br>
}<br>
<br>
#endif //(UART_sendTabExt==0)</font><br>
----------------------<br>
<br>
Poznámka:<br>
Zajímavé je, že na PORTA, PORTB, ... funguje define, ale USART0,
USART1, ... přes define nefunguje, tak je tam vopičárna s <font
face="monospace">UART_num.<br>
<br>
PH<br>
</font><br>
<div class="moz-cite-prefix">Dne 21.04.2024 v 11:24 Pavel Hudeček
napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:ba85baab-6331-4641-9242-c4c584f3e3c3@seznam.cz">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
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ý.<br>
<br>
Nějakou dobu to vypadalo, že v něm správně nefunguje ani přetížení
funkcí<br>
<font face="monospace">uartSendF(F("long \1---\r\n"), 123456L,
2);<br>
uartSendF(F("float \1---\r\n"), 98765.4321, 2);</font><br>
funkce deklarována pro long a float<br>
u řádku s 98765.4321 error, že overload je ambignous<br>
<br>
Takže následovala laborace s templaty a detekcí typu<br>
<font face="monospace">//#include <type_traits><br>
//#include <typeinfo></font><br>
File not found, takže normálně to nejde jedním ani druhým
způsobem.<br>
<br>
Nakonec jsem vytvořil:<br>
<font face="monospace">template <typename T> class clDetTyp
{<br>
public:<br>
char det();<br>
};<br>
<br>
template <> char clDetTyp<unsigned int>::det() {<br>
return 'u';<br>
}<br>
template <> char clDetTyp<int>::det() {<br>
return 'i';<br>
}<br>
template <> char clDetTyp<long>::det() {<br>
return 'l';<br>
}<br>
template <> char clDetTyp<float>::det() {<br>
return 'f';<br>
}<br>
template <> char clDetTyp<double>::det() {<br>
return 'd';<br>
}</font><br>
<br>
a použil:<br>
<br>
<font face="monospace">template<typename T><br>
void uartSendF(const char *t, T val, uint8_t mist) {<br>
clDetTyp<T> d;<br>
if (d.det()=='f' ...</font><br>
<br>
To funguje.<br>
Ale vedlejším produktem je zjištění, že <b>když napíšu 123.456
není to float, ale double</b>:-)<br>
A teda ten "double" má sizeof 4 stejně jako float, což je na 8bitu
očekávané.<br>
Ale WTF proč z des. čísla dělá "double" a ne float?<br>
<br>
Takže zpátky na stromy: <b>Funguje i normální overload</b>:-)<br>
avr-g++ teda není až takovej krám<br>
<br>
<font face="monospace">uartSendF(F("long \1---\r\n"), 123456L,
2);<br>
uartSendF(F("float \1---\r\n"), 98765.4321, 2);<br>
uartSendF(F("text \1---\r\n"), "blabla");<br>
uartSendF(F("textF blablabla\r\n"));<br>
uartSend("textR blablabla\r\n");<br>
</font><br>
Teď normálně vyplivne:<br>
<font face="monospace">long 1234,56---<br>
float 98765,43---<br>
text blabla---<br>
textF blablabla<br>
textR blablabla</font><br>
<br>
Jen je škoda, že ten <b>PSTR </b>(kterej jsem si předefinoval na
F) <b>se nedá rozpoznat</b>, takže mám uartSend na texty v RAM a
uartSendF na flash.<br>
<span style="white-space: pre-wrap">
------------------------
<font face="monospace">#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);
}</font>
----------------------------------
</span><span style="white-space: pre-wrap"><font face="monospace">cisloDT </font></span><span
style="white-space: pre-wrap">přejmenuju taky na uartSend.
</span><span style="white-space: pre-wrap"><font face="monospace">uartSendF_</font></span><span
style="white-space: pre-wrap"> přejmenuju na </span><span
style="white-space: pre-wrap"><font face="monospace">uartSendF.</font></span><br>
<span style="white-space: pre-wrap">
Mám radši nechat ten template s detekcí typů, nebo udělat jen overloady?
PH
</span>
<blockquote type="cite"
cite="mid:b01b7f84-7e73-407b-b567-dbd0f77e05e7@seznam.cz">
<blockquote type="cite"
cite="mid:07035d67-bd13-4ca5-8b45-c6fcaf944dee@volny.cz">
<blockquote type="cite"
cite="mid:674463bf-438e-4e67-88aa-34cf0e2f0c10@seznam.cz">
<blockquote type="cite"
cite="mid:62da3616-1d24-431d-9cf0-0c397e03b07f@volny.cz">
<blockquote type="cite"
cite="mid:cafe8589-63d8-448f-9f19-eb19f16669d4@seznam.cz">
<blockquote type="cite"
cite="mid:ab12d61f-7c9b-4434-9138-43db4d9875b4@volny.cz">
<blockquote type="cite"
cite="mid:b4bb63a0-c0e8-4e00-bb0f-836ae08e652c@seznam.cz"> </blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<span style="white-space: pre-wrap">
</span></blockquote>
<br>
</body>
</html>