Forum: Mikrocontroller und Digitale Elektronik Frage zu Programmierung mit STM8S


von Mirco (Gast)


Lesenswert?

Hallo,

auf dem Gebiet der Microcontrollerprogrammierung bin ich leider ein 
ziemlicher Neuling und deshalb entschuldige ich mich schon mal im 
vorraus für etwaige Unkenntnisse.

Mein Problem ist folgendes:

Im unten angegebenen Quellcode wird einfach nur die LED auf dem Board 
periodisch an und aus geschaltet. Mit der Schleife stellt man halt die 
Zeit ein. Soweit ziemlich simpel aber ich wollte halt auch klein 
anfangen.

Was ich nun nicht verstehe ist, dass der STM8S105C6 nach einem Reset auf 
2Mhz Clock gestellt ist. D.h. in einer Sekunde 2Millionen 
Arbeitsschritte.
Also müsste, wenn die Schleife bis 50000 zählt, die LED ziemlich schnell 
blinken und ungefähr bei i = 2*10^6 müsste Sie eine Sekunde an und aus 
sein. Evtl kleinere Abweichungen. Aber bei i = 50000 Blinkt sie bereits 
ungefähr jede Sekunde.

Was mache ich falsch bzw. wo ist mein Denkfehler?

Auch mit allen anderen Clocks die es evtl sein könnten kommt es nicht 
hin.
Und das der STM8 einen Clock von 50kHz hat habe ich auch nirgends 
gelesen.

#include "stm8s.h"

main(){
  GPIO_DeInit(GPIOD);
  GPIO_Init(GPIOD, GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_SLOW);

  while (1){

    unsigned int i = 0;

  for(i=0;i<50000;i++);

    GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
  }
}

von Mirco (Gast)


Lesenswert?

Push

von Bastler (Gast)


Lesenswert?

wie groß ist der Zahlenbereich von unsigned int ???

Ich behaubte mal 16384...

Mach mal zwei verschachtelte Schleifeb draus.
1x 1000 Durchläufe und 1x 50.

von noobuntu (Gast)


Lesenswert?

Hallo Mirco,

du hast da einen kleinen Denkfehler. Ich bin mir nicht mehr sicher wie 
es beim STM8S war, aber ich glaube das der einen internen Prescaler für 
den Clock hatte? Hast du das schon berücksichtig? Aber das ist 
eigentlich auch nur nebensächlich.

Ein C Programm wie du es hast läuft nicht ohne weiteres auf einem uC. 
Wenn du dein Programm compilierst, wandelt dein Compilier es in 
Assembler um (Maschiensprach in für Menschen lesbare Befehle). Dieser 
Assembler Code ist länger als dein C Programm, außerdem hat jeder 
Assemblerbefehl eine bestimmte Laufzeit. Aufgrund dieser Laufzeiten 
kannst du dann die zum Beispiel deine Blinkfrequenz ausrechnen.

Das von dem Complier erzeugte Assembler File müsste bei dir auch in 
deinem Workspace Ordner vorhanden sein. Es hat die Endung ".asm" einfach 
mal öffnen. Vllt versteht du dann auch weshalb ich lieber C als 
Assembler programmiere!

von Oliver J. (skriptkiddy)


Lesenswert?

Eine 16-bit Addition dauert bei einer Wortbreite von 8 Bit auf einem 
RISC-Prozessor wesentlich länger als einen Takt. Außerdem werden durch 
die for-Schleife bedingt noch Sprünge ausgeführt, welche ebenfalls 
Taktzyklen benötigen.

Gruß Skriptkiddy

von noobuntu (Gast)


Lesenswert?

Jop Skriptkiddy hat völlig recht. Hier hab ich mal den Assembler Code 
für ein Blinklicht für den STM8S. Nur das ich damals die Schleife bist 
60 000 Zählen lies.
1
   1                     ; C Compiler for STM8 (COSMIC Software)
2
   2                     ; Parser V4.8.32.1 - 30 Mar 2010
3
   3                     ; Generator V4.3.4 - 23 Mar 2010
4
  58                     .const:  section  .text
5
  59  0000               L6:
6
  60  0000 0000ea60        dc.l  60000
7
  61                     ; 4 main()
8
  61                     ; 5 {
9
  62                       scross  off
10
  63                       switch  .text
11
  64  0000               _main:
12
  66  0000 89              pushw  x
13
  67       00000002      OFST:  set  2
14
  70                     ; 6   GPIO_DeInit(GPIOD);
15
  72  0001 ae500f          ldw  x,#20495
16
  73  0004 cd0000          call  _GPIO_DeInit
17
  75                     ; 7   GPIO_Init(GPIOD, GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_SLOW);
18
  77  0007 4bc0            push  #192
19
  78  0009 4b01            push  #1
20
  79  000b ae500f          ldw  x,#20495
21
  80  000e cd0000          call  _GPIO_Init
22
  82  0011 85              popw  x
23
  83  0012               L72:
24
  84                     ; 13     for(i = 0; i < 60000; i++){
25
  86  0012 5f              clrw  x
26
  87  0013 1f01            ldw  (OFST-1,sp),x
27
  88  0015               L33:
28
  89                     ; 14       nop();
29
  92  0015 9d            nop
30
  94                     ; 13     for(i = 0; i < 60000; i++){
31
  97  0016 1e01            ldw  x,(OFST-1,sp)
32
  98  0018 1c0001          addw  x,#1
33
  99  001b 1f01            ldw  (OFST-1,sp),x
34
 102  001d 9c              rvf
35
 103  001e 1e01            ldw  x,(OFST-1,sp)
36
 104  0020 cd0000          call  c_uitolx
37
 106  0023 ae0000          ldw  x,#L6
38
 107  0026 cd0000          call  c_lcmp
39
 109  0029 2fea            jrslt  L33
40
 110                     ; 17     GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
41
 112  002b 4b01            push  #1
42
 113  002d ae500f          ldw  x,#20495
43
 114  0030 cd0000          call  _GPIO_WriteReverse
44
 116  0033 84              pop  a
45
 118  0034 20dc            jra  L72
46
 131                       xdef  _main
47
 132                       xref  _GPIO_WriteReverse
48
 133                       xref  _GPIO_Init
49
 134                       xref  _GPIO_DeInit
50
 153                       xref  c_lcmp
51
 154                       xref  c_uitolx
52
 155                       end

von Mirco (Gast)


Lesenswert?

Vielen Dank für die Antworten. Das hat mir sehr geholfen. Danke nun 
verstehe ich das besser.

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