N76E003 C-Kurs      


Elektronik-Labor  Projekte  Nuvoton 





In letzter Zeit habe ich sehr viel Zeit verschwendet, weil ich nie richtig C gelernt habe. Jetzt habe ich angefangen, ein Buch zur Einführung zu lesen: C programmieren von Anfang an, von Helmut Erlenkötter, rororo, 25. Auflage Juli 2019. Das Buch gibt es schon seit 20 Jahren, und es ist immer weiter gepflegt worden. Das Lesen hat mir so viel Freude gemacht, dass ich unbedingt etwas testen wollte. Aber darf es auch mit dem N76E003 sein? Dann hätte die Sache einen doppelten Nutzen. Ich würde nicht nur C lernen, sondern gleich auch testen, wie kompatibel SDCC mit dem Standard-C ist.



Der erste Test war erfolgreich! Das Startbeispiel habe ich in JFE eingegeben. Das erste Beispiel aus dem Buch sieht so aus:

#include <stdio.h>

 /* bsp10001.c /02.c */
main()
{
    printf ("\nDies ist ein erstes C-Programm.\n");
    printf ("\nWie Sie sehen, kann 'printf' ");
    printf ("nicht nur Text drucken,\n");
    printf ("\sondern auch rechnen.\n\n");
    printf ("13 * 7 = %i \n", 13 * 7);
}


Zusätzlich muss natürlich noch das hardwarenahe Zeug wie getchar und purchar dabei sein. Und ich muss die Ports einrichten und am Ende noch while(1); einfügen, weil der Controller sonst kein Ende findet.


#include <N76E003.h>
#include <stdio.h>

void InitUART0_Timer1(long Baudrate);
char getchar(void);
void putchar(char);
void delay(void);
 
void main(void)
{
    P0M1=0;P0M2=0;P1M1=0;P1M1=0;
    InitUART0_Timer1(9600);
    /* bsp10001.c /02.c */
    printf ("\nDies ist ein erstes C-Programm.\n");
    printf ("\nWie Sie sehen, kann 'printf' ");
    printf ("nicht nur Text drucken,??/n");
    printf ("\sondern auch rechnen.??/n??/n");
    printf ("13 * 7 = %i \n", 13 * 7);
 
    while (1);
}

void InitUART0_Timer1(long Baudrate)    //T1M = 1, SMOD = 1
{
    SCON = 0x50;        //UART0 Mode1,REN=1,TI=1
    TMOD |= 0x20;       //Timer1 Mode1 
    PCON |= 128;        //SMOD = 1 UART0 Double Rate Enable
    CKCON |=16;         //set_T1M
    T3CON &= ~64;       //BRCK = 0  Serial port 0 baud rate clock source = Timer1
    TH1 = 256 - (1000000/Baudrate+1);               /*16 MHz */
    TR1 = 1;
    TI = 1;             //For printf
}


char getchar(void)
{
    char c;
    while (!RI);
    c = SBUF;
    RI = 0;
    return (c);
}

void putchar(char c)
{
    while (!TI); 
    TI = 0;
    SBUF = c;     
}


void delay(void)
{
    int i,j;
    for(i=0;i<0xff;i++)
         for(j=0;j<0xff;j++);
}



Das zweite Beispiel behandelt die sogenannten Trigraphs: Statt \n kann man auch schreiben: ??/n. Sowas habe ich noch nie gesehen. Es wurde wohl auch nur verwendet, wenn irgendwelche alten Rechner den Backslash nicht auf der Tatstatur hatten. Aber es wird hier immer noch unterstützt wie das Beispiel zeigt. SDCC kennt die Schreibweise und behandelt sie korrekt.

Bei diesen Escapesequenzen geht es um den Zeilenumbruch. Dazu wird ein Byte 10 gesendet. Andere meinen, es sollte eine 13 sein, wieder andere wollen beides. Bei verschiedenen Tests mit unterschiedlichen Terminalprogrammen schnitt der Serielle Monitor in der Arduino-IDE am besten ab. Das soll also jetzt immer mein Monitor sein.




Beim dritten Beispiel im Buch geht es darum, dass man mit nur einem printf gleich zwei ganze Zeilen mit Platzhaltern und Rechnungen ausgeben kann. Ich mache das jetzt immer so, dass ich das alte main stehenlasse und leicht umbenenne. Davor kommt dann die neue main. Damit spare ich Arbeit, weil der Dateiname gleich bleibt, keine neue Datei erzeugt werden muss und ich kein neues ihx in den Brenner eingeben muss. Die Faulheit siegt ....



void main(void)
{
    P0M1=0;P0M2=0;P1M1=0;P1M1=0;
    InitUART0_Timer1(9600);
    /* bsp10003.c */
    printf ("\nJetzt rechne ich: \n");
    printf ("3 + 2 = %i\n3 - 2 = %i\n", 3 + 2, 3 - 2);
    printf ("12 * 3 = %i\n", 12 * 3);
    printf ("12 / 3 = %i\n", 12 / 3);
    while (1);
}














Elektronik-Labor  Projekte   Nuvoton