Moin, ich arbeite mit dem STM32F103 und wandle analoge Werte im Simultanen Modus mit den ADC Wandlern des Controllers, die gewandelten Werte werden mittels DMA in ein großes Array geschoben und von dort aus über den USB an einen PC gesendet. Wenn ich die Abtastrate des ADC einstellen möchte, mache ich das über die Prescaler und die SampleTime. Für die ADC Clock komme ich auf 12MHz und wenn ich den DMA benutze berechne ich meine Abtastrate mit folgender Formel: Ta = (12,5 + SampleTime) / 12MHz. Da kommen dann nur krumme Werte für die Abtastfrequenz bei raus, außer bei der Einstellung 7,5Cycles. Da erhalte ich 600kHz, diese Abtastfrequenz ist allerdings zu hoch für eine Mehrkanalabtastung mit nachfolgender Übertragung per USB und darum möchte ich diese Abtastrate weiter teilen, zum Bsp. auf 300kHz,200kHz oder 150kHz. Dafür wollte ich einen eigenen Teiler verwenden. Für den DMA habe ich automatische Inkrementierung des Memory Zeigers aktiviert und der wird bei jeder DMA - Übertragung inkrementiert, d.h. 600k mal in der Sekunde. Hat jemand eine Idee wie ich die Inkrementierung beeinflussen kann, sodass nur noch jeder zweite, dritte oder vierte Wert übertragen wird? Danke im Voraus. Gruß Waddi
Lass doch per DMA das Ergebis in den Speicher übertragen und mach die Übertragung per USB von da aus mit der gewünschten Abtastrate.
Wieso nimmst du keinen Timer für die Abtastrate? TIM4 wäre z.B. möglich. Grüsse
Mit der Timer - Triggerung habe ich mich noch nicht auseinandergesetzt. Hast du da Erfahrung mit? Sind damit so hohe Abtastraten denn möglich? Wäre nett wenn du mir ein Beispiel nennen könntest, bzw. Beispielcode. Danke Gruß Johannes
>Hat jemand eine Idee wie ich die Inkrementierung beeinflussen kann, >sodass nur noch jeder zweite, dritte oder vierte Wert übertragen wird? Du hast DMA nicht verstanden. Das übertragt dir nur Blöcke. Aber nicht jedes zweite, dritte, vierte Byte.
holger schrieb: > Du hast DMA nicht verstanden. Das übertragt dir nur Blöcke. > Aber nicht jedes zweite, dritte, vierte Byte. Du auch nicht. So etwas gibt es, aber nicht bei dieser CPU. c.u.
Danke Holger & Heinzi aber auf solche Antworten kann ich echt verzichten!!! Also ich ich weiß wie der DMA funktioniert! Meine Frage war ob ich die Inkrementierung beeinflussen kann.
>Also ich ich weiß wie der DMA funktioniert! Meine Frage war ob ich die >Inkrementierung beeinflussen kann. Ja, klar du kannst auf 8Bit, 16Bit und 32Bit umschalten. Aber ich glaube das bringt dich nicht weiter.
Danke Holger! Das habe ich auch schon durchgespielt, aber ohne Lösung. Also ich dachte irgendiwe daran, dass ich den MemoryZeiger beeinflussen kann. Über das CMDTR Register, aber das ist nicht der Zeiger sondern nur die Anzahl an verbleibenden Bytes.
Ich versteh dein Problem nicht! Wenn du nur jeden 2.Wert brauchst,dann brauchts du ja auch nur mit dieser Frequenz zu sampeln. Außer du willst zur Auflösungsverbesserung mehrere Werte mitteln. Die Ansteuerung des ADC über TIM4 geht sinngemäß so: /* TIM4 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3051; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* TIM4 channel4 configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0x3F; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC4Init(TIM4, &TIM_OCInitStructure); ADC: ADC_DeInit( ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 12; ADC_Init(ADC1, &ADC_InitStructure); void start_ADC1(void) { ADC_ExternalTrigConvCmd(ADC1, ENABLE); TIM_CtrlPWMOutputs(TIM4, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); /* Enable DMA1 Channel1 Transfer Complete & Half interrupt */ DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel1,DMA_IT_HT, ENABLE); TIM_Cmd(TIM4, ENABLE); DevStatus.adc1_run=1; } Grüsse
Dankeschön, das werde ich gleich mal ausprobieren. Also das oben Beschriebene wollte ich machen, weil wir uns über die gesamte Zeit der Entwicklung auf die SampleTime Einstellungen konzentriert haben und uns die krummen Abtastraten erstmal egal waren, nun da alles soweit funktioniert wollten wir auch gerade Abtastraten erreichen und da kam uns die Idee den ADC mit 600kHz abtasten zu lassen und nur jeden zweiten Wert zu nehmen, sodass wir effektiv mit 300kHz abtasten. Aber diese Sache mit dem nur jeden zweiten Wert nehmen, dass klappt nicht wie ich mir das ausgedacht hatte. Schade. Da ich im letzten Monat meiner BA bin, wollte ich mich nun eigentlich nicht mehr mit den Timern beschäftigen, aber das wird mein Entwicklerherz wohl nicht zulassen und darum werde ich heute Nacht mal eine Timer - Time einlegen. Gruß
Der Thread ist zwar schon eine Weile in der Versenkung, allerdings beschäftige ich mich auch gerade mit der Thematik. Bist du zum gewünschten Ziel gelangt und falls ja, wie hast du es nun final umgesetzt? Ich habe eine ähnliche Aufgabe vor mir: - die Umsetzung soll über einen Taster ausgelöst werden - die Abtastrate soll 200kHz betragen - ein Signal soll über einen einzelnen ADC 100ms lang aufgezeichnet werden --> 20.000 Messwerte à 12bit resp. 16bit - die gesampelten Daten sollen im SRAM (ggf. Erweiterung des SRAM über FSMC) hinterlegt und weiterverarbeitet und das Ergebnis der Analyse auf einem GLCD (per FSMC angebunden) dargestellt werden (Histogramm, MinWert, MaxWert, Vpp etc.) - bzw. die gesampelten Daten aus dem SRAM sollen zum PC hin übertragen und abgespeichert werden, um dort ausgewertet werden zu können Als Plattform habe ich den STM32F103 (HY-Mini) vor mir zu liegen. branadic
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.