Forum: Mikrocontroller und Digitale Elektronik STM32F4Discovery debugging timer mit coocox ide


von Paul (Gast)


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?

von Dr. Sommer (Gast)


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...

von Michi (Gast)


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.

von Paul (Gast)


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.

von Paul (Gast)


Lesenswert?

habs nun auch mit dem CORE_SysTick sachen aus der wiki probiert, der 
Wert ist auch 0 und wenn sich DWT_CYCCNT an Speicheradresse 0xE0001004 
befindet dann ist es auch 0 :(

von Arne Maximilian R. (arnemaximilian_r)


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).

von Dr. Sommer (Gast)


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...

von Paul (Gast)


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);

von Uwe (Gast)


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.

von Paul (Gast)


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.

von Paul (Gast)


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?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


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.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


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.

von Paul (Gast)


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.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


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.

von Markus C. (ljmarkus)


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

von Paul (Gast)


Angehängte Dateien:

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

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der Timer läuft sicher mit 84000000, ansonsten ist der Bus falsch 
parametriert.

Vergleiche das Ergebnis doch mit den DWT Funktionen.

von Dr. Sommer (Gast)


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).

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


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 ;-)

von Paul (Gast)


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)

von Paul (Gast)


Lesenswert?

also wenn das was Markus sagt richtig ist, würde timer 2 nur mit 42MHz 
laufen, das wiederspricht aber dem was hier : 
http://myembeddedtutorial.blogspot.de/2013/06/working-with-stm32f4-timers.html
steht, und die LED würde in dem Beispiel nicht im 1 Sekunden Takt an/aus 
gehen, aber das tut sie!!!

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

DWT ist in
#include "core_cm4.h
deklariert, die muss man mit einbinden.

Ja, der TIM2 sollte nur mit 42MHz laufen.
Mache doch mal das:
Beitrag "Re: STM32F4Discovery debugging timer mit coocox ide"

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Markus Müller schrieb:
> #include "core_cm4.h
> deklariert, die muss man mit einbinden.
Aber nicht direkt, das klappt nicht... Man muss wie im Artikel die 
<stm32f4xx.h> #includen, die #include't die <core_m4.h> interen.

von Paul (Gast)


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.

von Paul (Gast)


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.

von Dr. Sommer (Gast)


Lesenswert?

Paul schrieb:
> und in stm32f4xx.h steht auch #include "core_cm4.h"
> aber DWT kennt er trotzdem nicht.
Scheinbar sind die "DWT"-Sachen in alten Versionen der CMSIS nicht 
definiert. Verwende mal die neuste Version, 1.3.0 von ST:
http://www.st.com/web/en/catalog/tools/PF257901

von Paul (Gast)


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

von Dr. Sommer (Gast)


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...

von Michi (Gast)


Lesenswert?

Paul schrieb:
> und in stm32f4xx.h steht auch #include "core_cm4.h"
> aber DWT kennt er trotzdem nicht.

core_cm4.h zu alt.

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.