STM32F4Discovery debugging timer mit coocox ide

Gast #3506094
Lesenswert?

Hi,
ich benutze die coocox ide 1.7.5 um mit dem STM32F4Discovery board zu 
basteln,
jetzt bin ich an einem Punkt wo ich gerne feststellen möchte wie lange 
ein bestimmer codeabschnitt für die Ausführung braucht.
Ich habe das ganze jetzt einfach mit Timer1 als up counter mit prescaler
1 und period 1 gemacht damit sollte dieser doch mit dem 
Systemtakt(168MHz laufen), vor dem zu beobachtendem code den timer 
gestartet und nach dem code den counter wert geholt.
Dieser Wert ist aber immer 0.
Das kann nicht richtig sein denn dieser code sollte ausgeführt werden:
1
uint16_t pixelLine[640];
2
uint8_t screenBuffer[4800]; //(640*480) / (8*8)
3
uint16_t tileBuffer0[16384]; //(8*8) * 256
4
uint16_t line = 0;
5
uint16_t col = 0;
6
uint16_t screenBufferIndex;
7
uint8_t tileBuffer0LineOffset;
8
uint8_t tileBuffer0Col;
9
uint16_t tileBuffer0Index;
10

11
TIM_Cmd(TIM1, ENABLE);
12

13
for (line = 0; line < 480; line++)
14
{
15
    for (col = 0; col < 640; col++)
16
    {
17
  screenBufferIndex = (line / 8) * 80 + (col /8);
18
  tileBuffer0LineOffset = line % 8;
19
  tileBuffer0Col = col % 8;
20
  tileBuffer0Index = screenBuffer[screenBufferIndex] * 64 + (tileBuffer0LineOffset * 8) + tileBuffer0Col;
21
  pixelLine[col] = tileBuffer0[tileBuffer0Index];
22
    }
23
}
24

25
int timerValue = TIM_GetCounter(TIM1);

der sollte doch schon ein paar systemtakte dauern.
Als ich Timer2 ausprobiert habe, habe ich ihn auch mal auf 1 Sekunde
eingestellt (prescaler = 42000-1; period = 2000-1;) da war timerValue
dann 303... alles sehr komisch. Bei prescaler = 1 und period = 1 war der 
Wert dann wieder 0.
Die timer funktionieren wohl (LED mit timer blinken lassen etc. 
funktioniert)

Ich  habe debug auf RAM gestellt damit nicht immer der flash geschrieben 
werden muss.

btw. habe ich die Frage auch schon unter der Rubrik PC Hard- & Software 
gestellt, aber da gehört sie wohl nicht so wirklich rein.
Werden die for Schleifen evtl. vom compiler doch wegoptimiert obwohl 
Optimierung aus gestellt ist?
Gast #3506114
Lesenswert?

Im Wiki steht wie man Takte mit dem SysTick Timer zählt:
http://www.mikrocontroller.net/articles/STM32_f%C3%BCr_Einsteiger#Taktzeitberechnung_und_.C3.9Cberwachung

Zeig doch mal ein vollständiges Beispiel, d.h. ein kompletter 
kompilierbarer Code der das bemängelte Verhalten zeigt und so kurz wie 
möglich ist. Insbesondere dem Wichtigsten überhaupt, der 
Timer-Initialisierung!

Paul schrieb:
> Werden die for Schleifen evtl. vom compiler doch wegoptimiert obwohl
> Optimierung aus gestellt ist?
Nein, diese Art Schleife wird wohl nie wegoptimiert. Außerdem bewirkt 
die Optimierung kleine Wunder, daher sollte man die außer zu 
Debug-Zwecken schon auch verwenden...
Gast #3506122
Lesenswert?

Dr. Sommer schrieb:
> Im Wiki steht wie man Takte mit dem SysTick Timer zählt:

Werden aber eigentlich mit der Data Watchpoint and Trace Unit gezählt.
Zuvor standen auch die (richtigen) DWT register Adressen im wiki.

http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439d/BABJFFGJ.html
1
The DWT if present contains counters for:
2

3
•Clock cycles (CYCCNT).
4
•Folded instructions.
5
•Load Store Unit (LSU) Operations.
6
•Sleep Cycles.
7
•CPI, that is all instruction cycles except for the first cycle.
8
•Interrupt overhead.
Gast #3506133
Lesenswert?

code der main.c :
1
#include "stm32f4xx.h"
2
#include "stm32f4xx_gpio.h"
3
#include "stm32f4xx_rcc.h"
4
#include "stm32f4xx_tim.h"
5

6
uint16_t pixelLine[640];
7
uint8_t screenBuffer[4800]; //(640*480) / (8*8)
8
uint16_t tileBuffer0[16384]; //(8*8) * 256
9

10
void Delay(__IO uint32_t nCount)
11
{
12
  while(nCount--)
13
  {
14
  }
15
}
16

17
GPIO_InitTypeDef  GPIO_InitStruct;
18

19
TIM_TimeBaseInitTypeDef    TIM_InitStruct;
20

21
int main(void)
22
{
23
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
24
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12;
25
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
26
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
27
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
28
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
29
    GPIO_Init(GPIOD, &GPIO_InitStruct);
30

31
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
32
    TIM_InitStruct.TIM_Prescaler = 1;
33
    TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;     // Count-up timer mode
34
    TIM_InitStruct.TIM_Period = 1;
35
    TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;        // Divide clock by 1
36
    TIM_InitStruct.TIM_RepetitionCounter = 0;                // Set to 0, not used
37
    TIM_TimeBaseInit(TIM1, &TIM_InitStruct);
38

39
  uint16_t line = 0;
40
  uint16_t col = 0;
41
  uint16_t screenBufferIndex;
42
  uint8_t tileBuffer0LineOffset;
43
  uint8_t tileBuffer0Col;
44
  uint16_t tileBuffer0Index;
45

46
    GPIO_SetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
47
    Delay(0xFFFFF);
48
    GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
49

50
    /* TIM1 enable counter */
51
    TIM_Cmd(TIM1, ENABLE);
52

53
  for (line = 0; line < 480; line++)
54
  {
55
    for (col = 0; col < 640; col++)
56
    {
57
      screenBufferIndex = (line / 8) * 80 + (col /8);
58
      tileBuffer0LineOffset = line % 8;
59
      tileBuffer0Col = col % 8;
60
      tileBuffer0Index = screenBuffer[screenBufferIndex] * 64 + (tileBuffer0LineOffset * 8) + tileBuffer0Col;
61
      pixelLine[col] = tileBuffer0[tileBuffer0Index];
62
    }
63
  }
64
  
65
  int timerValue = TIM_GetCounter(TIM1);
66

67
    while(1)
68
    {
69

70
    } //End of while(1) loop
71
} //End of main loop

Die richtigen Werte für PLL usw. sind in den system files auch richtig 
gesetzt so das das board auch wirklich mit 168 MHz läuft.
#3506158
Lesenswert?

Moin Paul,

ich habe momentan leider keinen Beispielcode zur Hand, mit dem ich dir 
Zeigen kann wie es geht. Ich glaube aber eine deiner Aussagen ist 
falsch.

Paul schrieb:
> Ich habe das ganze jetzt einfach mit Timer1 als up counter mit prescaler
> 1 und period 1 gemacht damit sollte dieser doch mit dem
> Systemtakt(168MHz laufen),

Wenn ich mich recht erinnere laeuft kein Timer der STM32F4 Serie mit 168 
MHz. Auch sehe ich keinen Aufruf fuer das SystemInit, welches die 
Taktung im System einrichtet (kann aber auch im Startup Code liegen).

Schau dir am Besten mal folgendes Excel Tool an:
http://www.st.com/web/en/catalog/tools/PF257927#

Mit diesem Tool kann Taktung konfigurieren und auch sehen, an welchen 
Stellen welcher Takt tatsaechlich anliegt (laut Tool fuer Timer 1 
maximal 84 MHz). Auch solltest du ueberpruefen ob im "stm32f4xx.h" 
Header die Quarzfrequenz wirklich mit 25 MHz angegeben ist und nicht mit 
8 MHz (haeufiger Fehler).
Gast #3506160
Lesenswert?

Paul schrieb:
> TIM_InitStruct.TIM_Period = 1;
Du lässt den Timer von 0-1 zählen und dann wieder bei 0 starten. Kein 
Wunder dass das nicht so ganz klappt.

Michi schrieb:
> Zuvor standen auch die (richtigen) DWT register Adressen im wiki.
Oh... Ich hatte den Code dort "korrigiert", weil er hässlich war und im 
Text "SysTick" stand, aber die Adressen auf die DWT verwiesen. Habe es 
jetzt wieder auf DWT unter Verwendung der CMSIS geändert und im Text 
SysTick durch DWT ersetzt. Jetzt müsste es das gleiche tun wie der 
Original-Code...
Gast #3506301
Lesenswert?

Arne Maximilian R. schrieb:
> Schau dir am Besten mal folgendes Excel Tool an:
> http://www.st.com/web/en/catalog/tools/PF257927#
das habe ich benutzt um die Werte für HSE_VALUE (uint32_t)8000000 und 
PLL_M 8
einzustellen, die Werte für die Timer stimmten schon überein und laut 
dem sheet läuft dann timer 1 mit den 168MHz.
Das Problem ist wohl wirklich die Period. Hab sie auf 100 gesetzt und 
schon hatte timerValue einen Wert von 87. Anscheinend hab ich diesen 
Paramter nicht wirklich verstanden. Auf was müsste man den denn 
einstellen damit wirklich der counter so schnell wie nur eben möglich 
läuft und man dann wirklich sagen kann wenn z.B. timerValue = 100 ist 
dann hat die Ausführung (100 * 5,9ns) gedauert.
1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
2
TIM_InitStruct.TIM_Prescaler = 1;
3
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
4
TIM_InitStruct.TIM_Period =  ???????????????????????????????????
5
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
6
TIM_InitStruct.TIM_RepetitionCounter = 0;
7
TIM_TimeBaseInit(TIM1, &TIM_InitStruct);
Gast #3506369
Lesenswert?

> Ich  habe debug auf RAM gestellt damit nicht immer der flash geschrieben
> werden muss.

Auch alle anderen Einstellungen gemacht damit die Ausführung aus dem RAM 
nicht schiefgeht ?
Laß das Prog doch mal testweise aus dem Flash laufen.
Gast #3506390
Lesenswert?

Uwe schrieb:
> Auch alle anderen Einstellungen gemacht damit die Ausführung aus dem RAM
> nicht schiefgeht ?
> Laß das Prog doch mal testweise aus dem Flash laufen.
... was gäbe es denn da sonst noch für Einstellungen?
Mit Debug in RAM in der Projekt configuration wurde alles automatisch 
gesetzt, denke die Ausführung funktioniert schon, da nach einem reset 
des boards das original (LED blink und accelerometer test) Programm 
wieder läuft.
Schätze es ist wohl einfach ein Denkfehler von mir, muss mir die Sache 
mit den Timern nochmal vernünftig anschauen. Ich benutz da warscheinlich 
etwas falsch.
Gast #3506430
Lesenswert?

...habe grad mal etwas ausprobiert...
TIM_Period auf 168 gesetzt.
timerValue war nach der Ausführung der for Schleifen dann 29.
Bedeutet das nun die Ausführung hat : 29 * (1 / (168000000 / 168))s also 
29 mikrosekunden gedauert? Oder liege ich da immer noch falsch?
(Firma: EleLa - www.elela.de) #3506439
Lesenswert?

@Paul

Hier ist beschrieben wie man den Clock auf 168MHz einstellt:
http://www.mikrocontroller.net/articles/STM32_CooCox_Installation#Clock_auf_168MHz_einstellen

Wenn man SystemInit(); nicht aufruft wird der STM32F4xx mit dem internen 
HSI von 16MHz laufen. CooCox initialisiert den Clock nicht alleine.

Mit RCC_GetClocksFreq() kann man erfahren wie schnell die einzelnen 
Teile laufen, vorausgesetzt in der stm32f4xx.h wurde der Wert von 
HSE_VALUE korrekt definiert.
(Firma: EleLa - www.elela.de) #3506449
Lesenswert?

Du kannst auch das MCO1 Signal so parametrieren, dass der CPU Takt auf 
einem Port-Pin ausgegeben wird und dann messen ob das passt. Bei 168MHz 
musst Du den MCO1-Clock noch mindestens durch 4 Teilen, damit das auch 
gut messbar ist, somit müsste 42MHz zu messen sein wenn die CPU mit 
168MHz läuft.
Gast #3506461
Lesenswert?

Markus Müller schrieb:
> Hier ist beschrieben wie man den Clock auf 168MHz einstellt:
> 
http://www.mikrocontroller.net/articles/STM32_CooCox_Installation#Clock_auf_168MHz_einstellen
habe ich alles so gemacht, SystemInit(); wird auch im default reset 
handler aufgerufen.
Ich gehe davon aus das alles soweit stimmt, ich bin mir halt nur nich 
wirklich sicher ob meine Annahme über den TIM_Period Parameter und meine 
Rechnung stimmt.
Ansonsten dürfte da sonst kein Fehler mehr drin sein.
(Firma: EleLa - www.elela.de) #3506492
Lesenswert?

Der TIM1 läuft mit 84MHz, weil der Bus APB2 nicht mehr kann und der 
Teiler von der CPU Frequenz in SystemInit(); auf DIV 2 eingestellt 
wurde. (Wenn der doch mit 168MHz laufen sollte wird der Fehlerhaft 
arbeiten.)

TIM_InitStruct.TIM_Prescaler = 1; macht nochmal DIV 2

Somit zählt der Zähler mit 42MHz

Rufe mal RCC_GetClocksFreq(), dann siehst Du die Frequenzen der 
einzelnen Busse.
#3506494
Lesenswert?

Hallo,

lasse dir doch erstmal die Clocks ausgeben:
1
  RCC_ClocksTypeDef RCC_Clocks;
2
  RCC_GetClocksFreq(&RCC_Clocks);
3
  sprintf(ubuf, "HCLK:      %lu Hz", RCC_Clocks.HCLK_Frequency);
4
  Uart_SendString(COM2, ubuf, UART_LFCR);
5
  sprintf(ubuf, "PCLK1:      %lu Hz", RCC_Clocks.PCLK1_Frequency);
6
  Uart_SendString(COM2, ubuf, UART_LFCR);
7
  sprintf(ubuf, "PCLK2:      %lu Hz", RCC_Clocks.PCLK2_Frequency);
8
  Uart_SendString(COM2, ubuf, UART_LFCR);
9
  sprintf(ubuf, "SYSCLK:    %lu Hz", RCC_Clocks.SYSCLK_Frequency);
10
  Uart_SendString(COM2, ubuf, UART_LFCR);


lg, markus
Gast #3506548
Lesenswert?

... ich hab mal das excel sheet mit meinen Einstellungen drin angehängt, 
die Einstellungen habe ich wie hier : 
http://myembeddedtutorial.blogspot.de/2013/06/working-with-stm32f4-timers.html
 und hier :
http://blog.stm32f4.eu/development-chain/setting-up-coocox/
beschrieben gemacht.
Das sollte schon stimmen, aber
ich denke ich habe es raus:
gehen wir davon aus das board läuft mit 168 MHz
Timer 1:
TIM_Prescaler = 0;
TIM_Period = 100;
dann ist timerValue nach den for - Schleifen = 68.
Ausführung dauert:
(1 / (168000000 / 100))s * 68
=
0,00000059s * 68 = 0,00004046s = 40,46µs
Angehängte Dateien:
Gast #3506890
Lesenswert?

Paul schrieb:
> TIM_Period = 100;
Im Upcounting Mode läuft der Timer immer von 0 bis "TIM_Period" und 
fängt dann wieder bei 0 an; du solltest das also schlauerweise auf was 
möglichst hohes setzen (max. 2^16-1 bei 16bit-Timern wie dem TIM1) damit 
der Timer möglichst weit zählt bevor er wieder bei 0 anfängt! Und eben 
dafür sorgen dass er mit 168MHz zählt, damit er alle Core-Takte zählt. 
Alternativ kannst du auch einen der 32bit-Timer (wie TIM2) nehmen und 
Period auf 2^32-1 setzen, damit du "wirklich" weit zählen kannst (2^16 
Takte sind ja jetzt nicht soo viel).
(Firma: EleLa - www.elela.de) #3506955
Lesenswert?

Der Timer 1 kann nicht mit 168MHz zählen, nur mit 84MHz. Siehe hier:
http://www.mikrocontroller.net/wikifiles/3/33/STM32F407.png

Die maximale Frequenz der Timer ist begrenzt durch den jeweiligen Bus 
Takt, an dem der Timer angeschlossen ist (APB1/APB2).

Wenn man schneller zählen will muss man die Core eigenen Timer nutzen, 
wie z.B. den Systick oder DWT  (wie schon oben gezeigt).
Wobei der Systick in der Regel für das erzeugen eines 1ms System-Taktes 
genutzt wird und für die Zyklus-Zeitmessung eher nicht missbraucht 
werden sollte.

Geht leider nicht anders. Eine Zeitmessung ist mit den TIMx Timer der 
Periphere natürlich möglich - jedoch nicht mit 168MHz.

Wenn schon ein Timer, dann am besten den TIM6 oder TIM7 verwenden, denn 
die sind nur interne Timer ohne Port Anschluss.
Der TIM1 oder TIM8 sind relativ "Wertvolle" Timer, gedacht für 
Motor-Ansteuerungen und daher sollte man diese nicht schon für 
Kleinigkeiten "Blockieren".
TIM10 oder TIM11 können auch mit 84MHz zählen, und haben jeweils nur 
einen Ausgang. Den könnte man somit gut für internes nutzen.

Dieses Schaubild sollte jeder ausdrucken und sich wo hin hängen oder als 
Bildschirm Desktop Hintergrund setzen ;-)
Gast #3507018
Lesenswert?

OK, Timer 2, 32 bit, 84MHz, so wie hier : 
http://myembeddedtutorial.blogspot.de/2013/06/working-with-stm32f4-timers.html
eingestellt.

TIM_InitStruct.TIM_Prescaler = 0;
TIM_InitStruct.TIM_Period = 0xFFFFFFFF;;
TIM_InitStruct.TIM_ClockDivision = 0;

nach den for -Schleifen ist timerValue = 22130423.
Sieht schon ganz anders aus.
22130423 * 11,9ns = 263352033,7 ns = 263,352ms für die Ausführung.
Das scheint mir der bis jetzt vernünftigste Wert zu sein wenn man sich 
die ganzen Rechenoperationen in den verschachtelten for - Schleifen mal 
anschaut.
1
  for (line = 0; line < 480; line++)
2
  {
3
    for (col = 0; col < 640; col++)
4
    {
5
      screenBufferIndex = (line / 8) * 80 + (col /8);
6
      tileBuffer0LineOffset = line % 8;
7
      tileBuffer0Col = col % 8;
8
      tileBuffer0Index = screenBuffer[screenBufferIndex] * 64 + (tileBuffer0LineOffset * 8) + tileBuffer0Col;
9
      pixelLine[col] = tileBuffer0[tileBuffer0Index];
10
    }
11
  }

Dann lag das Problem wohl echt daran das der 16 Bit Timer 1 einfach zu 
oft übergelaufen ist und die Period einfach zu klein war.

Das mit dem DWT funktioniert leider nicht:
1
// Takt-Zähler - Messen der Anzahl der Befehle des Prozessors:
2
inline void DWT_CycCounterEn () {
3
  DWT->CTRL = 0x40000001;
4
}
5
inline void DWT_CycCounterDis () {
6
  DWT->CTRL = 0x40000000;
7
}
8
inline uint32_t DWT_CycCounterRead () {
9
  return DWT->CYCCNT;
10
}
11
inline void DWT_CycCounterClear () {
12
  DWT->CYCCNT = 0;
13
}
 [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c: In function 
'DWT_CycCounterEn':
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c:13:3: error: 
'DWT' undeclared (first use in this function)
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c:13:3: note: each 
undeclared identifier is reported only once for each function it appears 
in
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c: In function 
'DWT_CycCounterDis':
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c:16:3: error: 
'DWT' undeclared (first use in this function)
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c: In function 
'DWT_CycCounterRead':
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c:19:10: error: 
'DWT' undeclared (first use in this function)
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c: In function 
'DWT_CycCounterClear':
       [cc] C:\CooCox\CoIDE\workspace\LEDtest001\main.c:22:3: error: 
'DWT' undeclared (first use in this function)
Gast #3507079
Lesenswert?

1
RCC_GetClocksFreq(&RCC_Clocks);
2
uint32_t hclk = RCC_Clocks.HCLK_Frequency;
3
uint32_t pclk1 = RCC_Clocks.PCLK1_Frequency;
4
uint32_t pclk2 = RCC_Clocks.PCLK2_Frequency;
5
uint32_t sysclk = RCC_Clocks.SYSCLK_Frequency;
hclk = 168000000
sysclk = 168000000
pclk1 = 0
pclk2 = 0

das sind meine includes :
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
und in stm32f4xx.h steht auch #include "core_cm4.h"
aber DWT kennt er trotzdem nicht.
Gast #3507124
Lesenswert?

Habe es auch nochmal hier mit probiert :
1
volatile unsigned int *DWT_CYCCNT   = (volatile unsigned int *)0xE0001004; //address of the register
2
volatile unsigned int *DWT_CONTROL  = (volatile unsigned int *)0xE0001000; //address of the register
3
volatile unsigned int *SCB_DEMCR        = (volatile unsigned int *)0xE000EDFC; //address of the register
4

5

6
    *SCB_DEMCR = *SCB_DEMCR | 0x01000000;
7
    *DWT_CYCCNT = 0; // reset the counter
8
    *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
9

10
    volatile unsigned int start = *DWT_CYCCNT;
11
for (line = 0; line < 480; line++)
12
  {
13
      for (col = 0; col < 640; col++)
14
    {
15
      screenBufferIndex = (line / 8) * 80 + (col /8);
16
      tileBuffer0LineOffset = line % 8;
17
      tileBuffer0Col = col % 8;
18
      tileBuffer0Index = screenBuffer[screenBufferIndex] * 64 + (tileBuffer0LineOffset * 8) + tileBuffer0Col;
19
      pixelLine[col] = tileBuffer0[tileBuffer0Index];
20
    }
21
  }
22
    volatile unsigned int stop = *DWT_CYCCNT;
da klappt der build, aber bei der Zeile :
*SCB_DEMCR = *SCB_DEMCR | 0x01000000;
hängt sich das programm auf.
Gast #3507149
Lesenswert?

1
#define    DWT_CYCCNT    *(volatile uint32_t *)0xE0001004
2
#define    DWT_CONTROL   *(volatile uint32_t *)0xE0001000
3
#define    SCB_DEMCR     *(volatile uint32_t *)0xE000EDFC
4

5
SCB_DEMCR  |= 0x01000000;
6
DWT_CYCCNT  = 0;
7
DWT_CONTROL|= 1; // enable the counter
8

9
volatile unsigned int start = DWT_CYCCNT;
10
    for (line = 0; line < 480; line++)
11
  {
12
      for (col = 0; col < 640; col++)
13
    {
14
      screenBufferIndex = (line / 8) * 80 + (col /8);
15
      tileBuffer0LineOffset = line % 8;
16
      tileBuffer0Col = col % 8;
17
      tileBuffer0Index = screenBuffer[screenBufferIndex] * 64 + (tileBuffer0LineOffset * 8) + tileBuffer0Col;
18
      pixelLine[col] = tileBuffer0[tileBuffer0Index];
19
    }
20
    //line++;
21
    //if (line == 480) line = 0;
22
  }
23
volatile unsigned int stop = DWT_CYCCNT;

DAS hat jetzt geklappt,
start ist 4 und stop ist 48563556
das wären dann 48563556 * 5,9ns = 286,5249804ms
Gast #3507153
Lesenswert?

Paul schrieb:
> #define    DWT_CYCCNT    *(volatile uint32_t *)0xE0001004
> #define    DWT_CONTROL   *(volatile uint32_t *)0xE0001000
> #define    SCB_DEMCR     *(volatile uint32_t *)0xE000EDFC
Ganz böser Fehler, wenn schon Macros, dann immer Klammern machen:
1
#define    DWT_CYCCNT    (*(volatile uint32_t *)0xE0001004)
2
#define    DWT_CONTROL   (*(volatile uint32_t *)0xE0001000)
3
#define    SCB_DEMCR     (*(volatile uint32_t *)0xE000EDFC)
Immer drank denken, Macros sind nur eine Text-Ersetzung...

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