Har ju en ny version som är i drift på en bana - men det var problem. Displayen (via RS485) visade knasigt ibland - men inget som störde den riktiga visningen av hastigheten, det knasiga kom "efter". Det bestod av "d ou" som visades och efter en snabb sökning i källkoden kom det fram att det var ett debug-meddelanden ("Display#? blanked out due to new speed.") som det kom ifrån.
Men hur FAN kom det dit? Jag använde INTE den buffer som användes till att skriva det i i själva skicka-till-display-rutinen.
Efter att ha klurat lite kom jag fram till att jag ju skrev ett värde i just den buffer och OM displayen samtidig visade ett "gammalt" värde skulle det rensas blev det skickad en rensningskommando.
Detta KUNDE då utlösa ett debugmeddelande (om den bit var aktiverat) för att skriva i klartext på den seriella monitor att det hände och DÅ var värdet pajat.
Då jag väl insåg detta var det ju hyperenkelt att reservera en egen buffer för överföring av data till rutinen och sedan BARA använda textbuffern till just texter.
Jag hade även en klantighet mer. I Config-data har jag en samling bits som anger vilka debug-utskrifter som ska komma. Jag har gjort det så att jag skapade en union i Config-strukturen:
Kod: Markera allt
struct
{
union
{
_UWORD Sys : 1; // 0x0001
_UWORD Measurement : 1; // 0x0002
_UWORD Queue_In : 1; // 0x0004
_UWORD Queue_Out : 1; // 0x0008
_UWORD Specific : 1; // 0x0010
_UWORD RS485 : 1; // 0x0020
} Bits;
_UWORD Total;
} Debug;
Jag skrev ut värdet på dessa bit, bit för bit och var en på var alla på. Och det var ju helt jävla fel!
Men då slog det mig - någon av programmörerna hade gjort fel och då jag är den enda som programmerar på detta kan man ju gissa vem klappträet var...
Sedan ändrade jag till:
Kod: Markera allt
union
{
struct
{
_UWORD Sys : 1; // 0x0001
_UWORD Measurement : 1; // 0x0002
_UWORD Queue_In : 1; // 0x0004
_UWORD Queue_Out : 1; // 0x0008
_UWORD Specific : 1; // 0x0010
_UWORD RS485 : 1; // 0x0020
} Bits;
_UWORD Total;
} Debug;
Och för dom som inte är helt bekväma med detta är det "ganska enkelt" egentligen:
'union' betyder att de delar som ingår i deklarationen alla ligger "ovanpå varandra" så att säga, de börjar alltså på samma adress.
Om jag deklarerar "_UWORD Something : 1;" betyder det att Something fyller 1 bit i en Unsigned Word.
Det som hände först var att bitsen alla var samma union, alltså att alla bitsen var bit 1.
Då jag fick justerat till rätt sätt är bitsen en struct vilket betyder att de får fortlöpande bits i samma _UWORD och att unionen sker så att _UWORD'en med bitsen ligger på samma plats om _UWORD Total.
Så jag kan alltså komma åt värdet antingen bit för bit eller som en 16-bit samling. Till en del funktioner är detta väldigt bra och på väldigt många µC används detta sätt för att definiera olika bits i register.
Jag har ibland en union som följer:
Kod: Markera allt
union
{
uint32_t Big_One;
uint8_t Small_Ones[4];
} Ett_Namn;
Så man kan använda detta trick i bestämda miljöer men man ska undvika det i kod som ska migrera. Kan man inte undvika det MÅSTE man testa det i det nya miljö innan man liter på att det blir bra.
Och om man byter endian kan det bli helt jävla knasigt också...