Card12 mit EVAL-AD5781 verbinden

#2175835
Lesenswert?

Hier habe ich eine Funktion die festen Text ausgeben kann....
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8

9
  void sci0_init(void){
10
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
11
    SC0BDL=26; // MCLK/(16*BaudRate)
12
    SC0CR1=0;
13
    SC0CR2=0x0C; //TE+RE enable
14
}
15

16
void sci0_putc(char data){
17
   while ((SC0SR1 & TDRE) == 0){};
18
   SC0DRL = data;
19
}
20

21
void sci0_puts(char* data){
22
   while (*data)
23
       sci0_putc(*data++);
24
}
25

26
void main(void){
27
  sci0_init();
28
  sci0_puts("\n\nHallo ich bin ein String");
29
  sci0_putc(' ');sci0_putc('1');sci0_putc(' ');sci0_putc('2');sci0_putc(' ');sci0_putc('3');
30

31
  while(1);
32
}

Ich müsste aber auch noch eine haben, die eine Variable ausgeben kann... 
da muss ich aber erst suchen...

Du siehst aber schon hier, der Aufwand ist ziemlich groß an Code, der 
für ein einfaches printf nötig ist ;) bei meinem µC!

Gruß
#2175849
Lesenswert?

Hallo Jochen,

das ist gelinde gesagt M...!

Ich würde gerne sehen welche Werte bei unseren Berechnungen rauskommen.
Ich mach mir Sorgen das ich mit den Type Castings nen Bock geschossen 
habe ;-)

Irgend eine Idee wie wir da an eine Rückmeldung vom uC kommen können?
Ich vermute das wir auch keinen online debugger haben?

Grüße
Frank
#2175852
Lesenswert?

1
//Zeichen ausgeben
2

3
void sci0_putc(char data){
4
   while ((SC0SR1 & TDRE) == 0){};
5
   SC0DRL = data;
6
}
7

8
void sci0_puts(char* data){
9
   while (*data)
10
       sci0_putc(*data++);
11
}
12

13

14

15
//Eingabe
16
sci0_puts("\nBitte Kommando eingeben (muss Doppelpunkt enthalten):");
17
sci0_gets(command);
18

19

20
//Kommando finden hier anhand des ":"
21
while (commandsub != ':'){
22

23
commandsub = command[y];
24
y++;
25

26
}
27

28

29
//Kommando zur Kontrolle nochmals ausgeben
30
sci0_puts("\n\nGefundenes Kommando: ");
31

32

33
x=y-2;
34

35
while(x>=0){
36

37
commandid[z] = command[z];
38
x--;
39
z++;
40

41
}
42

43
sci0_puts(commandid); //Kommandoausgabe

Das würde schon ehr helfen oder? ;)
#2175935
Lesenswert?

Hallo Jochen,

so da werden wir wohl ein kleines Testprogramm stricken müssen um eine 
Textausgabe hin zu bekommen.
Mein Problem is jetzt das ich nicht sicher bin wie arrays definiert 
werden.
Das musst Du bitte mal nachschauen und auch ob es eine Bibliothek mit 
einem printf gibt. Das sollte eigentlich in deinen Handbüchern zum 
compiler drin stehen ;-)

Weil wenn, dann können wir so etwas bauen:
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5 / 0x03ffff;
10

11

12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18

19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23

24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28

29
void main(void){
30
  char mycharacterarray[128] /* This should be a 128 characters long array, how to do this properly? */
31

32
  sci0_init();
33
  mycharacterarray = printf("\n Here kommt die 1. Zahl: %f",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  mycharacterarray = printf("\n Here kommt die 2. Zahl: %f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37

38
  while(1);
39
}

DAS IST SO SICHER NICHT LAUFFÄHIG!!
Jetzt brauche ich deine Hilfe. Schau bitte das DU das array und den 
printf sauber bekommst. Evtl. gibt es auch einen Ersatz für den printf 
;-)

Grüße
Frank
Gast #2175983
Lesenswert?

J. R. schrieb:
> Kann es sein, dass hier der Wurm drinnen ist?
> DACValue = (int)(VoltValue / DACStepWidth); /* typeconversion added */

DACValue = (VoltValue / DACStepWidth);

Der Compiler macht die entsprechenden Konvertierungen.
[unsigned long] = ([Float]/[Float]) bzw
[  signed long] = ([Float]/[Float])

Sieh mal ins List-File, da wird das auf einen Blick klar.

Wenn du keine Umgebung hast, online zu debuggen,
dann schau wenigstens ab und zu ins list-File rein, was der
Compiler aus den C-Konstruktionen macht.

Du brauchst die 20-fache Zeit (gerade als Anfänger) wenn du keine
Möglichkeit hast, ein Programm zu debuggen, und am besten
mit Single-Stepping durchzutesten. Die Erfahrungen, die man dabei macht,
sind unbezahlbar.

Das mit
(int)..
ist hier total falsch. Das kopiert letztendlich einfach einen
(normalerweise 16Bit-) Teil aus dem Floatergebnis, konvertiert/erweitert
ihn dann erst (automatisch) auf den Typ von DACValue.
#2176021
Lesenswert?

@APW

nene so ganz falsch liegst Du nicht.
Das mit dem ungetestet tut mir ja auch leid, ich hab halt nix hier zum 
testen ;-)

@ Jochen
Da klauen wir mal die Idee vom APW und ändern die Zeile in:

DACValue = (VoltValue / DACStepWidth);

also das (int) raus. Ist wie ihr beide festgestellt habt aus mehreren 
Gründen Unsinn :-(

Ja ich werde doch langsam alt!


Was macht unser printf Testprogramm?

Grüße
Frank
Gast #2176043
Lesenswert?

Das Problem ist, dass ich jetzt einige Jahre nicht mehr in C
programmiert habe. Da ist einiges angerostet.

Vielleicht hole ich am WE mal wieder mein Zeug raus.
Bis auf den 18Bit DAC hab ich eigentlich alles hier.
#2176493
Lesenswert?

Hallo Jochen,

so nachdem ich mich durch diverse Meetings gequält habe gehen wir wieder 
auf was sinnvolles über ;-)

printf ist eigentlich ein standard C Befehl mit dem texte formatiert in 
ein character array geschrieben werden können.
Ich will jetzt nicht lügen, aber ich meine das printf in der Bibliothek 
"stdio" definiert ist.
Wenn Du da die Definition findest täte mir das schon helfen.

Grüße
Frank
#2177197
Lesenswert?

Hallo Jochen,

ich war dann gestern Abend ein bischen fleißig und habe mal nachgelesen 
was ich finden konnte. Dem zufolge sollte unser Testprogramm für die 
Ausgabe so aussehen:

Was hängt an SCI0 um den Text anzuzeigen?
Kannst DU das bitte mal testen ob wir so eine Anzeige bauen können?
Damit hätten wir dann wenigsten ein wenig debugging zur Verfügung.
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5 / 0x03ffff;
10

11

12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18

19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23

24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28

29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31

32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Here kommt die 1. Zahl: %f",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Here kommt die 2. Zahl: %f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37

38
  while(1);
39
}

Grüße
Frank
#2177314
Lesenswert?

COOOOOL!!!

Ok das mit dem Here ist meinem Job geschuldet.
Programmschnipsel basteln und gleichzeitig hier mit den Jungens englisch 
reden gibt dann so ein Misch Masch :-D

So die 2. Zahl schockiert mich.
Da hätte ich was anderes erwartet ;-)

Ich denke damit haben wir den Fehler schon eingefangen.
Ändere bitte mal in unserem Ausgabe Testprogramm:

const double DACStepWidth = 5 / 0x03ffff;

zu

const double DACStepWidth = 0.00001907;

und noch mal rennen lassen ;-)
#2177328
Lesenswert?

1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8
const double HalfRange = 2.5;
9
const double DACStepWidth = 0.00001907;
10

11

12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18

19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23

24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28

29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31

32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %lf",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37

38
  while(1);
39
}

Ich habe %f zu %lf noch ausgebessert ;) Aber an der Ausgabe ändert sich 
nichts :(

Leider :(
#2177331
Lesenswert?

Hallo Jochen,

das ist um klassen besser als das Ergebnis vorher!!

So ich grübel mal ne runde warum die Zahl zu kurz wird!
Auch wie wir das Problem umgehen können muss ich noch rausfinden ;-)

Du baust bitte die geänderte const Zeile in das DAC Programm und machst 
auf verdacht mal einen Test.

Dann schauen wir weiter

Grüße
Frank
Gast #2177349
Lesenswert?

Bei dem const müsste es event. so gemacht werden:
1
const double DACStepWidth = 5.0 / 0x03ffff;
sonst rechnet der Compiler auf der rechten Seite erst ganzzahlig,
wobei 0 rauskommt und wandelt dann erst in float/double um.
5.0 zwingt die rechte Seite als double zu rechnen


und die Ausgabe:
1
sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
oder so ähnlich
#2177368
Lesenswert?

Na das ist doch mal ein Wort ;-)

und APW war mal wieder schneller als ich mit der Lösung.
APW ich werde langsam ein wenig neidisch ;-)

Jochen, kannst Du bitte mal APWs Lösungsvorschlag für die const Zeile 
testen?

Grüße Frank
P.S. APW, Jochen, danke für die Geduld die ihr habt. Hab ja nu doch 
einige Böcke geschossen in den letzten Tagen ;-)
#2177375
Lesenswert?

Hey!
1
#include <stdio.h>
2
#include <mc912d128.h>
3

4

5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7

8

9

10
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
11
{
12
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
13
  
14
  SP0DR = myValue; /* Data goes to SPI data register*/
15
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
16
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
17
}
18

19
void VValueTo18BitDAC(double VoltValue)
20
{
21
  unsigned long DACValue = 0;
22
  unsigned char mylowbyte = 0x00;
23
  unsigned char mymidbyte = 0x00;
24
  unsigned char myhighbyte = 0x00;
25

26
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
27

28
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
29

30
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
31
  DACValue = DACValue >> 8; /* shift the next Byte into position */
32
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
33
  DACValue = DACValue >> 8; /* shift the next Byte into position */
34
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
35

36
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
37

38
  if (VoltValue <= HalfRange) /* Check for Halfrange */
39
  {
40
    myhighbyte |= 0x08;   /* to be able to set the MSB */
41
  }
42

43
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
44

45
  PORTS &= ~0x80;  /* /SS output low */
46
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
47
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
48
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
49
  PORTS |= 0x80;    /* /SS output high */
50
}
51

52
main()
53
{ 
54
  int i = 1;
55
  double myVValue = 0;  
56
  
57
  /* Init for SPI Interface */
58
  PORTS |= 0x80;
59
  DDRS = DDRS | 0xF0; /* outputs */
60
  SP0CR1 = 0x58; /* 0b01011000 */
61
  SP0CR2 = 0; /* Normal mode */
62
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
63

64
  /* Init to the DAC */
65
  PORTS &= ~0x80;  /* /SS output low */
66
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
67
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
68
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
69
  PORTS |= 0x80;    /* /SS output high */
70

71
  while (i>0) /* Endles Data sending for testing only */
72
  { 
73
    VValueTo18BitDAC(myVValue);
74
    myVValue += DACStepWidth;
75
    if (myVValue > 5)
76
      myVValue = 0;
77
  }
78
  
79
  return 0;    
80
}

Das Programm sieht nun folgendermaßen aus. Es läuft schon! Also Danke 
APW ;)

Und Frank was heißt da Danke für die Geduld... ich habe bisher Danke zu 
sagen ;)

Nun werde ich noch den Takt erhöhen :)
#2177404
Lesenswert?

Hallo Jochen,

kannst DU noch mal die von APW kommende Ausgabezeile testen?

sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: 
%2.10f",DACStepWidth);

nur das wir sicher gehen das wir keine "genauigkeit" verlieren ;-)

Tja und danach musste uns sagen was wir als nächstes machen. Weil dann 
rennt der DAC wie gewünscht ;-)

Grüße
Frank
#2177432
Lesenswert?

Hallo Jochen,

Du meinst weil der nicht schneller geworden ist?
Ich bin mir nicht sicher welche Takt der Prozessor selber hat, aber das 
sind jetzt einige Schritte wo er durchrechnen muss um durch zu kommen.
Kann es sein das der SPI mit 4Mhz nicht mehr das begrenzende Element 
ist?

Ist jetzt nur mal ein Verdacht.

Grüße
Frank
#2177433
Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> Du meinst weil der nicht schneller geworden ist?
> Ich bin mir nicht sicher welche Takt der Prozessor selber hat, aber das
> sind jetzt einige Schritte wo er durchrechnen muss um durch zu kommen.
> Kann es sein das der SPI mit 4Mhz nicht mehr das begrenzende Element
> ist?
>
> Ist jetzt nur mal ein Verdacht.
>
> Grüße
> Frank

Du meinst also, dass es der DAC ist? Weil der µC kann es ja net mit 8 
Mhz sein ;) oder?? :)
#2177438
Lesenswert?

1
Hier kommt die 1. Zahl: 2.5                                                  
2
Hier kommt die 2. Zahl: 0.000019

Programm dazu:
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5.0 / 0x03ffff;
10

11

12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18

19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23

24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28

29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31

32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %lf",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37

38
  while(1);
39
}

nicht, dass wir wieder aneinander vorbei reden ;) :)

Danke!

Scheint aber zu stimmen was APW da macht!
#2177452
Lesenswert?

Hallo Jochen,

8Mhz hat der HC12?
Dann haben wir seine Grenze erreicht.

Ich stelle mal ein par Behauptungen auf:
der HC12 braucht 2 Taktzyklen / Befehl (das erscheint mir optimistisch)
damit kann der HC12 effektiv nur 4 Mhz umsetzen.
Jetzt brauchen wir aber schon 3 Befehle um nur 1 byte von 3 an den DAC 
zu schicken.
Gibt (wieder optimistisch) 9 Befehle. Dann boste schon bei ca. 0,5 Mhz 
oder 500kHz.

Das bedeutet:
Ohne das wir auch nur einen Wert berechnet haben und ohne die reine 
Übertragungszeit des SPI braucht der Prozessor schon 0,5s für einen 
Zyklus.

Wenn Du jetzt noch das ganze grechne da drauf packst und die 
Übertragungszeiten....


Grüße
Frank
#2177476
Lesenswert?

Hallo Jochen,

ok dann die Erkläsrung noch mal anders und ein wenig genauer:

Wir führen (dieses mal habe ich nachgezählt) 22 C Zeilen aus um einen 
Wert zu schreiben.

Wenn wir behaupten das jede Zeile 2 Taktzyklen im HC12 sind (viel zu 
optimistisch) dann sind wir bei einer Bearbeitungszeit von 8Mhz / 44 
Zyklen = 0,18 Mhz
Das sind also ca. 0,000005 s pro Wert.

Wir verschicken pro Sägezahnzyklus 262143. Das ergibt dann schon 1,5 
sec.

Das deckt sich nicht mit deinem Bild, weil meine angenommen 2 Taktzyklen 
VIEEEEEEL zu optimistisch sind.

Mach ruhig mal den o.g. Versuch mit den Wertsprüngen zwischen 0 und 5 
Volt, damit wissen wir dann genau was bestenfalls möglich ist ;-)

Grüße
Frank
#2177496
Lesenswert?

1
Hier kommt die 1. Zahl: 2.5                                              Hier kommt die 2. Zahl: 0.000019

Dies gibt das Programm aus:
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5
#define RDRF 0x20   // Receive Data Register Full Bit
6
#define TDRE 0x80   // Transmit Data Register Empty Bit
7

8
const double HalfRange = 2.5;
9
const double DACStepWidth = 5.0 / 0x03ffff;
10

11

12
  void sci0_init(void){
13
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
14
    SC0BDL=26; // MCLK/(16*BaudRate)
15
    SC0CR1=0;
16
    SC0CR2=0x0C; //TE+RE enable
17
}
18

19
void sci0_putc(char data){
20
   while ((SC0SR1 & TDRE) == 0){};
21
   SC0DRL = data;
22
}
23

24
void sci0_puts(char* data){
25
   while (*data)
26
       sci0_putc(*data++);
27
}
28

29
void main(void){
30
  char mycharacterarray[128]; /* This is a 128 characters long array */
31

32
  sci0_init();
33
  sprintf(mycharacterarray,"\n Hier kommt die 1. Zahl: %lf",HalfRange);
34
  sci0_puts(mycharacterarray);
35
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
36
  sci0_puts(mycharacterarray);
37

38
  while(1);
39
}


Das Ergebnis ist aber zu oben identisch.... Bringt es also dann jetzt 
den von dir gewünschten Erfolg?

Gruß
#2177498
Lesenswert?

Hallo Jochen,

das bestätigt ein wenig meine Sorge.
Ich werde da noch mal lesen müssen ;-)

Generell haben wir aber jetzt ein funktionierendes Programm.
Die "Ungenauigkeit" werden ich noch mal genauer studieren, soll uns aber 
nicht davon abhalten das wir erst mal weiter basteln.

Kannst Du den Test zur maximal darstellbaren Frequenz durchführen?

Grüße
Frank
Gast #2177559
Lesenswert?

1) SPI läuft auf max Frequenz = F_Bus/2 = 4MHz
   3 Bytes pro Wertausgabe an den DAC zu übertragen:
   -> 24Bit * 250ns => 6us
   Wenn man den vollen Sägezahn mit 18Bits macht braucht man
   also für die SPI-Transfers alleine ca. 1,6s

   Sollte also momentan nicht der limitierende Faktor sein.

2) Das hier ist der limitierende Faktor:

   DACValue = (VoltValue / DACStepWidth);

   Pro Ausgabe eine double-Division sowie eine Double zu
   Longint Konvertierung. Wenn man auf Speed optimiert, muss man
   Fliesspunktrechnungen vermeiden. Ganz hardcoremässig event.
   sogar auf Assembler umsetzen.

3) Beim HC12 kann man nicht pauschal von 2 Clks/Maschinenbefehl 
ausgehen.
   Es gibt Befehle, die dauern 1 Clk, andere dauern so 12 Clks.
   Ich schätze den Durchschnitt so auf 3 Clks/Befehl
   Ausserdem wisst ihr ja nicht, was der C-Compiler aus euren
   Konstruktionen macht.

4) Kannst du mal sowas probieren:
1
...
2
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",DACStepWidth);
3
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.10f",10000*DACStepWidth);
4

5
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %2.12f",DACStepWidth);
6
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %12.12f",DACStepWidth);
7

8
  sprintf(mycharacterarray,"\n Hier kommt die 2. Zahl: %e",DACStepWidth);
9
...

Einfach mal ein bischen experimentieren. Vielleicht sinds 
Rundungseffekte
#2177614
Lesenswert?

APW du rettest meinen Tag!!

den %e habe ich gesucht und nicht gefunden!!
Ich gehe derzeit davon aus das wir einem Rundungsfehler zum Opfer 
fallen.

Da ich aber gerade an eben der Vermeidung der double Berechnungen 
arbeite (jep mir ist bewusst das die Dinger richtig Zeit kosten) werde 
ich auf dem Weg auch den Rundungsfehler los.

Ich stimme Dir übrigens zu was die 2 Zyklen betrifft. Habe derweil mal 
ein wenig im Netz gestöbert. Da sprach sogar jemand von 4 Zyklen im 
Mittel (bei Assembler code).
Ob ob Jochen aber wirklich viel schneller werden muss wird er uns noch 
verraten müssen ;-)

Dank Dir erst mal.

Grüße
Frank
#2177717
Lesenswert?

Hier die Messungen. Als Takt habe ich 4,0 Mhz am SPI.

Das Programm:
1
 while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 5;
5
    VValueTo18BitDAC(myVValue);
6
      myVValue = 0;
7
  }

Um Missverständnisse zu beseitigen ;)

:)
#2177930
Lesenswert?

Nächste Schritte sollen dann sein, mehrere DACs an einem µC zu 
betreiben. SPI-BUS soll dazu verwendet werden. Hardware habe ich aber 
noch nicht :)

Die Frage die ich deswegen habe ist, was passiert wenn der µC sein 
Signal vom DAC abzieht... das heißt hält der DAC dann seinen Wert? Soll 
nämlich so werden, damit mehrere DACs gleichzeitig laufen können.

Danke!
Gast #2178015
Lesenswert?

J. R. schrieb:
> Die Frage die ich deswegen habe ist, was passiert wenn der µC sein
> Signal vom DAC abzieht... das heißt hält der DAC dann seinen Wert?

Hä??

Ich hab keinerlei Durchblick, was du genau vorhast.
Wir brauchen ja nicht die DAC Wandlerrate von 1000/s auf 20000/s
hochtreiben, wenn 10/s ausreichen.

Also
-Was soll das Ganze eigentlich
-Wo kommen welche Daten in welchem Format / bzw. Protokoll
 wie schnell rein
-Was sind die Ausgabekanäle
-Was muss der uC wie verarbeiten
-Wie schnell soll das laufen
-Reichen 30 DAC Wandlungen/s oder sollens 10000/s sein
-Sollen die DACs gleichzeitig ihre Analogausgänge updaten ?
-Wenn du mehrere DACs bedienen musst, kannst du dir es überhaupt
 noch leisten, die ganze Ausgabe über zu warten ?
 (während z.B. serielle Daten reinkommen)

.....usw...

Langsam gehts event. mit Interruptprogrammierung los.
Das kann noch viel lustiger werden als bisher.

Wenn das auf die 10000 Beiträge zustrebt,
bekomme ich echte Probleme mit meinem Browser.
#2178692
Lesenswert?

Ich kann darüber auch noch keine genaueren Angaben machen... ist bei mir 
auch alles noch im Aufbau und muss ich erst einmal selber abklären.... 
;)

Aber nochmal zu dem was ich meinte... wenn ich jetzt über den BUS sagen 
wir 4 DACs ansteuere... dann kann ich ja immer nur eine mit den 
entsprechenden Infos versorgen... wegen dem BUS... und wie ist das dann 
mit den übrigen DACs die nicht SS mäßig gerade angesprochen werden? 
Schalten die sich dann einfach auf 0 V oder halten die ihren vorher 
übermittelten Wert? Das meine ich! Klar? :) ;)

Thx!
#2178702
Lesenswert?

Hallo Jochen,

heute wird die Session etwas holperig, weil wir hier auf der Baustelle 
versuchen einen 35KV Traffo scharf zu schalten.
Genauer der Kunde versucht das ;-)

Zu deiner Frage:
der DAC hält die Spannung am Ausgang.
Das kannst Du auch schon an unseren Sägezahnversuchen sehen. Weil wir ja 
immer nach dem Übertragen den SS wegnehmen ;-)

So ich hol mir schnell nen Kaffee und dann kommt die Antwort zu den 
Geschwindigkeiten ;-)

Grüße
Frank
#2178732
Lesenswert?

Hallo Jochen,

jetzt mal zu den Geschwindigkeiten oder "sample rates".

Es gibt da kein schnell oder langsam. Es gibt nur eine Anforderung die 
mit der gewählten Plattform erfüllt werden kann oder eben nicht.

Einfaches Beispiel:
wenn Du einen 2 Mhz Rechteck mit deiner gewählten Plattform darstellen 
willst, wirst du feststellen das geht nicht. egal wie Du es 
programmierst. Da ist dann der SPI Takt = 4Mhz zusammen mit dem 24 bit 
Kontrollwort eine Physikalische Grenze ;-)

Um also sagen zu können ob und wie deine Idee umsetzbar ist, müssen wir 
erst mal wissen welche Voraussetzungen wir erfüllen müssen.

Wir kennen aber schon ein par Werte die wir schaffen können.

1. Die reine Übertragung eines Wertes dauert 6us (dank an APW)
2. Derzeit verbraten wir durch Rechnereien ca. 220us pro Wert.

Diese 220us können (und müssen??) wir optimieren, nur dafür müssen wir 
wissen auf was wir optimieren. Da kommen dann wieder die schon mal 
gestellten Fragen zum tragen.

Ein einfaches Beispiel:
Ich glaube das wir locker 100us sparen können wenn der "Bediener" die 
Spannung nicht in V sonder in uV angibt.
Dadurch können wir die doubles weg optimieren und die kosten richtig 
Zeit!!

Wie APW schon sagte: Wenn Du nur eine Wertänderung alle 0,5s brauchst 
dann brauchen wir gar nix optimieren und sind (fast) fertig ;-)

Alles klar soweit?

Grüße
Frank
Gast #2178787
Lesenswert?

Solange man nicht weiß, wieviele Wandlungen/s er braucht, ist
optimieren überflüssige Arbeit. Vielleicht braucht er ja nur 50/s.

Ich denke Jochen hat 2 Möglichkeiten, mehrere DAC an den uC anzukoppeln:

Seriell:
So etwa, wie in Figure 47 und Figure 4 des AD5781 Datasheets.
Ist dort auch erklärt wiesowas funktioniert.
Nachteil ist, dass man jedesmal N*24Bit senden muss.
Wenn man weiß, dass man meistens alle DACs gleichzeitig mit neuen Werten
versorgen wird, ist das ok. Wenn man mal einen DAC in der Reihe nicht 
neu
mit Daten versorgen will, sendet man einfach ein NOP-Befehl
an der richtigen Position innerhalb der N*24Bit.

Parallel:
Da muss man nur die 24Bit des betreffenden DAC senden. Man braucht halt
individuelle Select-Leitungen. Alle DAC-SDI sind an einer Leitung und
alle DAC-SDO sind an einer Leitung. Aufpassen, dass nicht mehrere
Selects gleichzeitig aktiv sind.
#2178829
Lesenswert?

Hallo Jochen,

so da ich gerade mal eine kurze Verschnaufoasue habe kommt hier ein 
Programm wo ich mal versuche auf Leufzeit zu optimieren:
Ich habe die doubles durch unsigned long ersetzt. damit wir trotzdem 
noch ausreichend genau rechnen musste ich dafür die Basiswert mit 
1000000 mutliplizieren.

ACHTUNG der SPI Takt steht noch auf 1 MHz ;-)
(glaube ich)
1
#include <stdio.h>
2
#include <mc912d128.h>
3

4
const unsigned long HalfRange = 2500000;
5
const unsigned long DACStepWidth = 5000000 / 0x03ffff;
6

7
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
8
{
9
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
10
  
11
  SP0DR = myValue; /* Data goes to SPI data register*/
12
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
13
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
14
}
15

16
void VValueTo18BitDAC(unsigned long VoltValue)
17
{
18
  unsigned long DACValue = 0;
19
  unsigned char mylowbyte = 0x00;
20
  unsigned char mymidbyte = 0x00;
21
  unsigned char myhighbyte = 0x00;
22

23
  DACValue = VoltValue / DACStepWidth; 
24

25
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
26

27
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
28
  DACValue = DACValue >> 8; /* shift the next Byte into position */
29
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
30
  DACValue = DACValue >> 8; /* shift the next Byte into position */
31
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
32

33
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
34

35
  if (VoltValue <= HalfRange) /* Check for Halfrange */
36
  {
37
    myhighbyte |= 0x08;   /* to be able to set the MSB */
38
  }
39

40
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
41

42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
44
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
45
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
46
  PORTS |= 0x80;    /* /SS output high */
47
}
48

49
main()
50
{ 
51
  int i = 1;
52
  unsigned long myVValue = 0; /* changed to float as we do not need 64bit from double */  
53
  
54
  /* Init for SPI Interface */
55
  PORTS |= 0x80;
56
  DDRS = DDRS | 0xF0; /* outputs */
57
  SP0CR1 = 0x58; /* 0b01011000 */
58
  SP0CR2 = 0; /* Normal mode */
59
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
60

61
  /* Init to the DAC */
62
  PORTS &= ~0x80;  /* /SS output low */
63
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
64
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
65
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
66
  PORTS |= 0x80;    /* /SS output high */
67

68
  while (i>0) /* Endles Data sending for testing only */
69
  { 
70
    VValueTo18BitDAC(myVValue);
71
    myVValue += DACStepWidth;
72
    if (myVValue > 5000000)
73
      myVValue = 0;
74
  }
75
  
76
  return 0;    
77
}
#2178838
Lesenswert?

Hallo APW,

habe aus "Langeweile" trotzdem mal nen Versuch der Optimierung 
gestartet.
Habe mit Schrecken gelernt das double ja 8 byte lang ist.
Schau mal was Du von meiner Optimierungsidee denkst bitte.

Interrupts möchte ich wenn es eben geht vermeiden, weil damit 
überfordern wir Jochen fürchte ich. Dazu kommt das er ja offensichtlich 
nix ordentliches zum debuggen hat.

Grüße
Frank
#2178876
Lesenswert?

Zum Thema Sinus habe ich mir überlegt, dass man ja die Amplitude, die 
der Sinus haben soll, einfach so umsetzen könnte, dass man zu dem DC 
Wert die Werte die man vorher errechnet hat hinzu addiert. Bloß wie man 
jetzt die Frequenz umsetzt? Die Sache mit einer oder 2 Perioden könnte 
man ja mit einer while-Schleife lösen oder?

Danke.
#2178877
Lesenswert?

ok dann haben wir gelernt:

Es waren nicht unbedingt die Fließkommazahlen ;)
(hat der HC12 ne eingebaute FPU??)

das ist schön das hilft und wir können mit dem alten Programm weiter 
arbeiten.

Jochen dir muss klar sein: schneller wird es durch den Sinus nicht ;-)

Also Sinus aufmodulieren:

Was ist die maximale amplitude?
Was ist die maximal frequenz?

Grüße
Frank
#2178882
Lesenswert?

Hallo Jochen,

das mit den 2 while Schleifen ist so eine Sache:
Du hast ja schon gelernt, das wir das Zeitverhalten des uC nicht 100% 
vorhersagen können. Wenn Du jetzt die Frequenz des Sinus über eine 
verschachtelte Schleife (im schlimmsten fall mit Wait) erzeugst, dann 
gibt das alles nur keinen Sinus mehr.

Um die position im Sinus (und damit den zugehörigen Wert) zu bestimmen 
brauchen wir dann doch einen Timer. Alles andere ist halbherzig.

Grüße Frank
#2178937
Lesenswert?

Hallo Jochen,

ok war jetzt nicht ganz was ich erwartet habe aber macht nix.
Ich hab mir hier parallel auch mal ein wenig nen Kopf gemacht:

Ich würde gerne 360 Punkte pro Zyklus setzen (darfst raten warum)
Dann täte ich gerne erst mal nur den Sinus bauen. Das aufmodulieren 
machen wir dann im 2. Schritt ;-)

Das Problem das ich jetzt habe:
Ich habe keinen blassen Schimmer über die Timer im HC12.
Da musst Du mal die passenden Passagen im Handbuch suchen und wenn es 
geht ein oder 2 Beispiele.

Dann hoffe ich das es eine sin Funktion in deinen Bibliotheken gibt!?
Kannst Du das bitte rausfinden? Wenn es die nicht gibt, dann werden wir 
uns ein Tabelle mit den entsprechenden Werten basteln müssen.

Alles klar?
Dann los ans Werk ;-)

Grüße
Frank
#2178944
Lesenswert?

Floating-Point Math Functions

ICCV7 for CPU12 generates reentrant code including floating-point 
mathematics (at V6, ICC12 floating-point code is non-reentrant due to 
the use of static variables).

The following floating-point math routines are supported. You must 
#include <math.h> before using these functions.

    float asinf(float x)

returns the arcsine of x for x in radians.

    float acosf(float x)

returns the arccosine of x for x in radians.

    float atanf(float x)

returns the arctangent of x for x in radians.

    float atan2f(float y, float x)

returns the angle whose tangent is y/x, in the range [-pi, +pi] radians.

    float ceilf(float x)

returns the smallest integer not less than x.

    float cosf(float x) )

returns the cosine of x for x in radians.

    float coshf(float x)

returns the hyperbolic cosine of x for x in radians.

    float expf(float x)

returns e to the x power.

    float exp10f(float x)

returns 10 to the x power.

    float fabsf(float x)

returns the absolute value of x.

    float floorf(float x)

returns the largest integer not greater than x.

    float fmodf(float x, float y)

returns the remainder of x/y.

    float frexpf(float x, int *pexp)

returns a fraction f and stores a base-2 integer into *pexp that 
represents the value of the input x. The return value is in the interval 
of [1/2, 1) and x equals f * 2**(*pexp).

    float froundf(float x)

rounds x to the nearest integer.

    float ldexpf(float x, int exp)

returns x * 2**exp.

    float logf(float x)

returns the natural logarithm of x.

    float log10f(float x)

returns the base-10 logarithm of x.

    float modff(float x, float *pint)

returns a fraction f and stores an integer into *pint that represents x. 
f + (*pint) equal x. abs(f) is in the interval [0, 1) and both f and 
*pint have the same sign as x.

    float powf(float x, float y) )

returns x raised to the power y.

    float sqrtf(float x) )

returns the square root of x.

    float sinf(float x)

returns the sine of x for x in radians.

    float sinhf(float x)

returns the hyperbolic sine of x for x in radians.

    float tanf(float x) )

returns the tangent of x for x in radians.

    float tanhf(float x)

returns the hyperbolic tangent of x for x in radians.

Since, by default, float and double have the same size (32 bits), math.h 
also contains a set of macros that map the function names to be without 
the f suffix form. For example, pow is the same as powf, sin is the same 
as sinf, etc.




Daraus haben wir hier die Fkt:

    float sinf(float x)

returns the sine of x for x in radians.

Schonmal einwas ;)
#2178966
Lesenswert?

Der Timer heißt beim HC12 Enhanced Capture Timer... soweit ich weiß... 
nur ich habe auch damit so gut wie noch nie gearbeitet...

Außer dieses Blink-Programm:
1
//--------------------------------------------------------------
2
#include <stdio.h>
3
#include "mc912d128.h"
4
//--------------------------------------------------------------
5
void _HC12Setup(void) {
6
  COPCTL = 0x08;        // disable Watchdog
7
  }
8
//--------------------------------------------------------------
9
#pragma interrupt_handler isrOC2
10
void isrOC2(void) {
11
TFLG1 = 0x04; // clear OC2 Intr Flag
12
TC2 += 31250u; // 1 interrupt every 31250 timer ticks (0.5s)
13
PORTH ^= 0x80; // toggle LED
14
}
15
//--------------------------------------------------------------
16
void main(void) {
17
// install OC2 pseudo vector in RAM
18
// (if running with TwinPEEKs monitor)
19
*((unsigned char *)0x3FE2) = 0x06; // JMP opcode
20
*((void (**)(void))0x3FE3) = isrOC2;
21
// make PTH[7] an Output to drive the LED
22
DDRH |= 0x80;
23
// Timer Setup
24
TSCR = 0x80; // Timer enable
25
TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
26
TCTL2 = 0x00; // TC2 disconnected from Pin
27
TIOS |= 0x04; // TC2 is Output Compare
28
TMSK1 |= 0x04; // TC2 Interrupt enable
29
// enable Interrupts
30
asm("cli");
31
// loop endless (and let the interrupt work)
32
while(1) ;
33
}
34
//==============================================================

Wobei das uns jetzt glaube ich schon weiter bringt ;)

Sag mal wie weit dir das hilft!? Danke
#2178970
Lesenswert?

Hier ist noch eine Timer-Idee ;)
1
#include <stdio.h>
2

3
#include <mc912d128.h>
4

5

6
void delay1ms(void) {
7
  asm("ldy #2666"); //2666 in Y-Register laden
8
  asm("dbne y,.");  // Decrement, bis Y=0 ist / 
9
            //3cyc x 125ns x 2666 = 0,99975ms
10
}
11

12

13
void wait(int duration)
14
{
15
  while(duration--)
16
  delay1ms();
17
}
18

19

20

21
void main(void) {
22

23

24
  DDRH |= 0x3F;
25
 
26
 
27
 
28
   
29
  while(1){
30
  
31
  PORTH ^=0x3F;
32
  wait(1000);
33
  
34
  }
35
}


Vlt hilft das auch!


Sag mir bitte inwieweit dir das hilft.
#2179001
Lesenswert?

1
main()
2
{ 
3
  int i = 1;
4
  int GradZaehler = 1;
5
  double myVValue = 0;  
6
  
7
  /* Init for SPI Interface */
8
  PORTS |= 0x80;
9
  DDRS = DDRS | 0xF0; /* outputs */
10
  SP0CR1 = 0x58; /* 0b01011000 */
11
  SP0CR2 = 0; /* Normal mode */
12
  SP0BR = 0x02; /* 1,0 MHz SPI clock */
13

14
  /* Init to the DAC */
15
  PORTS &= ~0x80;  /* /SS output low */
16
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
17
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
18
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
19
  PORTS |= 0x80;    /* /SS output high */
20

21
  while (i>0) /* Endles Data sending for testing only */
22
  { 
23
    VValueTo18BitDAC(myVValue);
24
    myVValue = 2.5 + sin(GradZaehler++);
25
    if (GradZaehler > 360)
26
      GradZaehler = 1;
27
  }
28
  
29
  return 0;    
30
}
#2179115
Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8

9

10

11
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
12
{
13
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
14
  
15
  SP0DR = myValue; /* Data goes to SPI data register*/
16
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
17
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
18
}
19

20
void VValueTo18BitDAC(double VoltValue)
21
{
22
  unsigned long DACValue = 0;
23
  unsigned char mylowbyte = 0x00;
24
  unsigned char mymidbyte = 0x00;
25
  unsigned char myhighbyte = 0x00;
26

27
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
28

29
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
30

31
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
32
  DACValue = DACValue >> 8; /* shift the next Byte into position */
33
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
34
  DACValue = DACValue >> 8; /* shift the next Byte into position */
35
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
36

37
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
38

39
  if (VoltValue <= HalfRange) /* Check for Halfrange */
40
  {
41
    myhighbyte |= 0x08;   /* to be able to set the MSB */
42
  }
43

44
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
45

46
  PORTS &= ~0x80;  /* /SS output low */
47
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
48
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
49
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
50
  PORTS |= 0x80;    /* /SS output high */
51
}
52

53
main()
54
{ 
55
  int i = 1;
56
  double GradZaehler = 1;
57
  double myVValue = 0;  
58
  
59
  /* Init for SPI Interface */
60
  PORTS |= 0x80;
61
  DDRS = DDRS | 0xF0; /* outputs */
62
  SP0CR1 = 0x58; /* 0b01011000 */
63
  SP0CR2 = 0; /* Normal mode */
64
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
65

66
  /* Init to the DAC */
67
  PORTS &= ~0x80;  /* /SS output low */
68
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
69
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
70
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
71
  PORTS |= 0x80;    /* /SS output high */
72

73
  while (i>0) /* Endles Data sending for testing only */
74
  { 
75
    VValueTo18BitDAC(myVValue);
76
    myVValue = 2.5 + sin(GradZaehler++);
77
    if (GradZaehler > 360)
78
      GradZaehler = 1;
79
  }
80
  
81
  return 0;    
82
}


Programm. Und dazugehörige Aufnahme.
Angehängte Dateien:
Gast #2179120
Lesenswert?

Überleg dir mal, mit SPI können wir max 166000 Werte/s an einen (1) DAC
senden. Wenn das dein Ernst ist, kannst du schonmal den C-Compiler 
weglegen.
Das wird nur mit Integer+Hardcore Assembler was. Und selbst dann reicht 
es lange nicht.

Soll der Sinus auf den Sägezahn addiert oder multipliziert werden ?

Übrigens wegen
1
    VValueTo18BitDAC(myVValue);
2
    myVValue = 2.5 + sin(GradZaehler++);
3
    if (GradZaehler > 360)
4
      GradZaehler = 1;

Das muss Radiant sein, nicht Grad.

Und der HC12 hat keine FP-Unit, nur einige Befehle, die den Compiler 
dabei
unterstützen können. Wobei der ICC wahrscheinlich nicht den schnellsten
Code erzeugt.

Wenn die Speed-Anforderungen so hoch sind und es überhaupt HC12-artig
sein soll, dann würde ich nen HCS12, oder viel besser (und komplexer)
HCX12 nehmen, eine DAC event. parallel anbinden und wenn man auf C
besteht, den CodeWarrior-Compiler nehmen.

Diese Card12 gibts auch mit HCS12 und HCX12
Gast #2179176
Lesenswert?

J. R. schrieb:
> @APW: Welche Frequenz meinst du dann, dass wir überhaupt schaffen?

Kommt drauf an, wie kompromisslos du programmierst.
-kein Float, wenns eilig ist
-Werte vorberechnen
-Assembler benutzen
-nicht universeller (=langsamer/komplexer/mehr code) programmieren,
 als es die Aufgabenstellung (die wir nicht kennen) erfordert.
-Timings planen

Ohne Kenntnis der Aufgabenstellung kann man nichts genaues über
die Machbarkeit sagen.
#2179178
Lesenswert?

Hallo Jochen,

also nochmal weil es so schön war.
Ich bin echt zu lange raus :-(
Später haben wir es leichter weil da benutzen wir eine Tabelle ;-)

1
  while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 2.5 + sin(GradZaehler * 0.17453293);
5
    GradZaehler += 1;
6
    if (GradZaehler > 360)
7
      GradZaehler = 1;
8
  }

Grüße
Frank
#2179195
Lesenswert?

@APW

Ich fürchte das wir bald erkennen werden, das selbst mit optimalster 
Programmierung der HC12 seine Grenzen erreicht.

Dennoch würde ich gerne das ganze weiter treiben, nicht zuletzt damit 
Jochen die Möglichkeiten kennt und das auf einen anderen (schnelleren) 
Prozessor umsetzen kann.

Grüße
Frank
#2179231
Lesenswert?

Hallo Jochen,

ok der Peak beim 0 Durchlauf da will ich jetzt mal nicht pingelig sein. 
;-)
Den bekommen wir noch weg ;-)

Damit haben wir einen Sinus.
Gib mir bitte heute Abend um mal die Timernummer zu studieren.
Ich denke das ich aus dem Timer einen Sinus bauen kann und wir in der 
Main routine nur den Basis wert generieren.
Ich hab da so eine Idee ;-)

Grüße
Frank
#2179250
Lesenswert?

Frank Sander schrieb:
> Jochen das kann jetzt aber net sein.
> Zeig mal Code
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8

9

10

11
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
12
{
13
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
14
  
15
  SP0DR = myValue; /* Data goes to SPI data register*/
16
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
17
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
18
}
19

20
void VValueTo18BitDAC(double VoltValue)
21
{
22
  unsigned long DACValue = 0;
23
  unsigned char mylowbyte = 0x00;
24
  unsigned char mymidbyte = 0x00;
25
  unsigned char myhighbyte = 0x00;
26

27
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
28

29
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
30

31
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
32
  DACValue = DACValue >> 8; /* shift the next Byte into position */
33
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
34
  DACValue = DACValue >> 8; /* shift the next Byte into position */
35
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
36

37
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
38

39
  if (VoltValue <= HalfRange) /* Check for Halfrange */
40
  {
41
    myhighbyte |= 0x08;   /* to be able to set the MSB */
42
  }
43

44
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
45

46
  PORTS &= ~0x80;  /* /SS output low */
47
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
48
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
49
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
50
  PORTS |= 0x80;    /* /SS output high */
51
}
52

53
main()
54
{ 
55
  int i = 1;
56
  double GradZaehler = 1;
57
  double myVValue = 0;  
58
  
59
  /* Init for SPI Interface */
60
  PORTS |= 0x80;
61
  DDRS = DDRS | 0xF0; /* outputs */
62
  SP0CR1 = 0x58; /* 0b01011000 */
63
  SP0CR2 = 0; /* Normal mode */
64
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
65

66
  /* Init to the DAC */
67
  PORTS &= ~0x80;  /* /SS output low */
68
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
69
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
70
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
71
  PORTS |= 0x80;    /* /SS output high */
72

73
  while (i>0) /* Endles Data sending for testing only */
74
  { 
75
    VValueTo18BitDAC(myVValue);
76
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
77
     GradZaehler += 1;
78
    if (GradZaehler = 360)
79
      GradZaehler = 0;
80
  }
81

82

83
  
84
  return 0;    
85
}
#2179299
Lesenswert?

Frank Sander schrieb:
> Ach ja der ist herrlich ;-)
>
> if (GradZaehler == 360)
>
> dann funkts

Naja :) einen Peak hab ich aber noch ;) manchmal auch mehr... immer beim 
0-Durchgang... ???
1
while (i>0) /* Endles Data sending for testing only */
2
  { 
3
    VValueTo18BitDAC(myVValue);
4
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
5
     GradZaehler += 1;
6
    if (GradZaehler == 360)
7
    {
8
       GradZaehler = 0;
9
    }
10
  }
11

12

13
  
14
  return 0;    
15
}

Komisch? Klammern habe ich auch gesetzt!
Angehängte Dateien:
#2179782
Lesenswert?

Hallo Jochen,
Hallo APW,

ich hab da mal wieder was gebastelt ;-)
Ob das funktioniert? Keine Ahnung!
Ich habe net alles verstanden was ich aus dem Timer Beispiel geklaut 
habe.
Evtl. findet ja noch jemand was mehr Text zu dem Timer im HC12
Jochen ist mal wieder das Versuchstier :-D

Fehlermeldungen bitte zu mir.
Anregungen bitte auch zu mir.

Grüße
Frank
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7

8
double GradZaehler = 1;
9
double SinusOffset = 0.5;
10
double SinusAmplitude = 0.5;
11

12
void _HC12Setup(void) /* interesting but I did not see it is called some were */
13
{
14
  COPCTL = 0x08;        // disable Watchdog
15
}
16

17
#pragma interrupt_handler isrOC2 /* this most probably tells the Compiler about the interrupt hanlder */
18

19
void isrOC2(void) 
20
{
21
  unsigned long DACValue = 0;
22
  unsigned char mylowbyte = 0x00;
23
  unsigned char mymidbyte = 0x00;
24
  unsigned char myhighbyte = 0x00;
25
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
26
  double VoltValue = 0;
27

28
  TFLG1 = 0x04; // clear OC2 Intr Flag
29
  TC2 += 3125u; // 1 interrupt every 3125 timer ticks (0.05s) is kind of slow but good for the start ;-)
30

31
  VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) * SinusAmplitude);
32

33
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
34
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
35

36
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
37
  DACValue = DACValue >> 8; /* shift the next Byte into position */
38
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
39
  DACValue = DACValue >> 8; /* shift the next Byte into position */
40
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
41

42
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
43

44
  if (VoltValue <= HalfRange) /* Check for Halfrange */
45
  {
46
    myhighbyte |= 0x08;   /* to be able to set the MSB */
47
  }
48

49
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
50

51
  PORTS &= ~0x80;  /* /SS output low */
52
  SP0DR = myhighbyte; /* Data goes to SPI data register*/
53
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
54
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
55
  SP0DR = mymidbyte; /* Data goes to SPI data register*/
56
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
57
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
58
  SP0DR = mylowbyte; /* Data goes to SPI data register*/
59
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
60
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
61
  PORTS |= 0x80;    /* /SS output high */
62
}
63

64
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
65
{
66
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
67
  
68
  SP0DR = myValue; /* Data goes to SPI data register*/
69
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
70
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
71
}
72

73
main()
74
{ 
75
  int i = 1;
76
  /*********************************************************/
77
  /* Honestly the following I beblieve is not needed         */
78
  /*********************************************************/
79
  // install OC2 pseudo vector in RAM                        /***/
80
  // (if running with TwinPEEKs monitor)                    /***/
81
  *((unsigned char *)0x3FE2) = 0x06; // JMP opcode  /***/
82
  *((void (**)(void))0x3FE3) = isrOC2;                         /***/
83
  /********************************************************/
84
  /********************************************************/
85

86
  /*********************************************************/
87
  /*        Here starts what I beblieve is needed                */
88
  /*********************************************************/
89
  /* Init for SPI Interface */
90
  PORTS |= 0x80;
91
  DDRS = DDRS | 0xF0; /* outputs */
92
  SP0CR1 = 0x58; /* 0b01011000 */
93
  SP0CR2 = 0; /* Normal mode */
94
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
95

96
  /* Init to the DAC */
97
  PORTS &= ~0x80;  /* /SS output low */
98
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
99
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
100
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
101
  PORTS |= 0x80;    /* /SS output high */
102

103
  // Timer Setup
104
  TSCR = 0x80; // Timer enable
105
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
106
  TCTL2 = 0x00; // TC2 disconnected from Pin
107
  TIOS |= 0x04; // TC2 is Output Compare
108
  TMSK1 |= 0x04; // TC2 Interrupt enable
109
  // enable Interrupts
110
  asm("cli");
111

112
  while (i>0) 
113
  { 
114
    SinusOffset += DACStepWidth;
115
    if (SinusOffset >= (5.0 - SinusAmplitude))
116
      SinusOffset = SinusAmplitude;
117
  }  
118
  return 0;    
119
}
Gast #2179877
Lesenswert?

Hallo Frank

Eine Frage. Hast du schon mal uC programmiert ?
(Ich meine mehr als 100 Zeilen und mit Interrups und so).
Bitte nicht übelnehmen.
In deinem Quellcode hats ein paar Sachen drin, da könnte ich schlaflose
Nächte bekommen ;)
#2180202
Lesenswert?

Hallo APW,

jep habe ich. Ist aber 20 Jahre her. Von daher würde ich mich heute 
wieder Anfänger nennen.
Habe allerdings noch nie Interrupts in C eingebunden. Dafür habe ich 
früher immer Assembler pur gearbeitet.

Sag mal an was Dich beunruhigt. Ich will ja auch dazulernen.
Sorry wenn ich Dir die Nachtruhe raube. ;-)

Grüße
Frank
Gast #2180313
Lesenswert?

Ich hab gedacht ihr überlegt euch, was euch gleich um die Ohren fliegt,
und was euch erst später probleme macht.

Frage an Jochen:
Benutzt du TwinPeeks? Außerdem verwendest du ICC mit den Bibliotheken
in der Version 7?
#2180355
Lesenswert?

Hallo APW

sag an was Dich am meisten stört und ich werde versuchen mich zu 
bessern.
Leider steh ich das den HC12 betrifft etwas auf dem Schlauch, weil ich 
den vorher noch nicht genutzt habe. Unterlagen habe ich nur was ich 
bisher aus dem Netz gesammelt habe.

Da ich das ganze neben meinem normalen Job betreibe, bitte ich um 
Nachsicht bei den diversen Böcken die ich einbaue. Ich hoffe das Jochen 
trotzdem die Ideen die dahinter stecken versteht und umsetzen kann.

Grüße
Frank
#2180366
Lesenswert?

Frank Sander schrieb:
> Hallo APW
>
> sag an was Dich am meisten stört und ich werde versuchen mich zu
> bessern.
> Leider steh ich das den HC12 betrifft etwas auf dem Schlauch, weil ich
> den vorher noch nicht genutzt habe. Unterlagen habe ich nur was ich
> bisher aus dem Netz gesammelt habe.
>
> Da ich das ganze neben meinem normalen Job betreibe, bitte ich um
> Nachsicht bei den diversen Böcken die ich einbaue. Ich hoffe das Jochen
> trotzdem die Ideen die dahinter stecken versteht und umsetzen kann.
>
> Grüße
> Frank

Ich will es versuchen Meister ;)
#2180386
Lesenswert?

Hallo Jochen,

Ich persönlich bin ja eine faule Sau :-D, deswegen würde ich z.B. Excel 
dafür nutzen.
Geht einfacher und schneller ;)
Ausserdem kannst Du von da die Daten einfacher übernehmen.

Wenn Du dann noch sofort die 18 Bit werde generierst.... Das wäre mal ne 
so schlecht ;-)

Grüße
Frank
Gast #2180426
Lesenswert?

Da sind einige Fallen drin, kleine wie große. Und die sind nichtmal
HC12-spezifisch.

Mal der Reihe nach (kein Anspruch auf Vollständigkeit)
1) SinusOffset: Damit rechnest du in der Haupschleife UND in
   der Interruptfunktion (kurz ISR)
a)Was passiert, wenn die ISR Variablen verwendet, die vielleicht
  zum Interruptzeitpunkt gerade in der Haupschleife bearbeitet werden ?
  -> aus ISR rauswerfen oder in der Haupschleife z.B. mit kurzen (!!)
     Interruptsperren absichern
b)Wiedereintrittsfähigkeit (siehe auch Docu zum ICC6/7).
  Hier habt ihr reines Glück, dass Jochen den ICC V7 verwendet,
  bei ICC V6 (und auch bei einigen anderen Entwicklungsumgebungen)
  kann die gleichzeitige Verwendung von Float-Rechnungen
  in einer ISR und in der Haupschleife schiefgehen.
  In der ICC-Doku steht:

ICCV7 for CPU12 generates reentrant code including floating-point 
mathematics (at V6, ICC12 floating-point code is non-reentrant due to 
the use of static variables).

2) Halte die ISR so kurz wie möglich. Das mag jetzt noch funktionieren,
   aber irgendwann, wenn man nicht aufpasst ist auf einmal die Zeit
   für die ISR-Abarbeitung länger als als das ISR-Timerintervall.
1
  VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) * SinusAmplitude);
2
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
  Das sind folgende Double-Rechnungen
  1x sin(), 2x Multiplikationen,
  1x Addition, 1x Division, 1x Konvertierung Double->Long

  Das frisst Zeit, und sollte nich in einer ISR stehen.
  Ich würde alles vorberechnen und in der ISR nur noch die
  fertigen Bytes über SPI rausschieben.

3) // Timer Setup
   TSCR = 0x80; // Timer enable
   ...(Timer Register init)
   Ich würde generell empfehlen, den Timer erst zu enablen, wenn die
   anderen Timer-Register initialisiert worden sind. Das kann dazu
   führen, dass das erste Zeitintervall nicht stimmt.

Am WE Veruche ich mal, das Programm (mit einigen Anpassungen) auf meiner
HW (S12Compact) laufen zu lassen. Da ist ein 16Bt DAC drauf, der auch
über SPI angebunden ist.

Wegen dem Sinus: Der DT128 hat doch 8KB Ram.
Da kann man locker eine Sinustabelle im Init-Teil des
Programms vorberechnen, am besten gleich als Ganzzahl !?
#2180433
Lesenswert?

Frank Sander schrieb:
> Hallo Jochen,
>
> das sieht doch schon net schlecht aus.
> Da müssen die 0 udn max werte noch korrigiert werden ;-)
>
> Dann das ganze mit der Schrittweite multipliziert ergibt die Werte
> welche wir für den DAC brauchen.
>
> Grüße
> Frank

Hab nochmal das Diagramm durch ein ungerundetes ergänzt ;)

Aber ich verstehe jetzt nicht was du noch gerechent haben willst?

Kannst du mir mal die Fkt dazu hinschreiben?
Angehängte Dateien:
#2180446
Lesenswert?

APW schrieb:
> Da sind einige Fallen drin, kleine wie große. Und die sind nichtmal
> HC12-spezifisch.
>
> Mal der Reihe nach (kein Anspruch auf Vollständigkeit)
> 1) SinusOffset: Damit rechnest du in der Haupschleife UND in
>    der Interruptfunktion (kurz ISR)
> a)Was passiert, wenn die ISR Variablen verwendet, die vielleicht
>   zum Interruptzeitpunkt gerade in der Haupschleife bearbeitet werden ?
>   -> aus ISR rauswerfen oder in der Haupschleife z.B. mit kurzen (!!)
>      Interruptsperren absichern
> b)Wiedereintrittsfähigkeit (siehe auch Docu zum ICC6/7).
>   Hier habt ihr reines Glück, dass Jochen den ICC V7 verwendet,
>   bei ICC V6 (und auch bei einigen anderen Entwicklungsumgebungen)
>   kann die gleichzeitige Verwendung von Float-Rechnungen
>   in einer ISR und in der Haupschleife schiefgehen.
>   In der ICC-Doku steht:
>
> ICCV7 for CPU12 generates reentrant code including floating-point
> mathematics (at V6, ICC12 floating-point code is non-reentrant due to
> the use of static variables).
>
> 2) Halte die ISR so kurz wie möglich. Das mag jetzt noch funktionieren,
>    aber irgendwann, wenn man nicht aufpasst ist auf einmal die Zeit
>    für die ISR-Abarbeitung länger als als das ISR-Timerintervall.
>
1
>   VoltValue = SinusOffset + (sin(GradZaehler * 0.017453293) *
2
> SinusAmplitude);
3
>   DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
4
>
>   Das sind folgende Double-Rechnungen
>   1x sin(), 2x Multiplikationen,
>   1x Addition, 1x Division, 1x Konvertierung Double->Long
>
>   Das frisst Zeit, und sollte nich in einer ISR stehen.
>   Ich würde alles vorberechnen und in der ISR nur noch die
>   fertigen Bytes über SPI rausschieben.
>
> 3) // Timer Setup
>    TSCR = 0x80; // Timer enable
>    ...(Timer Register init)
>    Ich würde generell empfehlen, den Timer erst zu enablen, wenn die
>    anderen Timer-Register initialisiert worden sind. Das kann dazu
>    führen, dass das erste Zeitintervall nicht stimmt.
>
> Am WE Veruche ich mal, das Programm (mit einigen Anpassungen) auf meiner
> HW (S12Compact) laufen zu lassen. Da ist ein 16Bt DAC drauf, der auch
> über SPI angebunden ist.
>
> Wegen dem Sinus: Der DT128 hat doch 8KB Ram.
> Da kann man locker eine Sinustabelle im Init-Teil des
> Programms vorberechnen, am besten gleich als Ganzzahl !?


Zu 3. : Du würdest das also drehen...

// Timer Setup
  TSCR = 0x80; // Timer enable
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
  TCTL2 = 0x00; // TC2 disconnected from Pin
  TIOS |= 0x04; // TC2 is Output Compare
  TMSK1 |= 0x04; // TC2 Interrupt enable

TSCR = .... ganz nach unten?
#2180469
Lesenswert?

Hallo APW,

1a: Mist da habe ich wirklich net bedacht :-(
Ich war davon ausgegangen das ein reiner lesezugriff im Handler mir 
keine Probleme bereitet.

1b: Jep verstanden! So langsam kommt es mir wieder wieso ich früher 
immer gepredigt habe interrupt handler nur in assembler zu schreiben. Da 
wäre ich auf die Idee gar net gekommen floating point zu nutzen ;-)

2: rechst haste, deswegen habe ich die Zeit im Moment auch noch so lang 
gelassen.
Die Idee hinter dem Programm:
Sinus wird durch den timer gebaut. Damit bekomme ich den halbwegs 
stabil.
Mit dieser Version wollte ich die generelle Idee testen. Optimierung 
(sin() raus, floating point raus) sollten dann folgen.

3. Ups, den Teil habe ich einfach übernommen und net gesehen das da die 
Reihefolge vertauscht ist. Sorry, ich gelobe Besserung, habt Geduld mit 
einem alten Mann ;-)

Wäre klasse wenn Du am WE das ganze mal was mehr gerade rücken könntest.
Ich werde mit Jochen bis dahin mal versuchen alles was an floating point 
weg optimiert werden kann weg zu optimieren ;-)

Grüße
Frank
#2180547
Lesenswert?

1
// Timer Setup
2
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
3
  TCTL2 = 0x00; // TC2 disconnected from Pin
4
  TIOS |= 0x04; // TC2 is Output Compare
5
  TMSK1 |= 0x04; // TC2 Interrupt enable
6
  TSCR = 0x80; // Timer enable
7
  // enable Interrupts
8
  asm("cli");

so geht mal gar nix ;(
#2180559
Lesenswert?

1
// Timer Setup
2
  TMSK2 = 0x07; // Prescaler = 128 (1 timer tick every 16ìs)
3
  TCTL2 = 0x00; // TC2 disconnected from Pin
4
  TIOS |= 0x04; // TC2 is Output Compare
5
  TSCR = 0x80; // Timer enable
6
  TMSK1 |= 0x04; // TC2 Interrupt enable
7
  // enable Interrupts
8
  asm("cli");

so geht es ebenfalls net :(

Es geht nur wie Frank es vorgeschlagen hat ;)
#2180597
Lesenswert?

So Arbeit erledigt.... bitte lass mich sowas nicht wieder machen :)
War übelst nervig^^
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8

9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33

34

35

36
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
37
{
38
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
39
  
40
  SP0DR = myValue; /* Data goes to SPI data register*/
41
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
42
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
43
}
44

45
void VValueTo18BitDAC(double VoltValue)
46
{
47
  unsigned long DACValue = 0;
48
  unsigned char mylowbyte = 0x00;
49
  unsigned char mymidbyte = 0x00;
50
  unsigned char myhighbyte = 0x00;
51

52
  DACValue = (VoltValue / DACStepWidth); /* typeconversion added */
53

54
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
55

56
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
57
  DACValue = DACValue >> 8; /* shift the next Byte into position */
58
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
59
  DACValue = DACValue >> 8; /* shift the next Byte into position */
60
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
61

62
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
63

64
  if (VoltValue <= HalfRange) /* Check for Halfrange */
65
  {
66
    myhighbyte |= 0x08;   /* to be able to set the MSB */
67
  }
68

69
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
70

71
  PORTS &= ~0x80;  /* /SS output low */
72
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
73
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
74
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
75
  PORTS |= 0x80;    /* /SS output high */
76
}
77

78
main()
79
{ 
80
  int i = 1;
81
  double GradZaehler = 1;
82
  double myVValue = 0;  
83
  
84
  /* Init for SPI Interface */
85
  PORTS |= 0x80;
86
  DDRS = DDRS | 0xF0; /* outputs */
87
  SP0CR1 = 0x58; /* 0b01011000 */
88
  SP0CR2 = 0; /* Normal mode */
89
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
90

91
  /* Init to the DAC */
92
  PORTS &= ~0x80;  /* /SS output low */
93
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
94
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
95
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
96
  PORTS |= 0x80;    /* /SS output high */
97

98
  while (i>0) /* Endles Data sending for testing only */
99
  { 
100
    VValueTo18BitDAC(myVValue);
101
    myVValue = 2.5 + sin(GradZaehler * 0.017453293);
102
     GradZaehler += 1;
103
    if (GradZaehler == 360)
104
    {
105
       GradZaehler = 0;
106
    }
107
  }
108

109

110
  
111
  return 0;    
112
}

Das frisst er soweit ohne Fehler!

Danke!
#2180598
Lesenswert?

Hallo Jochen,

ich hab da mal was vorbereitet "Jean Pütz" ;-)
Da fehlt jetzt noch die SinusTabelle  von Dir und ein Testlauf.

Grüße
Frank
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5
const double HalfRange = 2.5;
6
const double DACStepWidth = 5.0 / 0x03ffff;
7

8
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
9
{
10
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
11
  
12
  SP0DR = myValue; /* Data goes to SPI data register*/
13
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
14
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
15
}
16

17
void VValueTo18BitDAC(unsigned long VoltValue)
18
{
19
  unsigned long DACValue = 0;
20
  unsigned char mylowbyte = 0x00;
21
  unsigned char mymidbyte = 0x00;
22
  unsigned char myhighbyte = 0x00;
23

24
  DACValue = VoltValue;
25
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
26

27
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
28
  DACValue = DACValue >> 8; /* shift the next Byte into position */
29
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
30
  DACValue = DACValue >> 8; /* shift the next Byte into position */
31
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
32

33
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
34

35
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
36
  {
37
    myhighbyte |= 0x08;   /* to be able to set the MSB */
38
  }
39

40
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
41

42
  PORTS &= ~0x80;  /* /SS output low */
43
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
44
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
45
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
46
  PORTS |= 0x80;    /* /SS output high */
47
}
48

49
main()
50
{ 
51
  int i = 0;
52

53
  int GradZaehler = 0;
54
  double myVValue = 0;  
55
  
56
  /* Init for SPI Interface */
57
  PORTS |= 0x80;
58
  DDRS = DDRS | 0xF0; /* outputs */
59
  SP0CR1 = 0x58; /* 0b01011000 */
60
  SP0CR2 = 0; /* Normal mode */
61
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
62

63
  /* Init to the DAC */
64
  PORTS &= ~0x80;  /* /SS output low */
65
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
66
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
67
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
68
  PORTS |= 0x80;    /* /SS output high */
69

70
  while (i>0) /* Endles Data sending for testing only */
71
  { 
72
    myVValue = (2.5 / DACStepWidth) + SinusTabelle[GradZaehler++];    
73
    VValueTo18BitDAC(myVValue);
74
    if (GradZaehler > 360)
75
      GradZaehler = 0;
76
  }
77
  return 0;    
78
}
#2180616
Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8

9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33

34

35

36
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
37
{
38
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
39
  
40
  SP0DR = myValue; /* Data goes to SPI data register*/
41
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
42
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
43
}
44

45
void VValueTo18BitDAC(double VoltValue)
46
{
47
  unsigned long DACValue = 0;
48
  unsigned char mylowbyte = 0x00;
49
  unsigned char mymidbyte = 0x00;
50
  unsigned char myhighbyte = 0x00;
51

52
  DACValue = VoltValue;
53

54
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
55

56
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
57
  DACValue = DACValue >> 8; /* shift the next Byte into position */
58
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
59
  DACValue = DACValue >> 8; /* shift the next Byte into position */
60
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
61

62
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
63

64
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
65
  {
66
    myhighbyte |= 0x08;   /* to be able to set the MSB */
67
  }
68

69
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
70

71
  PORTS &= ~0x80;  /* /SS output low */
72
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
73
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
74
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
75
  PORTS |= 0x80;    /* /SS output high */
76
}
77

78
main()
79
{ 
80
  int i = 0;
81
  int GradZaehler = 0;
82
  double myVValue = 0;  
83
  
84
  /* Init for SPI Interface */
85
  PORTS |= 0x80;
86
  DDRS = DDRS | 0xF0; /* outputs */
87
  SP0CR1 = 0x58; /* 0b01011000 */
88
  SP0CR2 = 0; /* Normal mode */
89
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
90

91
  /* Init to the DAC */
92
  PORTS &= ~0x80;  /* /SS output low */
93
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
94
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
95
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
96
  PORTS |= 0x80;    /* /SS output high */
97

98
  while (i>0) /* Endles Data sending for testing only */
99
  { 
100
    
101
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
102
    VValueTo18BitDAC(myVValue);
103
    if (GradZaehler > 360)
104
    {
105
       GradZaehler = 0;
106
    }
107
  }
108

109

110
  
111
  return 0;    
112
}


Läuft net wie es soll??? Habe mein Programm an den entsprechenden 
Stellen ausgebessert... keine Fehler gemeldet... kannst du nochmal 
drüber schauen, dass auch alles stimmt?

Oben Screen vom Oszi....
Angehängte Dateien:
#2180638
Lesenswert?

Hallo Jochen,

kannst Du bitte mal den Printf code in das Programm stricken und 
folgenden sprintf:
Tut mich mal interessieren wo ich mich da verrechne.
1
...
2
char mycharacterarray[128]; /* This is a 128 characters long array */
3
...
4

5
  while (i>0) /* Endles Data sending for testing only */
6
  { 
7
    
8
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
9

10
    sprintf(mycharacterarray,"myValue: %f  GradZaehler %i",myValue,GradZaehler);
11
    sci0_puts(mycharacterarray);   
12
    
13
    VValueTo18BitDAC(myVValue);
14
    if (GradZaehler > 360)
15
    {
16
       GradZaehler = 0;
17
    }
18
  }
#2180651
Lesenswert?

Schlechte Nachrichten:

Das Programm gibt gar nichts aus!
1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
#define RDRF 0x20   // Receive Data Register Full Bit
7
#define TDRE 0x80   // Transmit Data Register Empty Bit
8

9

10
const double HalfRange = 2.5;
11
const double DACStepWidth = 5.0 / 0x03ffff;
12

13
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
14
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
15
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
16
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
17
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
18
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
19
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
20
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
21
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
22
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
23
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
24
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
25
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
26
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
27
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
28
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
29
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
30
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
31
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
32
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
33
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
34
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
35
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
36
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
37
               
38
void sci0_init(void)
39
{
40
    SC0BDH=0;  // 19200 BR=26 (MCLK=8MHz)
41
    SC0BDL=26; // MCLK/(16*BaudRate)
42
    SC0CR1=0;
43
    SC0CR2=0x0C; //TE+RE enable
44
}
45

46
void sci0_putc(char data)
47
{
48
   while ((SC0SR1 & TDRE) == 0){};
49
   SC0DRL = data;
50
}
51

52
void sci0_puts(char* data)
53
{
54
   while (*data)
55
       sci0_putc(*data++);
56
}
57

58
               
59

60

61
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
62
{
63
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
64
  
65
  SP0DR = myValue; /* Data goes to SPI data register*/
66
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
67
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
68
}
69

70
void VValueTo18BitDAC(double VoltValue)
71
{
72
  unsigned long DACValue = 0;
73
  unsigned char mylowbyte = 0x00;
74
  unsigned char mymidbyte = 0x00;
75
  unsigned char myhighbyte = 0x00;
76

77
  DACValue = VoltValue;
78

79
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
80

81
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
82
  DACValue = DACValue >> 8; /* shift the next Byte into position */
83
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
84
  DACValue = DACValue >> 8; /* shift the next Byte into position */
85
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
86

87
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
88

89
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
90
  {
91
    myhighbyte |= 0x08;   /* to be able to set the MSB */
92
  }
93

94
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
95

96
  PORTS &= ~0x80;  /* /SS output low */
97
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
98
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
99
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
100
  PORTS |= 0x80;    /* /SS output high */
101
}
102

103
main()
104
{ 
105
  int i = 0;
106
  int GradZaehler = 0;
107
  double myVValue = 0;  
108
  
109
  char mycharacterarray[128]; /* This is a 128 characters long array */
110
  
111
  /* Init for SPI Interface */
112
  PORTS |= 0x80;
113
  DDRS = DDRS | 0xF0; /* outputs */
114
  SP0CR1 = 0x58; /* 0b01011000 */
115
  SP0CR2 = 0; /* Normal mode */
116
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
117

118
  /* Init to the DAC */
119
  PORTS &= ~0x80;  /* /SS output low */
120
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
121
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
122
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
123
  PORTS |= 0x80;    /* /SS output high */
124

125
  while (i>0) /* Endles Data sending for testing only */
126
  { 
127
    
128
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
129
   
130
    sprintf(mycharacterarray,"myVValue: %f  GradZaehler %i",myVValue,GradZaehler);
131
    sci0_puts(mycharacterarray);   
132
    
133
    VValueTo18BitDAC(myVValue);
134
    if (GradZaehler > 360)
135
    {
136
       GradZaehler = 0;
137
    }
138
  }
139

140

141
  
142
  return 0;    
143
}


:(
#2180674
Lesenswert?

Verbessert! ;)

00>g 4000
Executing 4000...myVValue: 131071.5  GradZaehler 1myVValue: 131986.5 
GradZaehler 2myVValue: 132901.5  GradZaehler 3myVValue: 13
3815.5  GradZaehler 4myVValue: 134728.5  GradZaehler 5myVValue: 135640.5 
GradZaehler 6myVValue: 136551.5  GradZaehler 7myVValue
: 137460.5  GradZaehler 8myVValue: 138368.5  GradZaehler 9myVValue: 
139273.5  GradZaehler 10myVValue: 140175.5  GradZaehler 11my
VValue: 141075.5  GradZaehler 12myVValue: 141972.5  GradZaehler 
13myVValue: 142865.5  GradZaehler 14myVValue: 143755.5  GradZaeh
ler 15myVValue: 144641.5  GradZaehler 16myVValue: 145522.5  GradZaehler 
17myVValue: 146400.5  GradZaehler 18myVValue: 147272.5
GradZaehler 19myVValue: 148140.5  GradZaehler 20myVValue: 149003.5 
GradZaehler 21myVValue: 149860.5  GradZaehler 22myVValue: 15
0711.5  GradZaehler 23myVValue: 151556.5  GradZaehler 24myVValue: 
152396.5  GradZaehler 25myVValue: 153228.5  GradZaehler 26myVV
alue: 154054.5  GradZaehler 27myVValue: 154873.5  GradZaehler 
28myVValue: 155685.5  GradZaehler 29myVValue: 156489.5  GradZaehle
r 30myVValue: 157285.5  GradZaehler 31myVValue: 158074.5  GradZaehler 
32myVValue: 158854.5  GradZaehler 33myVValue: 159626.5  Gr
adZaehler 34myVValue: 160389.5  GradZaehler 35myVValue: 161143.5 
GradZaehler 36myVValue: 161888.5  GradZaehler 37myVValue: 1626
23.5  GradZaehler 38myVValue: 163349.5  GradZaehler 39myVValue: 164065.5 
GradZaehler 40myVValue: 164771.5  GradZaehler 41myVVal
ue: 165467.5  GradZaehler 42myVValue: 166153.5  GradZaehler 43myVValue: 
166827.5  GradZaehler 44myVValue: 167491.5  GradZaehler
45myVValue: 168144.5  GradZaehler 46myVValue: 168785.5  GradZaehler 
47myVValue: 169415.5  GradZaehler 48myVValue: 170033.5  Grad
Zaehler 49myVValue: 170639.5  GradZaehler 50myVValue: 171234.5 
GradZaehler 51myVValue: 171816.5  GradZaehler 52myVValue: 172385
.5  GradZaehler 53myVValue: 172942.5  GradZaehler 54myVValue: 173487.5 
GradZaehler 55myVValue: 174018.5  GradZaehler 56myVValue
: 174536.5  GradZaehler 57myVValue: 175041.5  GradZaehler 58myVValue: 
175533.5  GradZaehler 59myVValue: 176011.5  GradZaehler 60
myVValue: 176475.5  GradZaehler 61myVValue: 176926.5  GradZaehler 
62myVValue: 177363.5  GradZaehler 63myVValue: 177785.5  GradZa
ehler 64myVValue: 178194.5  GradZaehler 65myVValue: 178587.5 
GradZaehler 66myVValue: 178967.5  GradZaehler 67myVValue: 179332.5
  GradZaehler 68myVValue: 179682.5  GradZaehler 69myVValue: 180017.5 
GradZaehler 70myVValue: 180338.5  GradZaehler 71myVValue:
180643.5  GradZaehler 72myVValue: 180934.5  GradZaehler 73myVValue: 
181209.5  GradZaehler 74myVValue: 181469.5  GradZaehler 75my
VValue: 181713.5  GradZaehler 76myVValue: 181942.5  GradZaehler 
77myVValue: 182156.5  GradZaehler 78myVValue: 182354.5  GradZaeh
ler 79myVValue: 182536.5  GradZaehler 80myVValue: 182703.5  GradZaehler 
81myVValue: 182854.5  GradZaehler 82myVValue: 182989.5
GradZaehler 83myVValue: 183109.5  GradZaehler 84myVValue: 183212.5 
GradZaehler 85myVValue: 183300.5  GradZaehler 86myVValue: 18
3372.5  GradZaehler 87myVValue: 183428.5  GradZaehler 88myVValue: 
183468.5  GradZaehler 89myVValue: 183492.5  GradZaehler 90myVV
alue: 183500.5  GradZaehler 91myVValue: 183492.5  GradZaehler 
92myVValue: 183468.5  GradZaehler 93myVValue: 183428.5  GradZaehle
r 94myVValue: 183372.5  GradZaehler 95myVValue: 183300.5  GradZaehler 
96myVValue: 183212.5  GradZaehler 97myVValue: 183109.5  Gr
adZaehler 98myVValue: 182989.5  GradZaehler 99myVValue: 182854.5 
GradZaehler 100myVValue: 182703.5  GradZaehler 101myVValue: 18
2536.5  GradZaehler 102myVValue: 182354.5  GradZaehler 103myVValue: 
182156.5  GradZaehler 104myVValue: 181942.5  GradZaehler 105
myVValue: 181713.5  GradZaehler 106myVValue: 181469.5  GradZaehler 
107myVValue: 181209.5  GradZaehler 108myVValue: 180934.5  Gra
dZaehler 109myVValue: 180643.5  GradZaehler 110myVValue: 180338.5 
GradZaehler 111myVValue: 180017.5  GradZaehler 112myVValue: 1
79682.5  GradZaehler 113myVValue: 179332.5  GradZaehler 114myVValue: 
178967.5  GradZaehler 115myVValue: 178587.5  GradZaehler 11
6myVValue: 178194.5  GradZaehler 117myVValue: 177785.5  GradZaehler 
118myVValue: 177363.5  GradZaehler 119myVValue: 176926.5  Gr
adZaehler 120myVValue: 176475.5  GradZaehler 121myVValue: 176011.5 
GradZaehler 122myVValue: 175533.5  GradZaehler 123myVValue:
175041.5  GradZaehler 124myVValue: 174536.5  GradZaehler 125myVValue: 
174018.5  GradZaehler 126myVValue: 173487.5  GradZaehler 1
27myVValue: 172942.5  GradZaehler 128myVValue: 172385.5  GradZaehler 
129myVValue: 171816.5  GradZaehler 130myVValue: 171234.5  G
radZaehler 131myVValue: 170639.5  GradZaehler 132myVValue: 170033.5 
GradZaehler 133myVValue: 169415.5  GradZaehler 134myVValue:
 168785.5  GradZaehler 135myVValue: 168144.5  GradZaehler 136myVValue: 
167491.5  GradZaehler 137myVValue: 166827.5  GradZaehler
138myVValue: 166153.5  GradZaehler 139myVValue: 165467.5  GradZaehler 
140myVValue: 164771.5  GradZaehler 141myVValue: 164065.5
GradZaehler 142myVValue: 163349.5  GradZaehler 143myVValue: 162623.5 
GradZaehler 144myVValue: 161888.5  GradZaehler 145myVValue
: 161143.5  GradZaehler 146myVValue: 160389.5  GradZaehler 147myVValue: 
159626.5  GradZaehler 148myVValue: 158854.5  GradZaehler
 149myVValue: 158074.5  GradZaehler 150myVValue: 157285.5  GradZaehler 
151myVValue: 156489.5  GradZaehler 152myVValue: 155685.5
 GradZaehler 153myVValue: 154873.5  GradZaehler 154myVValue: 154054.5 
GradZaehler 155myVValue: 153228.5  GradZaehler 156myVValu
e: 152396.5  GradZaehler 157myVValue: 151556.5  GradZaehler 158myVValue: 
150711.5  GradZaehler 159myVValue: 149860.5  GradZaehle
r 160myVValue: 149003.5  GradZaehler 161myVValue: 148140.5  GradZaehler 
162myVValue: 147272.5  GradZaehler 163myVValue: 146400.5
  GradZaehler 164myVValue: 145522.5  GradZaehler 165myVValue: 144641.5 
GradZaehler 166myVValue: 143755.5  GradZaehler 167myVVal
ue: 142865.5  GradZaehler 168myVValue: 141972.5  GradZaehler 
169myVValue: 141075.5  GradZaehler 170myVValue: 140175.5  GradZaehl
er 171myVValue: 139273.5  GradZaehler 172myVValue: 138368.5  GradZaehler 
173myVValue: 137460.5  GradZaehler 174myVValue: 136551.
5  GradZaehler 175myVValue: 135640.5  GradZaehler 176myVValue: 134728.5 
GradZaehler 177myVValue: 133815.5  GradZaehler 178myVVa
lue: 132901.5  GradZaehler 179myVValue: 131986.5  GradZaehler 
180myVValue: 131071.5  GradZaehler 181myVValue: 130156.5  GradZaeh
ler 182myVValue: 129241.5  GradZaehler 183myVValue: 128327.5 
GradZaehler 184myVValue: 127414.5  GradZaehler 185myVValue: 126502
.5  GradZaehler 186myVValue: 125591.5  GradZaehler 187myVValue: 124682.5 
GradZaehler 188myVValue: 123774.5  GradZaehler 189myVV
alue: 122869.5  GradZaehler 190myVValue: 121967.5  GradZaehler 
191myVValue: 121067.5  GradZaehler 192myVValue: 120170.5  GradZae
hler 193myVValue: 119277.5  GradZaehler 194myVValue: 118387.5 
GradZaehler 195myVValue: 117501.5  GradZaehler 196myVValue: 11662
0.5  GradZaehler 197myVValue: 115742.5  GradZaehler 198myVValue: 
114870.5  GradZaehler 199myVValue: 114002.5  GradZaehler 200myV
Value: 113139.5  GradZaehler 201myVValue: 112282.5  GradZaehler 
202myVValue: 111431.5  GradZaehler 203myVValue: 110586.5  GradZa
ehler 204myVValue: 109746.5  GradZaehler 205myVValue: 108914.5 
GradZaehler 206myVValue: 108088.5  GradZaehler 207myVValue: 1072
69.5  GradZaehler 208myVValue: 106457.5  GradZaehler 209myVValue: 
105653.5  GradZaehler 210myVValue: 104857.5  GradZaehler 211my
VValue: 104068.5  GradZaehler 212myVValue: 103288.5  GradZaehler 
213myVValue: 102516.5  GradZaehler 214myVValue: 101753.5  GradZ
aehler 215myVValue: 100999.5  GradZaehler 216myVValue: 100254.5 
GradZaehler 217myVValue: 99519.5  GradZaehler 218myVValue: 9879
3.5  GradZaehler 219myVValue: 98077.5  GradZaehler 220myVValue: 97371.5 
GradZaehler 221myVValue: 96675.5  GradZaehler 222myVVal
ue: 95989.5  GradZaehler 223myVValue: 95315.5  GradZaehler 224myVValue: 
94651.5  GradZaehler 225myVValue: 93998.5  GradZaehler 2
26myVValue: 93357.5  GradZaehler 227myVValue: 92727.5  GradZaehler 
228myVValue: 92109.5  GradZaehler 229myVValue: 91503.5  GradZ
aehler 230myVValue: 90908.5  GradZaehler 231myVValue: 90326.5 
GradZaehler 232myVValue: 89757.5  GradZaehler 233myVValue: 89200.
5  GradZaehler 234myVValue: 88655.5  GradZaehler 235myVValue: 88124.5 
GradZaehler 236myVValue: 87606.5  GradZaehler 237myVValue
: 87101.5  GradZaehler 238myVValue: 86609.5  GradZaehler 239myVValue: 
86131.5  GradZaehler 240myVValue: 85667.5  GradZaehler 241
myVValue: 85216.5  GradZaehler 242myVValue: 84779.5  GradZaehler 
243myVValue: 84357.5  GradZaehler 244myVValue: 83948.5  GradZae
hler 245myVValue: 83555.5  GradZaehler 246myVValue: 83175.5  GradZaehler 
247myVValue: 82810.5  GradZaehler 248myVValue: 82460.5
 GradZaehler 249myVValue: 82125.5  GradZaehler 250myVValue: 81804.5 
GradZaehler 251myVValue: 81499.5  GradZaehler 2ÿ

So und oben auch der passende Screenshot ;) Juhuuu!!! Aber die Peaks :(

Oszi hat Bild leicht verschoben beim Hardcopy ;)
Angehängte Dateien:
#2180710
Lesenswert?

1
#include <stdio.h>
2
#include <mc912d128.h>
3
#include <math.h>
4

5

6
const double HalfRange = 2.5;
7
const double DACStepWidth = 5.0 / 0x03ffff;
8

9
const long SinusWerte[] = {0,915,1830,2744,3657,4569,5480,6389,7297,8202,9104,10004,10901,11794,12684,13570,14451,15329,
10
                           16201,17069,17932,18789,19640,20485,21325,22157,22983,23802,24614,25418,26214,27003,27783,
11
                           28555,29318,30072,30817,31552,32278,32994,33700,34396,35082,35756,36420,37073,37714,38344,38962,
12
                           39568,40163,40745,41314,41871,42416,42947,43465,43970,44462,44940,45404,45855,46292,46714,47123,
13
                           47516,47896,48261,48611,48946,49267,49572,49863,50138,50398,50642,50871,51085,51283,51465,51632,51783,
14
                           51918,52038,52141,52229,52301,52357,52397,52421,52429,52421,52397,52357,52301,52229,52141,52038,
15
                           51918,51783,51632,51465,51283,51085,50871,50642,50398,50138,49863,49572,49267,48946,48611,48261,
16
                           47896,47516,47123,46714,46292,45855,45404,44940,44462,43970,43465,42947,42416,41871,41314,40745,
17
                           40163,39568,38962,38344,37714,37073,36420,35756,35082,34396,33700,32994,32278,31552,30817,30072,
18
                           29318,28555,27783,27003,26214,25418,24614,23802,22983,22157,21325,20485,19640,18789,17932,17069,
19
                           16201,15329,14451,13570,12684,11794,10901,10004,9104,8202,7297,6389,5480,4569,3657,2744,1830,915,0,
20
                           -915,-1830,-2744,-3657,-4569,-5480,-6389,-7297,-8202,-9104,-10004,-10901,-11794,-12684,-13570,-14451,
21
                           -15329,-16201,-17069,-17932,-18789,-19640,-20485,-21325,-22157,-22983,-23802,-24614,-25418,-26214,
22
                           -27003,-27783,-28555,-29318,-30072,-30817,-31552,-32278,-32994,-33700,-34396,-35082,-35756,-36420,
23
                           -37073,-37714,-38344,-38962,-39568,-40163,-40745,-41314,-41871,-42416,-42947,-43465,-43970,-44462,
24
                           -44940,-45404,-45855,-46292,-46714,-47123,-47516,-47896,-48261,-48611,-48946,-49267,-49572,-49863,
25
                           -50138,-50398,-50642,-50871,-51085,-51283,-51465,-51632,-51783,-51918,-52038,-52141,-52229,-52301,
26
                           -52357,-52397,-52421,-52429,-52421,-52397,-52357,-52301,-52229,-52141,-52038,-51918,-51783,-51632, 
27
               -51465,-51283,-51085,-50871,-50642,-50398,-50138,-49863,-49572,-49267,-48946,-48611,-48261,-47896,
28
                           -47516,-47123,-46714,-46292,-45855,-45404,-44940,-44462,-43970,-43465,-42947,-42416,-41871,-41314,
29
                           -40745,-40163,-39568,-38962,-38344,-37714,-37073,-36420,-35756,-35082,-34396,-33700,-32994,-32278,
30
                           -31552,-30817,-30072,-29318,-28555,-27783,-27003,-26214,-25418,-24614,-23802,-22983,-22157,-21325,
31
                           -20485,-19640,-18789,-17932,-17069,-16201,-15329,-14451,-13570,-12684,-11794,-10901,-10004,-9104,-8202,
32
                           -7297,-6389,-5480,-4569,-3657,-2744,-1830,-915,-0};
33
               
34
         
35

36

37
void mySPITrans(unsigned char myValue) /*Transmit Byte via SPI*/
38
{
39
  unsigned char mydelete; /* was zum Datenauslesen und verwerfen */
40
  
41
  SP0DR = myValue; /* Data goes to SPI data register*/
42
  while ((SP0SR & 0x80) == 0); /* wait for transfer to finish */ 
43
  mydelete = SP0DR; /* Daten auslesen und verwerfen */
44
}
45

46
void VValueTo18BitDAC(double VoltValue)
47
{
48
  unsigned long DACValue = 0;
49
  unsigned char mylowbyte = 0x00;
50
  unsigned char mymidbyte = 0x00;
51
  unsigned char myhighbyte = 0x00;
52

53
  DACValue = VoltValue;
54

55
  DACValue = DACValue << 2;  /* shift 2 needed Position in 24Bit Value */
56

57
  mylowbyte = DACValue & 0xff; /* Low Byte preparation */
58
  DACValue = DACValue >> 8; /* shift the next Byte into position */
59
  mymidbyte = DACValue & 0xff; /* Mid Byte preparation */
60
  DACValue = DACValue >> 8; /* shift the next Byte into position */
61
  myhighbyte = DACValue & 0xff; /* High Byte preparation */
62

63
  myhighbyte &= 0x07; /* make sure left 5 bits are empty */
64

65
  if (VoltValue <= 0x1ffff) /* Check for Halfrange */
66
  {
67
    myhighbyte |= 0x08;   /* to be able to set the MSB */
68
  }
69

70
  myhighbyte |= 0x10;  /* The Data Register Address Bit */
71

72
  PORTS &= ~0x80;  /* /SS output low */
73
  mySPITrans(myhighbyte); /* Analog Value Byte1 MSB first        */
74
  mySPITrans(mymidbyte); /* Analog Value Byte2 24 bit total    */
75
  mySPITrans(mylowbyte); /* Analog Value Byte3 LSB last         */
76
  PORTS |= 0x80;    /* /SS output high */
77
}
78

79
main()
80
{ 
81
  int i = 1;
82
  int GradZaehler = 0;
83
  double myVValue = 0;  
84
  
85
  
86
  /* Init for SPI Interface */
87
  PORTS |= 0x80;
88
  DDRS = DDRS | 0xF0; /* outputs */
89
  SP0CR1 = 0x58; /* 0b01011000 */
90
  SP0CR2 = 0; /* Normal mode */
91
  SP0BR = 0x03; /* 0,5 MHz SPI clock */
92

93
  /* Init to the DAC */
94
  PORTS &= ~0x80;  /* /SS output low */
95
  mySPITrans(0x20); /* Init DAC Control Register Byte1 MSB first      */
96
  mySPITrans(0x00); /* Init DAC Control Register Byte2 24 bit total  */
97
  mySPITrans(0x02); /* Init DAC Control Register Byte3 LSB last       */
98
  PORTS |= 0x80;    /* /SS output high */
99

100
  while (i>0) /* Endles Data sending for testing only */
101
  { 
102
    
103
    myVValue = (2.5 / DACStepWidth) + SinusWerte[GradZaehler++];    
104
    
105
    VValueTo18BitDAC(myVValue);
106
    if (GradZaehler > 360)
107
    {
108
       GradZaehler = 0;
109
    }
110
  }
111

112

113
  
114
  return 0;    
115
}

Version ohne Printf!! ;) Screenshots oben!
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren