Diskuze: Převod HEX hodnoty na DEC ascii
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 15 zpráv z 15.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
#define _CRT_SECURE_NO_WARNINGS
#include <cstdlib>
int main(){
unsigned _int32 Latitude = 0x1DD82DB4 // 500706740 (dec)
char ASCIIdec[20];
_itoa(Latitude, ASCIIdec, 10);
return 0;
}
Ty používáš postup převodu z desítkové soustavy...
Pro převod z jiné do desítkové je to trochu jinak (wiki píše: Např. 3F7H
reprezentuje hodnotu, které v desítkové soustavě odpovídá číslu
3×162 + 15×161 + 7×160 = 1015.)
Při převodu HEX na DEC je potřeba postupně dělit HEX číslo násobky 10
např.
0x1DD82DB4 t.j. 500706740 (dec) / 100000000 (tj. 10E8) = 5, 5 převést na ASCII
a uložit do výsledného pole. Pak od HEX odečíst 5 x 10E8 a získaz další
cifru dělením 10000000 (10E7) atd.
void numToStr(unsigned u, char *str);
int main() {
unsigned _int32 Latitude = 0x1DD82DB4; // 500706740 (dec)
char ASCIIdec[20];
numToStr(Latitude, ASCIIdec);
return 0;
}
void numToStr(unsigned u, char *str) {
char c, *p = str;
if (!u) {
*str = '0';
*(str + 1) = '\0';
return;
}
while (u > 0) {
*(p++) = u % 10 + '0';
u /= 10;
}
*p = '\0';
for (int i = 0; i < (p - str) / 2; i++) {
c = *(str + i);
*(str + i) = *(str + (p - str) - 1 - i);
*(str + (p - str) - 1 - i) = c;
}
}
Díky, nakonec jsem to dal na mikrochipu dohromady, nicméně mi někdo
poradil, že stačí použít funkci ultoa(LAT, ASCIIdec, 10); .
#include <atmel_start.h>
char ASCIIdec[9];
unsigned long LAT = 0x1DD82DB4; /* LAT +8 1DD82DB4 = 500706740 / 1E7 = 50.07067 */
volatile unsigned char flag; /* Suppression of insignificant 0 from left (' ') */
volatile unsigned char digit_v, digit_ch;
volatile unsigned long number, multiple_ten;
volatile signed char i, j;
void ASde(unsigned long HEXval) {
flag = 0;
number = HEXval;
multiple_ten = 0x5F5E100; // 100,000,000
for (i = 8; i >= 0; i--) {
digit_v = number / multiple_ten;
number = number - (digit_v * multiple_ten);
multiple_ten = multiple_ten /10;
if ((digit_v == 0) && (flag == 0)) {
ASCIIdec[8 - i] = ' ';
} else {
flag = 1;
digit_ch = digit_v + '0';
ASCIIdec[8 - i] = digit_ch;
}
}
}
int main(void) {
/* Initializes MCU, drivers and middleware */
atmel_start_init();
ASde(LAT);
// ultoa(LAT, ASCIIdec, 10);
asm("nop");
/* Replace with your application code */
while (1) {
}
}
Ja bych pouzil binarni rotace a binarni nasobeni x>>4, x&0f.
jinak, mocny google: https://www.itnetwork.cz/dev-lighter/261
private static int ToDec(this string s)
{
Dictionary<char, int> dic = new Dictionary<char, int>()
{
{'0', 0},
{'1', 1},
{'2', 2},
{'3', 3},
{'4', 4},
{'5', 5},
{'6', 6},
{'7', 7},
{'8', 8},
{'9', 9},
{'A', 10},
{'B', 11},
{'C', 12},
{'D', 13},
{'E', 14},
{'F', 15},
};
int result = 0;
int n = s.Length -1;
foreach (var c in s)
result += (dic[c] * (int)Math.Pow(16,n--));
return result;
}
Misto deleni pouzivaji aritmeticke rotace, coz by melo byt tak o dost rychlejsi.
Aha, ni, to vypadalo, ze si chces udelat vlastni funkci Jinak teda, jak uz tu psali, kdyz
pouzivat 16tkovou soustavu, tak v tech cislech musi byt 16 a ne 10. Cili x
4
nebo x/16, x
4 nebo x*16.
K čemu potřebuješ takovýto typ převodu? Zejména tu část, kde chceš číslo reprezentovat jako jeho ASCII řetězec. Přístup k jednotlivým bitům daného čísla Ti nestačí? Pokud jsou již data v paměti, pak je převádění z jedné soustavy do druhé zbytečné, neboť je to pořád ta samá hodnota, interně reprezentována binárně.
Podívej, jak snadno lze číslo z paměti v jakékoli soustavě vypsat do lidsky čitelné podoby.
#include <stdio.h>
void intToBin(unsigned int num);
void showValue(unsigned int num);
int main(void) {
unsigned int oct = 03566026664; // 8
unsigned int dec = 500706740; // 10
unsigned int hex = 0x1DD82DB4; // 16
intToBin(oct);
intToBin(dec);
intToBin(hex);
showValue(oct);
showValue(dec);
showValue(hex);
return 0;
}
void intToBin(unsigned int num) {
for (int i = 31; i >= 0; i--) {
if (num & (1 << i)) putchar('1');
else putchar('0');
}
putchar('\n');
}
void showValue(unsigned int num) {
unsigned int val = 0;
for (int i = 0; i < 32; i++) {
val += num & (1 << i);
}
printf("%d\n", val);
}
Data, která pořizuje jednočipový mikroprocesor (6x6x1 mm) a GPSka
(4,5x4,5x1 mm) a posílá je přes síť IoT na server, musím někde převést
na ASCII znaky, které potřebuje aplikace Android, kterou vytvářím, pro
zobrazení trasy pohybu (polohy) na mapě světa. Všechno navrhuji a programuji
sám .
Takže takový GPS Tracker. To je rozhodně zajímavý projekt, který se dá dále rozšiřovat
o spoustu užitečných vychytávek. Tedy GPS Ti získává souřadnice a
posílá Ti je v komprimované podobě (hex číslo) na server. Komprimovaná
data obsahují všechny potřebné souřadnice nutné pro přesné získání
polohy. Tyto data potřebuješ získat aby si je mohl spárovat s mapou, na
které poté zobrazíš výslednou cestu.
Pak získání přístupu k jednotlivým číslicím může mít své
opodstatnění. A nejsou ta data přesně uložena ve spodních a horních dvou
bytech? Pošli ukázku poslané informace za jednotku času a to co by to mělo
představovat. Třeba se dá něco optimalizovat lépe.
Zkusil jsem spustit tvůj kód výše ve Visual Studiu:
00011101110110000010110110110100
00011101110110000010110110110100
00011101110110000010110110110100
500706740
500706740
500706740
Dnes mi kurýr přivezl vývojovou desku s jednočipovým MCU z Dallasu, tak se do toho pustím.
Data jsou uložena jako long uint (32 bitů) ve formátu Little Endian.
Ano, to je správný výstup programu. Ukazuje to, že v paměti jsou všechny číselné soustavy rovny, přístup k jednotlivým bitům proměnné a lidský čitelný výstup číselné proměnné v načtené v libovolné číselné soustavě.
To se kurýr docela proletěl. Že se jedná o celočíselnou 32bit proměnnou je jasné, šlo mi o obsazenost bitů pro tu kterou proměnnou v příchozích datech.
Jak jsem již psal, vývojová deska včera dorazila a na LoRaWAN síti jsou již první zkušební data. Čekám, až mi z Číny dorazí logický analyzátor na I2C sběrnici abych doladil načítaní dat z GPSky. Něco jiného je zkoušet funkčnost I2C přes Arduino (funguje) a jednočipový mikrokontrolér.
Zobrazeno 15 zpráv z 15.