STM32 Registermanipulation HAL

OP #5145141
Lesenswert?

Hi,

Ich sehe gerade nicht wie ich ein Register manipuliere, wobei
ich nur Zugriff auf eine Instanz (htim2) habe. Was ich versucht habe 
ist:
1
htim2.Instance->EGR =(uint16_t)(1<<6) | (uint16_t)(1<<4); //Set TG=Trigger generation active and CC4G = Campture compare 4 event

Aber wenn ich EGR vor und nach diesem Codeabschnitt auslese, dann bleibt 
EGR immer Null. Wie genau manipuliere ich die Register, wenn ich nur 
Zugriff auf die Instanz habe?
Gast #5145144
Lesenswert?

Bert S. schrieb:
> Aber wenn ich EGR vor und nach diesem Codeabschnitt auslese, dann bleibt
> EGR immer Null.
Normal. EGR ist ein Write-Only-Register. Da kommt beim Zurücklesen immer 
nur 0 raus.

Der Kommentar an deiner Code-Zeile ist aber verdächtig - das Register 
schaltet nichts ein oder aus, sondern löst Ereignisse aus, die 
normalerweise per Hardware ausgelöst werden. Normalerweise braucht man 
das Register eher nicht...
OP #5145150
Lesenswert?

Was ich möchte ist, dass der Timer2 Channel 4 den ADC1 auslöst (über DMA 
einlesen). Beim ADC1 habe ich folgendes gesetzt:
1
 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
2
 hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2;

Und Timer2 Channel 4 ist im Output Compare No Output mode.

Es handelt sich um einen STM32F303K8T6:
http://www.st.com/content/ccc/resource/technical/document/reference_manual/4a/19/6e/18/9d/92/43/32/DM00043574.pdf/files/DM00043574.pdf/jcr:content/translations/en.DM00043574.pdf
Gast #5145153
Lesenswert?

Bert S. schrieb:

> Aber wenn ich EGR vor und nach diesem Codeabschnitt auslese, dann bleibt
> EGR immer Null.

Ist ja auch logisch, weil Du nur ein struct manipulierst, was das 
Register repräsentiert, aber nicht mit ihm identisch ist.

> Wie genau manipuliere ich die Register, wenn ich nur
> Zugriff auf die Instanz habe?

Indem Du danach eine passende API-Funktion aufrufst.

Übrigens solltest Du das direkte Rumgefummel mit Bits lassen und 
stattdessen die passenden Bitmasken-Defines verwenden, weil Dein Code 
sonst unwartbar wird.
Gast #5145162
Lesenswert?

Bert S. schrieb:
> Was ich möchte ist, dass der Timer2 Channel 4 den ADC1 auslöst
> (über DMA
> einlesen).
Ah. Über EGR kannst du nur den ADC sofort auslösen. Um den Timer den 
ADC automatisch auslösen zu lassen, musst du die CCMR, CCER, CCR1 
Register sowie das MMS Feld im CR2 Register setzen und den ADC 
entsprechend konfigurieren.

Nop schrieb:
> Ist ja auch logisch, weil Du nur ein struct manipulierst, was das
> Register repräsentiert, aber nicht mit ihm identisch ist.
Naja, das struct ist mit den Bus-Adressierbaren Daten identisch. 
Allerdings enthält das EGR nur "temporäre" Signale - man schreibt z.B. 
das "UG" bit auf 1, dadurch wird der Timer auf 0 gesetzt, aber das Bit 
wird nicht als 1 gespeichert weil der Timer ja nicht ständig resettet 
werden soll, sondern nur 1x. Es wird eben eine Aktion sofort 
ausgelöst, aber nichts gespeichert.
OP #5145251
Lesenswert?

Nop schrieb:
> Übrigens solltest Du das direkte Rumgefummel mit Bits lassen und
> stattdessen die passenden Bitmasken-Defines verwenden, weil Dein Code
> sonst unwartbar wird.

Das ist mir eigentlich schon klar, jedoch habe ich keine Ahnung, wie 
genau ich auf die Registernamen zugreifen kann? Ich verwende die AC6 
Toolchain und die Eclipse IDE mit den HAL Libraries.
Gast #5145258
Lesenswert?

Bert S. schrieb:
> Das ist mir eigentlich schon klar, jedoch habe ich keine Ahnung, wie
> genau ich auf die Registernamen zugreifen kann?
Einfach hinschreiben?
1
htim2.Instance->EGR = TIM_EGR_TG | TIM_EGR_CC4G;
Eventuell musst du noch ein
1
#include <stm32f303k8.h>
hinzufügen (oder so ähnlich, schau mal was da im Projekt ist).

Wenn du die HAL nutzt brauchst du eigentlich auch gar keine direkten 
Registerzugriffe, die HAL hat für sowas alles Funktionen.
Gast #5145261
Lesenswert?

Oh, ich seh grad ich hab's sogar selbst auf dem Rechner. Es muss
1
#include <stm32f303x8.h>
sein. Da stehen so Dinge drin wie:
1
#define TIM_EGR_TG_Pos   (6U)
2
#define TIM_EGR_TG_Msk   (0x1U << TIM_EGR_TG_Pos)
3
#define TIM_EGR_TG       TIM_EGR_TG_Msk
OP #5145285
Lesenswert?

Danke euch, ich habe das ganze jetzt mal versucht zu implementieren, 
doch leider scheint Timer2 den ADC1 immer noch nicht zu triggern. Ich 
habe das meiste in CubeMX eingestellt und dann noch die Register gemäß 
dem Datenblatt 
http://www.st.com/content/ccc/resource/technical/document/reference_manual/4a/19/6e/18/9d/92/43/32/DM00043574.pdf/files/DM00043574.pdf/jcr:content/translations/en.DM00043574.pdf 
angepasst.

1
//ADC Trigger trough Timer
2
  htim2.Instance->CR2=htim2.Instance->CR2 | (1<<TIM_CR2_MMS_0) | (1<<TIM_CR2_MMS_1) | (1<<TIM_CR2_MMS_2); 
3
  htim2.Instance->CCER=htim2.Instance->CCER |(1<<TIM_CCER_CC4E); 
4
  hadc1.Instance->CFGR=hadc1.Instance->CFGR | (1<<ADC_CFGR_EXTSEL_0) | (1<<ADC_CFGR_EXTSEL_1) | (1<<ADC_CFGR_EXTEN_0); 
5
  hadc1.Instance->CR=hadc1.Instance->CR|(1<<ADC_CR_ADSTART);
6

7
  HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
8
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_array, ADC_SIZE);
Angehängte Dateien:

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