Forum: Mikrocontroller und Digitale Elektronik uVision KEIL


von Ma B. (drumstick)


Lesenswert?

Hallo!

Ich arbeite mit dem uVision von Keil.

Mein uP ist der STM32F107VC!
Mein Programm:
1
void init(void)
2
{
3
4
  /* Konfiguration der GPIO für Push Buttons           */
5
6
7
  RCC   ->  CFGR    =   0x038E848A;
8
  RCC   ->  CR      =   0x01000081;
9
  
10
  RCC   ->  APB2ENR |=  1 <<  3; /* Enable GPIOB clock  */
11
12
13
  //GPIOB ->  CRL     &=  0x00000000;
14
  //GPIOB ->  CRL     |=  0x33333333;
15
  GPIOB ->  CRH     &=  0x00000000;
16
  GPIOB ->  CRH     |=  0x333333BB;
17
18
19
  RCC   ->  APB1ENR =   0x0004;            // enable clock for TIM4
20
       
21
  TIM4  ->  CR1     =   0;                // reset command register 1
22
  TIM4  ->  CR2     =   0;               // reset command register 2
23
24
  TIM4  ->  PSC     =   0x1C1F;         // set prescaler
25
  TIM4  ->  ARR     =   0x270F;        // set auto-reload
26
27
  TIM4  ->  CCR1    =   0x0000;                      //
28
  TIM4  ->  CCR2    =   0x0000;                      //
29
  TIM4  ->  CCR3    =   0x1388;                      //
30
  TIM4  ->  CCR4    =   0x094C;                      //
31
  TIM4  ->  CCMR1   =   0x0000;                      //
32
  TIM4  ->  CCMR2   =   0x6060;                      //
33
  TIM4  ->  CCER    =   0x1100;      // set capture/compare enable register
34
  TIM4  ->  SMCR    =   0x0000;      // set slave mode control register
35
36
  TIM4  ->  SR      =   0x0001;  
37
  TIM4  ->  CR1     =   0x0004;     // set command register 1
38
  TIM4  ->  CR2     =   0x0000;     // set command register 2
39
  TIM4  ->  DIER    =   0x0018;     // enable interrupt
40
  TIM4  ->  CR1     =   0x0001;     // enable timer
41
42
}

funktioniert im Debug Modus einwandfrei. In Echtzeit auf der Hardware 
ist der Ausgang dauernd auf 1.

Was hab ich noch nicht verstanden oder hat jemand das selbe Problem 
schon mal gehabt?? Eigentliche dürfte es im Debugmodus ja auch nicht 
laufen!!??


Vielen Dank und freundliche Grüsse!!

M.B.

von Markus (Gast)


Lesenswert?

> Mein Programm:

Bist du sicher, dass das ganze Programm ist? Wo ist z. B. main()?

von Ma B. (drumstick)


Lesenswert?

Hallo

Hier noch das Hauptprogramm! Sollte aber auch alles I.O. sein!?

Gruss  M.B.

1
#include <STM32F10x.h>
2
#include <Init.h>
3
4
/* Hauptprogramm Main 
5
6
int main (void)         
7
{
8
    
9
    // Subroutiene Initialisierung: Keine Uebergabewerte
10
11
    init();
12
13
    // Endlosschlaufe
14
15
    for (;;)            
16
    {
17
    }
18
19
}

von Bernhard (Gast)


Lesenswert?

Hast du das Hauptprogramm wirklich auskommentiert, oder ist das nur ein 
Copy/Paste Fehler?

Debuggst du mit dem Hardware Debugger oder per Simulator?

von Bernhard (Gast)


Lesenswert?

M. B. schrieb:
> funktioniert im Debug Modus einwandfrei. In Echtzeit auf der Hardware
> ist der Ausgang dauernd auf 1.

Was soll denn das Programm genau machen?

von Ma B. (drumstick)


Lesenswert?

Ach blöd!!

Das ist natürlich ein copy/paste Fehler!

Ja, im Simulator von uVision4! Habe den Output Pin am Oszilloskop 
angeschlossen. Im Debug Modus funktioniert alles im Einzelschritt und im 
Run Modus. Lass ich es in Echtzeit auf der Hardware laufen, bleibt der 
Output immer auf 1. Habe alle Einstellungen mehrfach kontrolliert! Habe 
auch ein Beispielprogramm heruntergeladen, dieses funktioniert auch in 
Echtzeit. Finde aber keinen Unterschied zu meinem Programm!?

Danke und Gruess!

M.B.

von Ma B. (drumstick)


Lesenswert?

Der Timer4 ist als PWM Generator (PWM Mode 1) eingestellt und gibt am 
PortB Pin 8 ein ständig ein PWM Signal aus! Mit Autoreload!

M.B.

von Bernhard (Gast)


Lesenswert?

M. B. schrieb:
> Ja, im Simulator von uVision4!

Wenn du einen Hardware Debugger hast, dann würde ich mit diesem 
debuggen. Die tatsächliche Hardware verhält sich nämlich immer ein 
bisschen anders ;)
In uVision kannst du das hier einstellen:

Project -> Options for Target -> Debug Reiter. Statt "Use Simulator" 
wählst du dann rechts daneben deinen Debugger aus.

Ich hab vor 2 Wochen selbst erst eine PWM Library geschrieben - jedoch 
für den STM32F103. Ich bilde mir ein, dass im Datenblatt meines 
Controllers gestanden ist, dass man den Alternate Function Clock auch 
anknipsen muss. Eventuell ist das auch bei dir der Fall?

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Hi,

setze bitte mal einen Breakpoint im HardFault.
Den findest du im startup.asm

Dann starte den Debugger im Target-Modus (Debug Settings: [ ] Run to 
main() deaktiviert), und starte das ganze mit RUN.

Sollte der im "Fullspeed-Mode" auf ein Peripheral zugreifen, was noch 
nicht (ganz) initialisiert ist, landet der im HardFault und du siehst es 
am BP.

Ein ganz beliebtes Problem bei dem LMI's. Die ST's sind da idR. weniger 
anfällig, was die Initialisierungszeit von CLK in den Peripherals 
betrifft...


VG
/th.

von Ma B. (drumstick)


Lesenswert?

Vielen Dank für die guten Hinweise! Aber es funktioniert immer noch 
nicht! Das heisst im Hardware Debugger schon aber in Echtzeit dann immer 
noch nicht!

Habe aber schon der Verdacht, es könnte an einer clock Einstellung 
liegen!?

Danke und Gruss

M.B.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

> Das heisst im Hardware Debugger schon aber in Echtzeit dann immer noch nicht!

Wenn du mit HW debugger arbeitest (ULINK? JLink?) und du auf RUNd 
drückst, dann sollte es genau so (schnell) funktionieren wie du mit 
"Echtzeit" beschreibst.

Wie genau gehst du vor?
hast du das von mir geschilderte mal ausprobiert?

Kannst auch Debug Session starten, dann auf RESET drücken, dann run. 
Kurz warten, dann STOP drücken und guggen, wo er steht.

Das Programm sollte dann in deiner for(;;) stehen ...


VG,
/th.

von Bernhard (Gast)


Lesenswert?

Ich hab mal aus meinem Code den entsprechenden Teil herauskopiert:
1
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; /*Timer 2 Clock aktivieren*/
2
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; /*Alternate Function Clock aktivieren*/
3
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; /*GPIO A Clock aktivieren*/
4
5
RCC->CFGR &= ~(0x00000700); /*kein ABP1 prescaler */
6
TIM2->CR1 &= (~TIM_CR1_CKD_0 & ~TIM_CR1_CKD_1); /*keine Clock division*/
7
TIM2->CCER &= (~TIM_CCER_CC1E); /*deaktiviere Capture/Compare Output 1 Channel  (um Parameter zu aendern)*/
8
TIM2->CCMR1 &= ~(TIM_CCMR1_CC1S_0 & TIM_CCMR1_CC1S_1); /*konfiguriere Capture/Compare 1 als Output*/
9
TIM2->CCMR1 |= (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2); /*PWM Mode 1*/
10
TIM2->CCMR1 |= TIM_CCMR1_OC1PE; /*Output Compare 1 Preload aktivieren*/  
11
TIM2->CCER &= (~TIM_CCER_CC1P);  /*Polaritaet =  active high*/
12
GPIOA->CRL = GPIOA->CRL & ~PA0_CLEAR | PA0_SET;  /*GPIOA 1 als Alternate-Function Output Push-Pull*/
13
14
TIM2->CCR1 = compare_value; /*Pulsbreitenverhaeltnis festlegen*/ 
15
TIM2->CCER |= TIM_CCER_CC1E; /*aktiviere Capture/Compare Output 1 Channel*/
16
TIM2->PSC = (tim2_prescaler - 1); /*Prescaler setzen*/  
17
TIM2->ARR = tim2_arr_value; /*Auto-Reload Register setzen*/   
18
TIM2->CR1 |= (TIM_CR1_DIR); /*Counter zaehlt runter*/
19
TIM2->EGR |= TIM_EGR_UG; /*Update Event generieren*/
20
TIM2->CR1 |= TIM_CR1_ARPE; /*Auto-Reload Preload aktivieren*/
21
22
TIM2->CR1 |= TIM_CR1_CEN; /*Counter aktivieren (Timer 2)*/
Ist zwar für ein STM32F103 Derivat geschrieben, aber vielleicht hilfts 
dir.

von Ma B. (drumstick)


Lesenswert?

Hallo Random!

Er landet aber nicht im Breakpoint, sonder es funktioniert!
Was meintest Du mit ist noch nicht ganz initialisiert??

Danke und Gruss!

M.B.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Bei den LMI CM3's bin ich anfangs drauf reingefallen, dass der ne gute 
Weile braucht, bis sich nach dem Clock Enable einer Peripherie die Clock 
durch das Peripheral geschwungen hat und dieses betriebsbereit war.
Hat man vorher drauf zugegriffen, landete der Proz im Hard Fault.

D.h. ein write oder read direkt nach einem clock enable funktioniert da 
nicht.
Bei den STs habe ich dies aber nicht feststellen können.


VG,
/th.

von Dennis (Gast)


Lesenswert?

Evtl. wird deine for-schleife vom compiler wegoptimiert.

mach doch mal ein:

while(1){__nop();}

von Ma B. (drumstick)


Lesenswert?

Hallo!

Bin immer noch nicht weiter gekommen! Kann es sein, dass gar kein Event 
generiert wird??

Habe deshalb im Beispiel von Bernhard gesehen, dass ich keine Werte im 
EGR Register gesetzt hatte. Aber laufen tut es immer noch nicht!

Erweiterung
1
TIM4  ->  EGR     =   0x0011;

Danke und Gruss

M.B.

von Bernhard B. (schluchti)


Lesenswert?

Auf welchem Portpin misst du das PWM-Signal? Hast du den entsprechenden 
Portpin als Alternate Function Push Pull konfiguriert? Hab grad kein 
Datenblatt bei der Hand um es zu kontrollieren. Der Alternate Function 
Clock muss auch aktiviert sein.

von Ma B. (drumstick)


Lesenswert?

Hallo Bernhard

Ja, Alternate Function Clock ist aktiviert!

Ich messe das Signal am Pin 8 des Ports B und ist als alternate function 
push pull output konfiguriert!!
1
   RCC   ->  APB2ENR |=  1 <<  0;  /* Alternate function Clock */
2
3
  GPIOB ->  CRH     &=  0x00000000;
4
  GPIOB ->  CRH     |=  0x333333BB; //Push pull output

Danke und Gruss

M.B.

von Ma B. (drumstick)


Lesenswert?

Um sicher zu gehen, dass ich die gleichen Einstellunge wie im 
funktionierenden Beispielprogramm habe, habe ich dieses 1:1 kopiert und 
in mein Programm eingeführt. Jetzt hab ich das Problem, dass der Pointer 
nicht mer ins Hauptprogramm zurückkehrt nach der Init. Und der Fehler, 
"could not stop Cortex-M device Pleas check the JTAG cable".
1
#define __TIM4_PERIOD             0x003E8                 // 48
2
#define __TIM4_PSC                0x1C1F                  // 49
3
#define __TIM4_ARR                0x270F                  // 50
4
#define __TIM4_CR1                0x0004                  // 51
5
#define __TIM4_CR2                0x0000                  // 52
6
#define __TIM4_SMCR               0x0000                  // 53
7
#define __TIM4_CCMR1              0x0000                  // 54
8
#define __TIM4_CCMR2              0x6060                  // 55
9
#define __TIM4_CCER               0x1100                  // 56
10
#define __TIM4_CCR1               0x0000                  // 57
11
#define __TIM4_CCR2               0x0000                  // 58
12
#define __TIM4_CCR3               0x1388                  // 59
13
#define __TIM4_CCR4               0x09C4                  // 60
14
#define __TIM4_DIER               0x0018                  // 61
15
#define __CLOCK_SETUP              1
16
#define __RCC_CR_VAL               0x01010082
17
#define __RCC_CFGR_VAL             0x001D8402
18
#define __HSE 
19
   
20
21
22
23
void init(void)
24
{
25
26
 RCC->CFGR = __RCC_CFGR_VAL;           // set clock configuration register
27
  RCC->CR   = __RCC_CR_VAL;            // set clock control register
28
29
  if (__RCC_CR_VAL & RCC_CR_HSION) {     // if HSI enabled
30
    while ((RCC->CR & RCC_CR_HSIRDY) == 0); //Wait HSIRDY=1 (HSI is ready)
31
  }
32
33
  if (__RCC_CR_VAL & RCC_CR_HSEON) {                 // if HSE enabled
34
    while ((RCC->CR & RCC_CR_HSERDY) == 0); //Wait HSERDY=1 (HSE is ready)
35
  }
36
37
  if (__RCC_CR_VAL & RCC_CR_PLLON) {                 // if PLL enabled
38
    while ((RCC->CR & RCC_CR_PLLRDY) == 0); //Wait PLLRDY=1 (PLL is ready)
39
  }
40
41
  /* Wait till SYSCLK is stabilized (depending on selected clock) */
42
  while ((RCC->CFGR & RCC_CFGR_SWS) != ((__RCC_CFGR_VAL<<2) & RCC_CFGR_SWS));
43
44
45
46
47
  RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;      // enable clock for TIM4
48
        
49
50
    TIM4->CR1 = 0;                          // reset command register 1
51
    TIM4->CR2 = 0;          // reset command register 2
52
                             // detailed settings used
53
      TIM4->PSC = __TIM4_PSC;                        // set prescaler
54
      TIM4->ARR = __TIM4_ARR;              // set auto-reload
55
56
      TIM4->CCR1  = __TIM4_CCR1;            //
57
      TIM4->CCR2  = __TIM4_CCR2;                //
58
      TIM4->CCR3  = __TIM4_CCR3;                            //
59
      TIM4->CCR4  = __TIM4_CCR4;                            //
60
      TIM4->CCMR1 = __TIM4_CCMR1;                           //
61
      TIM4->CCMR2 = __TIM4_CCMR2;                           //
62
      TIM4->CCER  = __TIM4_CCER;    // set capture/compare enable register
63
      TIM4->SMCR  = __TIM4_SMCR;   // set slave mode control register
64
65
      TIM4->CR1 = __TIM4_CR1;       // set command register 1
66
      TIM4->CR2 = __TIM4_CR2;
67
68
}

Ich find den Hacken einfach nicht! Werde aber weitersuchen!

Vielen Dank und Gruss

M.B.

von Ma B. (drumstick)


Lesenswert?

Tja, das Problem ist, dass ich mein Board nach dem Download der Software 
zuerst reseten muss. Dann klappts! Jetzt muss ich nur noch wissen, ob 
dies auch per Software möglich ist?


Danke Euch für die vielen Tipps, Antworten und Geduld ;-)

Gruss

M.B.

von Ma B. (drumstick)


Lesenswert?

Zur Info!

Im uVision unter "Option for Target" -> Utilities -> Settings ->
bei "reset and run" Häckchen setzen

dann läufts!! :-)


Gruss

M.B.

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.