Hallo liebe Gemeinde:
Ich habe mehrere int Variablen, diese wandel ich jeweils mit itoa() in
strings um. Dann möchte ich die einzelnen strings in einen großen String
verketten und diesen großen sende ich dann mit UART raus.
Manche Variablen können mal einen Wert von 5 bis 255 haben, nun muss
aber der String immer die gleiche Länge haben um ihn am Empfänger
auswärten zu können!
Bsp.:
1
inta=5;
2
chara_str[];
3
4
itoa(a,a_str,10);
Ergebnis: '5'
Ich hätte gerne: '005'
Vielen Dank im voraus !
René K. schrieb:> Manche Variablen können mal einen Wert von 5 bis 255 haben, nun muss> aber der String immer die gleiche Länge haben um ihn am Empfänger> auswärten zu können!
Alternative wäre, ein Trennzeichen zwischen die Variablen setzen.
Stichwort csv
Hallo wieder....
Ja stimmt dass mit dem Trennzeichen klingt auch gut!
Ich habe nun folgendes Problem:
Die Zusammensetzung und Umwandlung der verschiedenen Variablen in einen
String funktioniert auch das mit den "Nullen" auffüllen. Ich habe mit
einem anderen Compiler ein c-Programm geschrieben und mit printf zur
Kontrolle ausgegeben.
Wenn ich einen char teststring[]="Hallo Welt" über die UART ausgebe wird
es mir auch in HTerm angezeigt, also funktioniert die "uart_puts()"
Die Übertragung des von mir generierten String klappt aber leider nicht
und ich komme nicht drauf. Mittlerweile habe ich auch schon alles ins
main geschrieben.
1
#include<util/setbaud.h>
2
3
//Standardbibliotheken
4
#include<avr/io.h>
5
#include<util/delay.h>
6
#include<string.h>
7
#include<avr/interrupt.h>
8
9
10
11
//Eigene Bibliotheken
12
#include"defines.h"
13
#include"init.h"
14
#include"globals.h"
15
#include"pwm.h"
16
17
chartest_string[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
18
19
intmain(void)
20
{
21
//Globale setzen nach Neustart
22
bga_go=1;
23
bga_power_bit=255;
24
led_go=1;
25
frost=1;
26
bga_stufen=7;
27
bga_max_power_bit=255;
28
bga_timer=123;
29
pwm_rot=1023;
30
pwm_gruen=1023;
31
pwm_blau=1023;
32
33
34
portinit();
35
timer0_init();
36
serial_init();
37
38
39
40
sei();
41
42
43
while(1)
44
{
45
//Umwandlung und Speichern der Globalen in die Strings
Warum erst in verschiedene Strings per snprintf und dann diese wieder
zusammenkopieren? Warum nicht direkt raussenden?
1
charbuf[16];
2
3
snprintf(buf,1,"%01d",bga_go);
4
uart_puts(buf);
5
snprintf(buf,3,"%03d",bga_power_bit);
6
uart_puts(buf);
7
....
> send_to_PI[23]= bga_max_power_bit_str[2];
Hier fehlt die Terminierung:
send_to_PI[24] = '\0';
> ISR(TIMER0_OVF_vect)> {> cli();>> //uart_puts(send_to_PI); //Das noch nicht !> uart_puts(test_string); //Das Funktioniert perfekt !> sei();>> }
Das ist böse: Einen ganzen String in einer ISR rauskloppen macht man
nicht. Das dauert viel zu lang.
Man setzt in der ISR ein Flag. In der Hauptschleife wertet man dann
dieses Flag aus und sendet dann den String.
Vielen Dank,
ich wollte das in eins rausschicken damit ich den String am Empfänger
wieder in die Variablen aufdröseln und abspeichern kann.
Mit der ISR hatte ich auch schon bedenken, auch weil ich dort eine
Schleife drin habe, was ja auch gefährlich ist.
Ich weiß irgendwie selber nicht warum mir das so Schwierigkeiten
macht....klar ist schon etwas her das Ganze.
René K. schrieb:> Vielen Dank,>> ich wollte das in eins rausschicken damit ich den String am Empfänger> wieder in die Variablen aufdröseln und abspeichern kann.>> Mit der ISR hatte ich auch schon bedenken, auch weil ich dort eine> Schleife drin habe, was ja auch gefährlich ist.>> Ich weiß irgendwie selber nicht warum mir das so Schwierigkeiten> macht....klar ist schon etwas her das Ganze.
Wenn Dein Empfänger auf einem grösseren Betriebssystem basiert ist aber
auch nicht garantiert, dass Du den kompletten String als einen einzigen
"Block" erhälst. Da musst Du eh damit umgehen können, dass der String
unterteilt sein könnte, also alles was empfangen wird zusammensetzen,
bis das Endzeichen (\0) empfangen wird.
Nur mal so interessehalber...
dieses Array send_to_PI[...]
ist was? Klar, wenn es ein char-array sein soll fehlt die
Null-Terminierung
- aber wo sehe ich was das ist, wie gross es deklariert wurde?
ist das auch in globals.h ?
Das send_to_PI[] ist in den globals.h deklariert und ist ja der String
den ich in eins übertragen möchte.
also mit dev-c Compiler funktioniert snprintf() aber in AVR nicht!
ich habe das mal mit atoi() gemacht und es klappt. Den funktionierenden
Code poste ich gleich. Zuvor habe ich noch eine Frage:
nach jedem uart_puts() setzt er am Ende "\0" warum? liegt das irgendwie
am Zeiger ?
Wie bekomme ich das hin das dort ein "\n" anstatt dem "\0" angehängt
wird?
[c}
void uart_puts (const char *s)
{
do
{
uart_putc (*s);
}
while (*s++);
uart_putc('\n');
}
[/c]
Nop schrieb:> René K. schrieb:>>> nach jedem uart_puts() setzt er am Ende "\0" warum?>> Weil Du eine do-while-Schleife anstatt einer while-do-Schleife> verwendest.
Stimmt...
so geht es:
René K. schrieb:> so geht es:void uart_puts (const char *s)> {> while (*s)> {> uart_putc (*s);> *s++;> }> uart_putc('\n');>> }
Etwas aufgeräumter wäre:
1
{
2
while(*s)
3
{
4
uart_putc(*s);
5
s++;
6
}
7
uart_putc('\n');
8
9
}
Und falls uart_putc nicht irgendein verstecktes Macro ist, sondern eine
Funktion:
René K. schrieb:> uart_putc('\n');
Das würde ich gar nicht in uart_puts() schreiben, dann wird das ja nach
jeder Zahl gesandt. Da Du die zu sendenden Werte bereits auf feste
Längen ausrichtest, brauchst Du einen solchen Trenner nicht.
Wenn doch, eignet sich '\n' eher nicht als Feldttrenner, da würde ich
eher ein Leerzeichen ' ' oder ein Tab '\t' bevorzugen.
'\n' wird üblicherweise als Satztrenner benutzt, also am Ende Deines
Datensatzes, also da, wo Du ein 'E' für Ende-des-Datensatzes sendest.