Forum: Mikrocontroller und Digitale Elektronik Rechnen mit dem HC12?


von J. R. (cia_man)


Lesenswert?

Hallo!

Nochmal ne Frage:

Kann ich mit dem HC12 auch unter C geschriebenes rechnen lassen?

Also nach der Devise:

int x;

int y;

x = y/4;

Geht so was?? Nehme das ICC12-Programm!

THX!!!

von J. R. (cia_man)


Lesenswert?

Habe folgendes einfaches Programm geschrieben:
1
#include <stdio.h>
2
#include <math.h>
3
4
#include <mc912d128.h>
5
6
#define RDRF 0x20
7
#define TDRE 0x80  
8
9
10
void sci0_init(void){
11
    SC0BDH=0;  
12
    SC0BDL=26; 
13
    SC0CR1=0;
14
    SC0CR2=0x0C; //TE+RE enable
15
}
16
17
void sci0_putc(char data){
18
   while ((SC0SR1 & TDRE) == 0){};
19
   SC0DRL = data;
20
}
21
22
void sci0_puts(char* data){
23
   while (*data)
24
       sci0_putc(*data++);
25
}
26
27
28
void main(void){
29
int Ergebnis = 1;
30
31
32
sci0_init();
33
34
  sci0_puts("Das Ergebnis lautet: ");
35
  printf ("%d",Ergebnis);
36
37
38
while(1);
39
}

Stoppt jedoch mit einem Fehler! Verstehe das jetzt nicht ganz?? Weil 
unter C geht doch das ganze so????

THX!!!

von heinzhorst (Gast)


Lesenswert?

WO stoppt das Ganze? Warum benutzt du zur Ausgabe einmal sci0_puts() und 
einmal printf()? Ist printf() überhäuft verfügbar in deiner firmware? 
Nicht jede Funktion, die unter C mit einem Betriebssystem auf dem PC 
funktioniert, muss auch zwangsläufig in der selben Form unter einer 
Embedded-Umgebung vorhanden sein.

von J. R. (cia_man)


Lesenswert?

heinzhorst schrieb:
> WO stoppt das Ganze? Warum benutzt du zur Ausgabe einmal sci0_puts() und
> einmal printf()? Ist printf() überhäuft verfügbar in deiner firmware?
> Nicht jede Funktion, die unter C mit einem Betriebssystem auf dem PC
> funktioniert, muss auch zwangsläufig in der selben Form unter einer
> Embedded-Umgebung vorhanden sein.

Weil ich eine Zahl ausgeben will :)

Aber sehe gerade im Handbuch folgendes...




    * int printf(char *fmt, ..)

printf prints out formatted text according to the format specifiers in 
the fmt string. NOTE: printf is supplied in three versions, depending on 
your code size and feature requirements (the more features, the higher 
the code size):

                + Basic: only %c, %d, %x, %u, %p, and %s format 
specifiers without modifiers are accepted.
                + Long: the long modifiers %ld, %lu, %lx are supported, 
in addition to the width and precision fields.
                + Floating-point: all formats, including %f for 
floating-point, are supported.

The code size is significantly larger as you progress down the list. 
Select the version to use in the Compiler Options: Target dialog box.

The format specifiers are a subset of the standard formats:

%[flags]*[width][.precision][l]<conversion character>

The flags are:

# - alternate form. For the x or X conversion, a 0x or 0X is generated. 
For the floating-point conversions, a decimal point is generated even if 
the floating-point value is exactly an integer.

- (minus) - left-align the output

+ (plus) - add a '+' + sign character for positive integer output

' ' (space) - use space as the sign character for positive integer

0 - pad with zero instead of spaces

The width is either a decimal integer or *, denoting that the value is 
taken from the next argument. The width specifies the minimal number of 
characters that will be printed, left or right aligned if needed, and 
padded with either spaces or zeros, depending on the flag characters.

The precision is preceded by a '.' . and is either a decimal integer or 
*, denoting that the value is taken from the next argument. The 
precision specifies the minimal number of digits for an integer 
conversion, the maximum number of characters for the s-string 
conversion, and the number of digits after the decimal point for the 
floating-point conversions.

The conversion characters are as follows. If an l (letter el) appears 
before an integer conversion character, then the argument is taken as a 
long integer.

d - prints the next argument as a decimal integer

o - prints the next argument as an unsigned octal integer

x - prints the next argument as an unsigned hexadecimal integer

X - the same as %x except that upper case is used for A-F

u - prints the next argument as an unsigned decimal integer

p - prints the next argument as a void pointer. The value printed is the 
unsigned hexadecimal address, prefixed by 0x.

s - prints the next argument as a C null-terminated string

c - prints the next argument as an ASCII character

f - prints the next argument as a floating-point number in decimal 
notation (e.g., 31415.9)

e - prints the next argument as a floating-point number in scientific 
notation (e.g., 3.14159e4)

g - prints the next argument as a floating-point number in either 
decimal or scientific notation, whichever is more convenient.

Das mit dem char in der Klammer von printf macht mich nervös....

Müsste dann wahrscheinlich ein char sein dass man ausgibt und kein 
int????

Bloß wie gebe ich int aus????

THX!!!

von heinzhorst (Gast)


Lesenswert?

sorry, kenne jetzt den Compiler und die Librarys für den HC12 nicht, 
aber ich würde das einfach so lösen:
1
unsigned char loc_string[10];
2
3
//  numerischen Wert in string umwandeln
4
uitoa(Ergebnis, loc_string);  
5
6
//  Ergebnis ausgeben
7
sci0_puts("Das Ergebnis lautet: ");
8
sci0_puts(loc_string);

Wobei ich natürlich nicht weiß, ob und wenn ja, welche Header-Dateien 
man beim HC12 für uitoa() einbinden muss.

von J. R. (cia_man)


Lesenswert?

uitoa() finde ich net.... diese Fkt gibt es alle:





    The Standard Library header file <stdlib.h> defines the macros NULL 
and RAND_MAX and typedefs size_t and declares the following functions. 
Note that you must initialize the heap with the _NewHeap call before 
using any of the memory allocation routines (calloc, malloc, and 
realloc).

        * int abs(int i)

    returns the absolute value of i.

        * int atoi(char *s)

    converts the initial characters in s into an integer, or returns 0 
if an error occurs.

        * double atof(char *s)

    converts the initial characters in s into a double and returns it.

        * long atol(char *s)

    converts the initial characters in s into a long integer, or returns 
0 if an error occurs.

        * void *calloc(size_t nelem, size_t size)

    returns a memory chunk large enough to hold nelem number of objects, 
each of size size. The memory is initialized to zeros. It returns 0 if 
it cannot honor the request.

        * void exit(status)

    terminates the program. Under an embedded environment, typically it 
simply loops forever and its main use is to act as the return point for 
the user main function.

        * void free(void *ptr)

    frees a previously allocated heap memory.

        * char *ftoa(float f, int *status)

    converts a floating-point number to the its ASCII representation. It 
returns a static buffer of approximately 15 chars. If the input is out 
of range, *status is set to the constant, _FTOA_TOO_LARGE or 
_FTOA_TOO_SMALL, defined in stdlib.h, and 0 is returned. Otherwise, 
*status is set to 0 and the char buffer is returned. This version of the 
ftoa is fast but cannot handle values outside of the range listed. 
Please contact us if you need a (much) larger version that handles 
greater ranges.

    As with most other C functions with similar prototypes, *status 
means that you must pass the address of a variable to this function. Do 
not declare a pointer variable and pass it without initializing its 
pointer value.

        * void itoa(char *buf, int value, int base)

    converts a signed integer value to an ASCII string, using base as 
the radix. base can be an integer from 2 to 36.

        * long labs(long i)

    returns the absolute value of i.

        * void ltoa(char *buf, long value, int base)

    converts a long value to an ASCII string, using base as the radix.

        * void utoa(char *buf, unsigned value, int base)

    same as itoa except that the argument is taken as unsigned int.

        * void ultoa(char *buf, unsigned long value, int base)

    same as ltoa except that the argument is taken as unsigned long.

        * void *malloc(size_t size)

    allocates a memory chunk of size size from the heap. It returns 0 if 
it cannot honor the request.

        * void _NewHeap(void *start, void *end)

    initializes the heap for memory allocation routines. malloc and 
related routines manage memory in the heap region. for information on 
memory layout. A typical call uses the address of the symbol _bss_end+1 
as the "start" value. The symbol _bss_end defines the end of the data 
memory used by the compiler for global variables and strings.

    extern char _bss_end;
    _NewHeap(&_bss_end+1, &_bss_end + 201); // 200 bytes heap

    Be aware that for a microcontroller with a small amount of data 
memory, it is often not feasible or wise to use dynamic allocation due 
to its overhead and potential for memory fragmentation. Often a simple 
statically allocated array serves one's needs better.

        * int rand(void)

    returns a pseudo-random number between 0 and RAND_MAX.

        * void *realloc(void *ptr, size_t size)

    reallocates a previously allocated memory chunk with a new size.

        * void srand(unsigned seed)

    initializes the seed value for subsequent rand() calls.

        * long strtol(char *s, char **endptr, int base)

    converts the initial characters in s to a long integer according to 
the base. If base is 0, then strtol chooses the base depending on the 
initial characters (after the optional minus sign, if any) in s: 0x or 
0X indicates a hexadecimal integer, 0 indicates an octal integer, with a 
decimal integer assumed otherwise. If endptr is not NULL, then *endptr 
will be set to where the conversion ends in s.

        * unsigned long strtoul(char *s, char **endptr, int base)

    is similar to strtol except that the return type is unsigned long.


Kannst du mir da nochmal sagen welche?

THX!

von J. R. (cia_man)


Lesenswert?

Hab das Programm nun wie folgt:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <mc912d128.h>
5
6
#define RDRF 0x20
7
#define TDRE 0x80  
8
9
10
void sci0_init(void){
11
    SC0BDH=0;  
12
    SC0BDL=26; 
13
    SC0CR1=0;
14
    SC0CR2=0x0C; //TE+RE enable
15
}
16
17
void sci0_putc(char data){
18
   while ((SC0SR1 & TDRE) == 0){};
19
   SC0DRL = data;
20
}
21
22
void sci0_puts(char* data){
23
   while (*data)
24
       sci0_putc(*data++);
25
}
26
27
28
void main(void){
29
int Ergebnis = 100;
30
31
char loc_string[10];
32
33
//  numerischen Wert in string umwandeln
34
itoa(loc_string, Ergebnis, 5);  
35
36
37
38
sci0_init();
39
40
  sci0_puts("Das Ergebnis lautet: ");
41
  sci0_puts(loc_string);
42
  
43
  
44
45
while(1);
46
}

Jetzt bekomme ich zwar ne Ausgabe und es läuft auch jedoch ist die weng 
seltsam....

Hier ist sie:
Executing 4000...Das Ergebnis lautet: 400

??? Müsste doch 100 sein???

THX!!!

von J. R. (cia_man)


Lesenswert?

Ich habs!!!!

http://en.wikipedia.org/wiki/Radix schaut hier! Und nun das Programm 
richtig:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
#include <mc912d128.h>
5
6
#define RDRF 0x20
7
#define TDRE 0x80  
8
9
10
void sci0_init(void){
11
    SC0BDH=0;  
12
    SC0BDL=26; 
13
    SC0CR1=0;
14
    SC0CR2=0x0C; //TE+RE enable
15
}
16
17
void sci0_putc(char data){
18
   while ((SC0SR1 & TDRE) == 0){};
19
   SC0DRL = data;
20
}
21
22
void sci0_puts(char* data){
23
   while (*data)
24
       sci0_putc(*data++);
25
}
26
27
28
void main(void){
29
int Ergebnis = 10005;
30
31
char loc_string[10];
32
33
//  numerischen Wert in string umwandeln
34
itoa(loc_string, Ergebnis, 10);  
35
36
37
38
sci0_init();
39
40
  sci0_puts("Das Ergebnis lautet: ");
41
  sci0_puts(loc_string);
42
  
43
  
44
45
while(1);
46
}


Es lag an dem Radix-Element -> itoa(loc_string, Ergebnis, 10);
Muss für Dezimal -> 10 sein :)

THX!!!

Jetzt gehts freu!!!!

Super Forum :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.