PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : hexadezimale Werte im Array !



casa74
16.08.2005, 13:41
Hallo Zusammen,

möchte gerne 30 konstante hexadezimale Werte in einem Array speichern.(ATMEGA8),
die dann später der Reihe nach über den USART ausgegeben werden sollen.

Für das Speichern von char Zeichen kann ich ja einfach folgenden Befehl nutzen:

Beispiel:

char Array[30]='a','b','c','d','e'....,\0;


Kann ich genauso mit hexadezimalen Werten verfahren ??
Oder gibt es da sogar eine andere Methode ?


Danke und Gruß

Casa74

cavegn
16.08.2005, 13:53
hi

ja, das geht auch mit hex-werten:

unsigned char myArray[] = {0x01, 0x02, 0xff};

unsigned desshalb, da signed von -128 bis 127 geht, und alle werte ab 0x7f grösser als 127 sind -> sonst kanns kompilerwarnungen geben

cu

chris

casa74
16.08.2005, 14:17
Ja super!

Vielen Dank!


casa74

casa74
16.08.2005, 15:26
Noch mal eine Frage dazu!

Kann man den Inhalt von 2 Arrays zu einem zusammenfassen um ihn dann später zu senden ?

Das Problem ist ,daß die Daten die ich senden möchte zu einem Teil aus
Konstanten besteht und zum anderen aus Daten ,die über den USART empfangen werden
und in einem anderen Array gespeichert werden.
Diese möchte ich dann gerne zusammenfügen und aus einem Array auslesen und an den TX des USART führen.
geht das ? und wenn ja, wie würde das aussehen ?

Danke
Casa74

cavegn
16.08.2005, 20:03
hmm, kannst du genauer beschreiben, wie dieses zusammensetzen aussehen soll?

am besten mit zahlenbeispiel - da gibts sicher eine möglichkeit

cu

chris

ps: wenn du zuerst das eine, dann das andere array übertragen willst, machst du das am besten in der sende-methode

also sinngemäss:

send(){
für jedes element von array1{
sende zeichen;
}
für jedes element von array2{
sende zeichen;
}
}

sep
16.08.2005, 20:06
Warum kann man in ein char - Feld auch Hexwerte schreiben?

Weil ein char auch nur ein Byte ist.
Egal ob du


char a = 'a';
char a = 97;
char a = 0x61;
char a = 0b01100001;

schreibst, es passiert immer dasselbe denn

Ascii-Wert von a = 97
HEX(97) = 61
BINÄR(97) = 01100001

Für den Rechner gibt es da keinen Unterschied, er sieht keine Buchstaben, nur Binärzahlen.


Array kopierst du einfach aneinander:


char a[] = {'a','b','c'};
char b[] = {'1','2','3'};
char c[];

c = a + b; // FALSCH!!!! a und b sind Pointer auf das erste Feldelement, a+b = irgendwo aber nicht da wo es sein soll

for(uint8_t i=3; i>0; i--)c[i] = a[i]; //richtig!!!
for(uint8_t i=3; i>0; i--)c[i+3] = b[i];


Es gibt auch Funktionen wie StrCpy die dasslebe machen. (Siehe array.h)
Oder du könntest einfach in Feld a etwas Platz lassen und da b hineinschreiben

casa74
17.08.2005, 14:29
Vielen Dank erstmal für die Erklärungen,
ich denke das ist vom Prinzip her schon fast was ich gesucht habe.

@cavegn
habe vor daten eines GPS-Empfängers, die über den USART empfangen
werden sollen, in einen Array zu speichern.
Später sollen dieser dann in einen Bitrahmen eingefügt werden(AX.25)

Der Header eines solchen Rahmens ist immer gleich, daher die Idee
in einen anderen Array die festen Daten zu speichern.
Dann wollte ich diese beide Array zusammenfügen, daraus eine
CRC-Prüsumme berechnen, der dann zum Schluss angehangen wird.
Und dann soll das Ganze wieder über den USART an ein AFSK-Modem gesendet werden.
Ich denke, daß das durch zusammenführen der einzelnen Array möglich
sein sollte, oder!?

So war zumindest meine Überlegung !! :-k

Gruß!
casa74

Psiyou
17.08.2005, 15:46
Hallo,

dann wuerd ich das mit dem zusammenkopieren lassen und einfach die beiden Arrays nacheinander senden und die Pruefsumme hinterher ;)
Sparst Du Code und Speicherplatz :)

cavegn
17.08.2005, 15:48
hi

jo, das ist schon möglich.

bekommst du vom gps immer gleichviele daten?

wenn ja, würde ich das etwa so machen:



#define HEADER_SIZE xBytes
#define GPS_DATA_SIZE yBytes
#define CRC_SIZE zBytes

unsigned char frame[HEADER_SIZE + GPS_DATA_SIZE + CRC_SIZE];


=> du baust dir ein array, welches so gross ist, dass Header, GPS-Daten sowie CRC darin platz haben.

während dem initialisieren kopierst du dir die immer gleichen header-daten rein



unsigned char i;
for(i=0;i<HEADER_SIZE; i++){
frame[i] = header_data[i];
}


die gps-daten kannst du jetzt auch gerade reinkopieren:



unsigned char i;
for(i=HEADER_SIZE;i<GPS_DATA_SIZE + HEADER_SIZE; i++){
frame[i] = get_gps_byte()
}


und am schluss nach analog die checksumme ...


cu

chris

casa74
18.08.2005, 10:33
Ich denke so werde ich es mal versuchen, vielen Dank für den Vorschlag !
Der GPS-String ist immer gleichgroß , dürfte deswegen kein Problem
sein !
Muss jetzt nur mal schauen wie ich das so von der Programmstruktur in
eine Main unterkriege !
weiss halt im Moment noch nicht, ob ich das so der Reihe nach innerhalb
des Main-Programms runterschreiben kann, also z.B
1. Usart initialisieren
2. Über USART Empfangen
3. In Array speichern
4. zusammenfügen
5. CRC Bilden
5. Senden über USART

u.s.w !

Muss mal schauen, werde mal versuchen und mich wieder melden !

Gruß !

casa74

casa74
18.08.2005, 15:20
Ok habe hier mal versucht, mit den Erkenntnissen aus den letzten Beiträgen,ein Programm zu basteln!

Bin mir absolut nicht sicher ob das von der Struktur bzw. Stil so hinhaut !!
Vielleicht hat ja jemand lust da mal schnell drüber zu fuchsen.
Bin für jeden Hinweis dankbar !


MFG
Casa


/*************************************************
Empfangen der GPS-daten,
zusammenfügen von GPS-Daten in einen Bitrahmen und
Senden des Bitrahmens
**************************************************/



#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <usart_bibliothek.h>
#define gps_data_size 96 /* Wert 96 wird der Variablen Datenfeld zugewiesen */
#define header_data_size 30 /* Wert 30 wird der Variablen header_data_size zugewiesen*/



static int ifr; /* Definition eines Zählers für for in frame_data*/
static int ih; /* Definition eines Zählers für for in header_data*/
static int ig; /* Definition eines Zählers für for in gps_data*/

static unsigned char gps_data[gps_data_size]; /* USART Array für Dateneingänge */
static unsigned char pointer; /* USART pointer */

static unsigned char frame[header_size + gps_data_size + crc_size]; /* Datenrahmen komplett*/

static unsigned char header[header_size]={0x82,0xA4,0xA6,0x8E,0x60,0x60,0x9c,0x68,0xA8,0xB 0,0x92,
0x40,0x76,0xA4,0x8A,0x98,0x82,0xB2,0x40,0x60,0xAE, 0x92,
0x88,0x8A,0x64,0x40,0x65,0x03,0xF0};/*headerdaten*/





/*----------- Initialisieren des USART -----------------------------------------------*/



UBRRH = 0;
UBRRL = 191; /*Baudrate des USART wird bei 4MHZ auf 4800 Baud gesetzt*/

UCSRC = (1<<URSEL)|(3<<UCSZ0); /*Datenformat auf 1Byte gesetzt, kein Paritätbit, kein Stopbit*/

UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); /*Aktivieren der Empfangs
und Sendebereitschaft und der Interrupts*/







/*------Programmeinstieg------------------*/


void main(void)
{



while (!(UCSRA & (1<<RXC)); /* Warten bereit zum empfang*/

{
if (++pointer == gps_data_size) /* Zählvariable pointer wächst bis auf den*/
/*Wert von Datenfeld (100) an */
pointer = 0; /* Erreicht Pointer den Wert von */
/*Datenfeld, wird pointer wieder auf 0*/
/*zurückgesetzt */
gps_data[pointer] = UDR; /* Bei jeder Inkrementierung von pointer
wird der aktuellere Inhalt vom UDR
} in das entsprechende Datenfeld vom
Array gesetzt. */

}


/*---------Es folgt zuerst die Zuweisung der header_daten in das Frame Array ---------*/





for(i=0;i<HEADER_SIZE; i++) /* Anweisung die bis headersize
raufzählt*/

{
frame[i] = header_data[i]; /* Mit jedem schritt wird
Inhalt aus header-data in
frame geschoben*/
}





/*--- Daten aus gps_data werden im Anschluss an Header den
Array-Frame übergeben---*/



for(ig=HEADER_SIZE;ig<gps_data_size + header_size; ig++)

{
frame[i] = gps_data[i]
}





/* ----Datenausgabe aus dem ARRAY "Frame" an den
TX des USART-----*/




while (!(UCSRA & (1<<RXC));

{
UDR=0x07 /*senden des Anfangsflag*/

}




while (!(UCSRA & (1<<UDRE) ) );

{

for (ifr=0; ifr<header_size + gps_data_size + crc_size; ifr++)
/* wird hochgezählt, solange
ifr kleiner als die Länge
von komplettarray */
{

if (!frame[ifr]) /* wenn Inhalt des aprs == /0 */

break; /* wird Schleife beendet */

UDR=frame[ifr]; /* Innerhalb der
for- Bedingung wird einzeln
jeder Inhalt des Array seriell
über usart ausgesendet */
}
}


while (!(UCSRA & (1<<UDRE) ) );


{
UDR = 0x7E /*senden des Endflags*/
}
}



[/code]

cavegn
18.08.2005, 17:23
hi

funktioniert es denn?

was mir gerade aufgefallen ist - eigentlich ist es überflüssig, dass du frame und header seperat definerst.

static unsigned char frame[header_size + gps_data_size + crc_size]=
{0x82,0xA4,0xA6,0x8E,0x60,0x60,0x9c,0x68,0xA8,0xB0 ,0x92,
0x40,0x76,0xA4,0x8A,0x98,0x82,0xB2,0x40,0x60,0xAE, 0x92,
0x88,0x8A,0x64,0x40,0x65,0x03,0xF0};

würde reichen, glaube ich. dann kannst du auch die for-schlaufe, die das array mit den headerdaten füllt, sparen.

ansonsten:

die formatierung sieht bei mir nicht so schön aus, das liegt aber an meinem editor, glaube ich :-)

ahja, ein paar funktionen zur strukturierung würden das programm ein wenig lesbarer machen ;-)

cu

chris

casa74
18.08.2005, 18:11
Wenn ich deine Version der Framebildung richitg verstanden habe,
wird also der Frame direkt in voller Größe definiert und die ersten Plätze
einfach schon mit den konstanten Daten aufgefüllt?!?
werde es mal versuchen !

Habe im moment leider keine Möglichkeit das in der Praxis zu testen.
Kommt aber bald.
Wollte halt schonmal vorher wissen, ob zumindest von der Syntax alles stimmt
und vor allem die Sende und Empfangsanweisungen richitg in C von mir programmiert wurde.

Mit der Strukturierung hast du natürlich recht, werde es noch in einzelne Funktionsblöcke aufteilen.
Ich glaube das hiess Prototype-style, oder so ! muss erstmal sehen wie das funzt !
Habe es halt jetzt nur alles in eine Funktion gepackt, weil es vom Verständnis für mich "noch" einfacher ist.

Gruß und schönen Abend!

Casa74

Psiyou
18.08.2005, 19:45
Hi,

also da sind ein paar Fehler drinne... Denke mal nicht das Du versucht hast das zu Kompilieren.... Solltest Du in Zukunft tun, Fehler anschauen, selber überlegen und erst dann fragen (sonst lernst auch nichts, nur wer schon mal Stundenlang davor gessesn hat und verzweifekt ist kapiert auch was ;) ).
Erst mal hast Du unten in den for schleifen bei den Zuweisungen das ; vergessen. Dann die Initialisierung der UART kann nicht ausserhalb einer funktion erfolgen (dort können nur globale Variablen definiert werden, Funktionsprototypen, Preprozessoranweisungen etc). Mach am besten eine init() funktion (siehe Bsp).
Dann nimt man wenn möglich auch keine globalen Variablen sondern lokal. Vor allem wenn es nur eine funktion gibt ;)
Und was Du da in der ersten Schleife machts mit den Pointer gibt nicht wirklich sinn... Lass so was erst mal aussen vor und arbeite Dich in die Grundfunktionsweisen von C ein.
Ich poste hier mal ein Bsp wie ich das ungefähr lösen wurde als kleine Hilfe, jetzt Dein Prog durchzusprechen währe etwas zu langwierig...


#define gps_data_size 96 /* Wert 96 wird der Variablen Datenfeld zugewiesen */
#define header_data_size 30 /* Wert 30 wird der Variablen header_data_size zugewiesen*/
#define crc_size 1

void init(void); //Prototyp

void main(void)
{

int i=0; //schleifenzaehler
unsigned char data[header_data_size+gps_data_size+crc_size]={0x82,0xA4,0xA6,0x8E,0x60,
0x60,0x9c,0x68,0xA8,0xB0,0x92,0x40,0x76,0xA4,0x8A, 0x98,
0x82,0xB2,0x40,0x60,0xAE,0x92,0x88,0x8A,0x64,0x40, 0x65,
0x03,0xF0};/*headerdaten*/

init(); //UART initialisieren...

while(1) //unendlich schleife...
{
//empfangen der Daten
for(i=gps_data_size;i<gps_data_size + header_data_size; i++)
{
while (!(UCSRA & (1<<RXC)));/* Warten bereit zum empfang*/
data[i] = UDR;
}

//hier fehlt noch Berechnung der Pruefsumme...

UDR=0x07; /*senden des Anfangsflag*/

for (i=0; i<header_data_size + gps_data_size + crc_size; i++) //senden der Daten
{
while (!(UCSRA & (1<<UDRE) ) );
UDR = data[i];
}

while (!(UCSRA & (1<<UDRE)));

UDR = 0x7E; /*senden des Endflags*/
}//while(1)

}//main()



/*----------- Initialisieren des USART -----------------------------------------------*/

void init(void)
{
UBRRH = 0;
UBRRL = 191; /*Baudrate des USART wird bei 4MHZ auf 4800 Baud gesetzt*/

UCSRC = (1<<URSEL)|(3<<UCSZ0); /*Datenformat auf 1Byte gesetzt, kein Paritätbit, kein Stopbit*/

UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); /*Aktivieren der Empfangs
und Sendebereitschaft und der Interrupts*/
}//init()

Hab die Initanweisungen jetzt nicht überprüft da ich die Header auch nicht habe.
Wenn irgwnd was unklar ist noch mal fragen.