Forum: Mikrocontroller und Digitale Elektronik STM32L152RC HSI


von Mathias G. (motze)


Lesenswert?

Hallo ich versuche den STM32L auf 16 MHz internen clock laufen zu lassen 
leider gelingt mir das noch nicht so.

Konnte die clock werte schon veränder aber irgendwie nie auf den wert 
den ich wollte(16MHz).
1
#include <STM32L1XX.h>
2
#include <stdio.h>
3
#include "GPIO_INI.h"
4
5
6
int main(void)
7
{  
8
  GPIO_INI();
9
10
  RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
11
  RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
12
  RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
13
  
14
  //Systemtakt auf PortA Pin8 ausgeben
15
  RCC->CFGR |= RCC_CFGR_MCO_HSI;  //Internal 16 MHz RC oscillator clock selected
16
  
17
  while (1)
18
  {
19
    //Schaltet PortB Pin6 auf Low
20
    GPIOB->BSRRL = (1<<6);
21
    
22
    //Schaltet PortB Pin6 auf High
23
    GPIOB->BSRRH = (1<<6);
24
  }
25
  
26
  return 0;
27
}

Ich messe an PortB Pin6 eine Frequenz von 1,773 MHz.

Wo liegt den da der Fehler?

Ich benutze Keil und das 32L152 L1 Discovery Board von STM.

Vielen Dank.
Mathias

von Detlef K. (adenin)


Lesenswert?

Mathias G. schrieb:
> RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
>   RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
>   RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
>
>   //Systemtakt auf PortA Pin8 ausgeben
>   RCC->CFGR |= RCC_CFGR_MCO_HSI;  //Internal 16 MHz RC oscillator clock
> selected

Hmm, welche Werte enthielten den die Register CR und CFGR vor der 
ODER-Verknüpfung?

von Mathias G. (motze)


Lesenswert?

Hallo also wenn ich debugge und die werte mir gleich anschaue sind es 
folgende.

CR:   0x00010300
CFGR: 0

Nach dem diser teil ausgeführt wurde
1
  RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
2
  RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
3
  RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
4
  
5
  //Systemtakt auf PortA Pin8 ausgeben
6
  RCC->CFGR |= RCC_CFGR_MCO_HSI;  //Internal 16 MHz RC oscillator clock selected

sind die Werte wie folgt.

CR:   0x00010303
CFGR: 0x00000005

ich hoffe es hilft dir weiter.

lg
Mathias

von Detlef K. (adenin)


Lesenswert?

>> RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
Die Bits kannst Du nicht beschreiben, nur auslesen


>> CFGR: 0x00000005
Vergleich mal die Bits, die gesetzt sind, mit denen, die Du setzen 
wolltest.

von Mathias G. (motze)


Lesenswert?

Hi

also es sieht wie folgt aus:

RCC->CFGR |= RCC_CFGR_SW_HSI (ist gleich zu setzen mit 0x00000001)
Das bit ist gestzt.

RCC->CFGR |= RCC_CFGR_SWS_HSI (ist gleich zu setzen mit 0x00000001)
Das bit ist auch gesetzt.

Das ergibt zusammen 0x00000005. Genau das was mir auch der Debugger 
sagt.

Mir ist aber aufgefallen das noch andere bits in CR Register gestzt 
sind.

Das sind folgende:
HSEON
MSION
MSIRDY

kann es sein das er sich daran stört?
1
  RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
2
  RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock  
3
  RCC->CR &= ~RCC_CR_HSEON;        //Lösche bit für externen clock
4
  RCC->CR &= ~RCC_CR_MSION;        //lösche bit für multi clock

Habe die stelle mall so umgeschrieben aber keine änderung ausser das die 
Bits gelöscht sind im RCC und MSIRDY sich auch löscht.

lg
Mathias

von ./. (Gast)


Lesenswert?

So wird das auch nuex.

Folgende Reihenfolge:
Im RCC_CR:
1. HSION einschalten
2. Warten bis HSIRDY 1 wird

Dann erst umschalten im RCC_CFGR:
SW auf HSI.

Das ist dann eigentlich schon alles.

Der SWS gibt an was aktuell eingestellt ist, und kann nicht 
beschrieben
werden. (Schrub ja jemand auch schon)

Und der MCO-Pin muss natuerlich Takt bekommen und die Alternate Funktion
eingeschaltet...

Dann kommt da auch was raus.

von Mathias G. (motze)


Lesenswert?

Ich denke ich sollte das in dieser form machen.
1
while(RCC->CR & (1 << RCC_CR_HSIRDY))
2
{
3
4
}

aber irgendwie stimmt die while schleife nicht.

Frage ich das Bit richtig ab? Ich glaube nicht oder?

lg
Mathias

von Detlef K. (adenin)


Lesenswert?

Mathias G. schrieb:
> also es sieht wie folgt aus:
>
> RCC->CFGR |= RCC_CFGR_SW_HSI (ist gleich zu setzen mit 0x00000001)
> Das bit ist gestzt.
>
> RCC->CFGR |= RCC_CFGR_SWS_HSI (ist gleich zu setzen mit 0x00000001)
> Das bit ist auch gesetzt.
>
> Das ergibt zusammen 0x00000005. Genau das was mir auch der Debugger
> sagt.

Weiter oben machst Du aber:

Mathias G. schrieb:
> RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
>   RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
>
>   //Systemtakt auf PortA Pin8 ausgeben
>   RCC->CFGR |= RCC_CFGR_MCO_HSI;  //Internal 16 MHz RC oscillator clock
> selected

Also zusätzlich RCC->CFGR |= RCC_CFGR_MCO_HSI.
Das hast Du bei deiner Erklärung unterschlagen, genauso wie Du 
unterschlagen hats, warum diese Bitgruppe nicht den erwarteten Wert hat.

von Mathias G. (motze)


Angehängte Dateien:

Lesenswert?

So jetzt nochmal das Programm das ich bis jetzt getestet habe. Leider 
hat sich noch nichts verändert. es werden mir immer noch die 1.77 MHZ 
ausgegeben auf den GPIOB Pin6. Diesmal habe ich den Code in anhang 
gesetzt.

Es ging auch schonmal soweit das ich den Systemtakt ausgegeben bekommen 
habe auf GPIOA Pin8. Leider auch nur um die 1MHz.

ach so und weiter oben ist mir ein Fehler passiert.

es geht um diese Zeilen:

RCC->CFGR |= RCC_CFGR_SWS_HSI (ist gleich zu setzen mit 0x00000001<- 
Felhler es heist 0x00000004)
Das bit ist auch gesetzt.

Das ergibt zusammen 0x00000005. Genau das was mir auch der Debugger
sagt.

lg
Mathias

von Detlef K. (adenin)


Lesenswert?

Auszug aus deiner Source:
1
  //Speed Register 
2
  //00 - 2MHz
3
  //01 - 25MHz
4
  //10 - 50MHz
5
  //11 - 100MHz on 30pF/80MHz on15pF
6
  GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6_0;    //PortB Pin6
7
  GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR7_0;    //PortB Pin7
Du setzt nirgendwo die Geschwindigkeit von GPIOA8, damit hat er eine 
Geschwindigkeit vom 400kHz
Deine Geschwindigkeitsangaben sind komplett falsch!

Wenn Du RCC_CFGR_MCO_HSI setzt, wieso zeigt dein Debugger immer noch 
0x00000005 an?
Wieso kommt am MCO was raus, wenn RCC->CFGR auf 0x00000005 gesetzt ist?

1
    //Schaltet PortB Pin6 auf Low
2
    GPIOB->BSRRL = (1<<6);
3
    
4
    //Schaltet PortB Pin6 auf High
5
    GPIOB->BSRRH = (1<<6);
Die Kommentare stimmen nicht mit deinem Code überein.
Das funktioniert genau andersrum.

Ich empfehle ganz dringen nochmal das Reference manual und den Product 
datasheet zu lesen.

von Mathias G. (motze)


Angehängte Dateien:

Lesenswert?

Hi Detlef

vielen dank für deine Hilfe ich habe jetzt den Systemtakt auf 16MHz 
stellen können. Den Code habe ich angehangen mit dem das ganze 
funktioniert. Habe die Geschwindikeit von GPIOA gestezt und schon hat es 
funktioniert. Ne es gingschonmal aber nicht mit den code den ich hier 
gepostet habe. Es war ein anderer und dann habe ich rumgespielt und dann 
ging es halt nicht mehr.

gibt es eine elegantere lösung für die while schleife als ich sie 
benutze?
1
//warten bis speed clock ready ist
2
  while(RCC->CR == 0x00010303)
3
  {
4
    
5
  }

Das ist aus der Header datei kopiert(STM32L1xx.h)
1
#define GPIO_OSPEEDER_OSPEEDR6     ((uint32_t)0x00003000)
2
#define GPIO_OSPEEDER_OSPEEDR6_0   ((uint32_t)0x00001000)
3
#define GPIO_OSPEEDER_OSPEEDR6_1   ((uint32_t)0x00002000)

Das ist aus meiner GPIO_INI.c datei
1
//Speed Register 
2
  //00 - 2MHz
3
  //01 - 25MHz
4
  //10 - 50MHz
5
  //11 - 100MHz on 30pF/80MHz on15pF
6
  GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6;    //PortB Pin6
7
  GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR7;    //PortB Pin7
8
  GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8;    //PortA Pin8

Schön sieht das Bild aber nicht aus auf den Oszi.

Die gelbe Linie ist GPIOB Pin6(1.77MHZ). Die Blaue ist der Systemtakt 
auf GPIOA Pin8(16.13MHz).

Ich glaube irgendwas stimmt immer noch nicht.


lg
Mathias

von Detlef K. (adenin)


Lesenswert?

Mathias G. schrieb:
> gibt es eine elegantere lösung für die while schleife als ich sie
> benutze?

Vielleicht.
1
    while (!(RCC->CR & RCC_CR_HSIRDY))
2
    {
3
4
    }

Die Geschwindigeits in der  GPIO_INI.c sind falsch und die angegeben 
Lastkapazitäten (100MHz/30pF  80MHz/15pF) sind unlogisch.

Mathias G. schrieb:
> Ich glaube irgendwas stimmt immer noch nicht.

Mit deiner Masse stimmt was nicht. (Sag das nie zu einer Frau) ;)

von Mathias G. (motze)


Lesenswert?

Wie kann den was mit meiner Masse nicht Stimmen habe das STM32L1 
Discovery Board das über USB vom Laptop versorgt wird und halt mein 
Osci.

Das mit der Masse werde ich auch vermeiden zu meiner Freundin zu sagen.


lg
Mathias

von Detlef K. (adenin)


Lesenswert?

Wenn die Masseleitung der Messstrippe vom Oszi nicht richtig am Board 
angeschlossen ist, dann bekommt man so ein Bild.

von ./. (Gast)


Lesenswert?

Mit der Art und Weise wie Du versuchst Bits in Registern zu setzen,
wirst Du auch nur Zufallserfolge erzielen:

>   RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
>  RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
>  RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock

Bereits auf '1' stehende Bits werden da hoechstens vor Lachen
wieder auf eine '0' schalten...

von Detlef K. (adenin)


Lesenswert?

./. schrieb:
> Mit der Art und Weise wie Du versuchst Bits in Registern zu
> setzen,
> wirst Du auch nur Zufallserfolge erzielen:
>
>>   RCC->CR |= RCC_CR_HSION;        //Internal High Speed clock enable
>>  RCC->CFGR |= RCC_CFGR_SW_HSI;    //HSI selected as system clock
>>  RCC->CFGR |= RCC_CFGR_SWS_HSI;  //HSI oscillator used as system clock
>
> Bereits auf '1' stehende Bits werden da hoechstens vor Lachen
> wieder auf eine '0' schalten...

Aber nicht diese hier, nur die, die mit w1 im Reference Manual 
gekennzeichnet sind. :P

Hackt doch nicht immer auf den Anfängern rum.
Er lernt das irgendwann schon noch.

: Bearbeitet durch User
von Mathias G. (motze)


Lesenswert?

Wie setze ich die Bits den richtig?

lg
Mathias

von derKer (Gast)


Lesenswert?

Hei

Auf 
http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1533/PF257838?s_searchtype=keyword
findest Du das Clock Configuration tool von ST. Ist ein Excel das Dir 
gleich ein c File generiert mit allen Clock Einstellungen. Wärmstens zu 
empfehlen!

Grüsse derKer

von Mathias G. (motze)


Lesenswert?

Vielen dank für den Tipp.
Leider habe ich kein excell. Ich würde es auch gerne so schaffen damit 
ich die Register besser kennenlerne und den controller. Vorgefertigte 
Funktionen kann ich dann immer noch benutzen.

Kann es sein das dass Masseproblem durch falsche config der GPIO Ports 
kommt?
1
//HSE Off schalten
2
  RCC->CR &= ~RCC_CR_HSEON;    
3
  
4
  //Internal High Speed clock enable
5
  RCC->CR |= RCC_CR_HSION;        
6
  //warten bis speed clock ready ist
7
  while (!(RCC->CR & RCC_CR_HSIRDY))
8
  {
9
10
  }
11
  //HSI selected as system clock          
12
  RCC->CFGR |= RCC_CFGR_SW_HSI;

damit habe ich jetzt 16MHZ auf mein MCO.

Jetzt muss ich noch PLL setzen damit die 16MHz auch auf die GPIOB 
auswirkungen haben richtig?

lg
Mathias

von Detlef K. (adenin)


Lesenswert?

Mathias G. schrieb:
> Wie setze ich die Bits den richtig?
>
> lg
> Mathias

Hier hast Du den Link für die "Standard Peripherals Library"
http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stsw-stm32077.zip

Da sind Beispiele, wie man man mit der Hardware umgehen kann (aber nicht 
zwingend muss).

Mathias G. schrieb:
> Kann es sein das dass Masseproblem durch falsche config der GPIO Ports
> kommt?

Niemals!
Sieht eher so aus, als hast Du überhaupt keine Masseleitung (das kurze 
Stück Kabel an deiner Messspitze) angeschlossen.

Mathias G. schrieb:
> Jetzt muss ich noch PLL setzen damit die 16MHz auch auf die GPIOB
> auswirkungen haben richtig?

Mach doch einfach!
Sieht doch alles nach KEIL aus, was Du da hast. Die haben doch einen 
Debugger, wo Du einfach nur das Bit im Register anklicken kannst, und 
sofort das Ergebnis siehst. Da brauchst Du ja nicht mal was 
programmiern, wenn Du schnell mal ein paar Einstellungen "on the fly" 
ändern willst.

von derKer (Gast)


Lesenswert?

Für was brauchst du denn jetzt die PLL?
Der HSI läuft auf 16MHz, damit der SYSCLK ebenfalls und mit einem AHB 
Prescaler von 1 läuft der HCLK auch auf diesen 16MHz.
Die PLL brauchst du wenn du die 16MHz beispielsweise verdoppeln willst.

von Mathias G. (motze)


Angehängte Dateien:

Lesenswert?

Brauchen tue ich sie jetzt noch nicht. Ich will halt kucken ob ich in 
der lage bin die PLL anzuwenden.
Bin aber noch weit weg davon. Bis jetzt läuft mein 16MHz takt immer noch 
mit diesen Sägezahn ähnlichen Bild auf den Oszi.
Also am ende Soll eine LED mit 16MHz blinken und der Systemtakt soll auf 
Maximum.
Das ist erstmal mein Ziel und das halt nur mit Registern.
Wenn ich das schaffe habe ich wieder ein bischen mehr von STM 
verstanden.

Also Systemtakt habe ich schonmal auf 16MHz und jetzt will ich das 
Maximum halt rausholen.


lg
Mathias

: Bearbeitet durch User
von derKer (Gast)


Angehängte Dateien:

Lesenswert?

Das hilft dir hoffentlich ein bisschen weiter.

HSI als Source für die PLL, PLL multiplication factor auf 4, PLL output 
division auf 2, und du hast die maximalen 32MHz aufem SysClk.
Ob du mit dem internen RC ein besseres Signal bekommst als auf deinen 
Bildern weiss ich nicht, habe immer externe Quarze verwendet...

Gruss derKer

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.