Hallo Mikrocontroller-Mitglieder,
ich möchte ein Code schreiben, mit dem man das Tastverhältnis einer PWM
laufend ändert. Dafür habe ich zwei if-Anweisungen geschrieben, jedoch
wird das Tastverhältnis nicht geregelt. Wenn ich nach dem Debugen,
schrittweise die Anweisungen durchklickte, wird zwar die Variable
CCR2_Value erhöht, das lässt sich aber nicht bemerkbar machen. Ich messe
am Oszilloskop das PWM Signal laufend, dieser rennt aber mit dem im Main
fix eingestellten Tastverhältnis. Hat einer von euch Tipps bzw.
Anregungen? Jeder Hinweis ist brauchbar.
Danke und LG
Michael
#include <stm8s.h>
#include <stm8s_eval_lcd.h>
#include <stdio.h>
uint8_t StrName[16]={0};
uint16_t Conversion_Value = 0;
float Stufe = 0.00488;
float Nominal_Min = 3.500;
float Nominal_Max = 4.500;
float Conversion_Value_Current = 0;
uint16_t CCR2_Val = 27 ;
// Parametrisierung des PI Reglers !!!! MUSS NOCH IN MATLAB BESTIMMT
WERDEN !!!! //
float kp = 0.001;
float tn = 0.04;
int main(void){
// Systemtakt
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
// Erzeuge PWM
TIM3_DeInit();
TIM3_TimeBaseInit(TIM3_PRESCALER_1, 45);
TIM3_OC2Init(TIM3_OCMODE_PWM1, TIM3_OUTPUTSTATE_ENABLE,CCR2_Val,
TIM3_OCPOLARITY_HIGH);
TIM3_ARRPreloadConfig(ENABLE);
TIM3_OC2PreloadConfig(ENABLE);
TIM3_Cmd(ENABLE);
// Initialisiere ADC und LCD
STM8S_EVAL_LCD_Init();
GPIO_DeInit(GPIOB);
ADC2_DeInit();
GPIO_Init(GPIOB, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT);
ADC2_Init(ADC2_CONVERSIONMODE_CONTINUOUS, ADC2_CHANNEL_2,
ADC2_PRESSEL_FCPU_D4, ADC2_EXTTRIG_TIM, DISABLE , ADC2_ALIGN_RIGHT,
ADC2_SCHMITTTRIG_CHANNEL9, DISABLE);
ADC2_Cmd(ENABLE);
LCD_Clear();
LCD_BacklightCmd(ENABLE);
ADC2_StartConversion();
LCD_SetCursorPos(LCD_LINE1, 0);
LCD_Print("Convers.Value.:");
LCD_Print(" ");
while(1)
{
while(!ADC2_GetFlagStatus()){}
Conversion_Value = ADC2_GetConversionValue();
Conversion_Value_Current = Conversion_Value*Stufe;
//Regelung der Duty Cycle für einen erwünschten Ausgangsstrom
if(Conversion_Value_Current > Nominal_Max)
{
CCR2_Val--;
}
else if (Conversion_Value_Current < Nominal_Min)
{
CCR2_Val++;
}
TIM3_OC2Init(TIM3_OCMODE_PWM1, TIM3_OUTPUTSTATE_ENABLE,CCR2_Val,
TIM3_OCPOLARITY_HIGH);
sprintf((char*)StrName, "%.3f ", (Conversion_Value*Stufe));
LCD_SetCursorPos(LCD_LINE2, 0);
LCD_Print(StrName);
ADC2_ClearFlag();
}
}
Du musst, um den Fehler zu finden, etwas systematischer vor gehen als "geht nicht, hiiiiilfeeeee". Grenze den Fehler ein, analysieren warum sich der Tastgrad nicht ändert. Was passiert wenn du den Comparewert manuell hoch und runter zählst, ohne die if-Bedingung, ändert er sich dann? Was passiert wenn du den Comparewert innerhalb der while(1) auf einen anderen Wert als den bei der Initialisierung setzt? Wird er übernommen oder bleibt er auf dem Wert bei Initialisierung? Michael L. schrieb: > while(!ADC2_GetFlagStatus()){} Kommt er dran hier überhaupt vorbei? Eine while(irgendwas) ohne ein Timeout ist gefährlich...
Ingo Less schrieb: > Grenze den Fehler ein, analysieren warum sich der Tastgrad nicht ändert. > Was passiert wenn du den Comparewert manuell hoch und runter zählst, > ohne die if-Bedingung, ändert er sich dann? Was passiert wenn du den > Comparewert innerhalb der while(1) auf einen anderen Wert als den bei > der Initialisierung setzt? Wird er übernommen oder bleibt er auf dem > Wert bei Initialisierung? Hallo Igno, ja du hast recht, bin systematischer vorgegangen und folgendes entdeckt: 1. Wenn ich die if-Anweisung weglasse und in den CCR2_Value händisch erneut definiere, wird dieser neuere Wert in übernommen und es stellt sich der neue Tastgrad ein 2. Sobald ich aber die if-Anweisung wieder einfüge, und folgenden Teil-Code verwende: if(Conversion_Value_Current > Nominal_Max) { CCR2_Val = 10; } else if (Conversion_Value_Current < Nominal_Min) { CCR2_Val = 38; } TIM3_SetCompare2(CCR2_Val); ändert sich der Tastgrad für den jeweiligen Fall. Also wird mein Decrement bzw. Increment fehlerhaft sein oder? Was meinst du?
Michael L. schrieb: > Was meinst du? Das das hier > TIM3_SetCompare2(CCR2_Val); was Anderes ist als das hier > TIM3_OC2Init(TIM3_OCMODE_PWM1, TIM3_OUTPUTSTATE_ENABLE,CCR2_Val, > TIM3_OCPOLARITY_HIGH); Aber das hier ist wohl der Fehler:
1 | if(Conversion_Value_Current > Nominal_Max) |
2 | {
|
3 | CCR2_Val--; |
4 | }
|
5 | else if (Conversion_Value_Current < Nominal_Min) |
6 | {
|
7 | |
8 | CCR2_Val++; |
9 | |
10 | }
|
ist ziemlicher Unsinn, grundsätzlich. Denn wenn CCR2_Val = 0 ist und du einen abziehst, geht der Tastgrad von 0 auf 2^16-1 UND es erfolgt kein Compare-Match mehr. Also, du musst deinen Tastgrad schon in den zulässigen Grenzen bewegen und die nicht verlassen. Also nicht größer als 45 werden... Also einen Limitter hinter die if, else if Abfrage. Dann wirst du sehen, dass dein Tastgrad vermutlich auf 0 oder 100% rast...
Hallo, ich habe eine Frage bezüglich der PWM Erzeugung bei STM8. Ich brauche ein 350kHz Signal, und möchte aber den Duty Cycle in 1% Schritten erhöhen. Laut dem Formel im ST Sheet, PWm_Freq = Timer_Freq/ARR + 1 Setzte ich als Timer_Freq 16MHz, ungeteilt vom Clock Frequenz hergeleitet und hierbei komme ich auf ca. ARR = 45 um 353kHz zu kommen. 45 entspricht aber eine Auflösung von 2,2% Schrittweite, welches für meine Anwendung nicht brauchbar ist. Gibt es eine Möglichkeit, trotz dieser Tatsache eine feinere Auflösung zu erreichen?
Hallo, ich habe eine Frage bezüglich zwei unterschiedlichen Versorgungsspannungen. Ich muss ein µC versorgen mit 5V, brauche aber auch für die weitere Beschaltung 3,3V. Muss ich dafür zwei LDOs nehmen oder kann ich am Ausgang des 5V LDOs auch einen Spannungsteiler machen um die 3,3V zu bekommen. Wären dann die 3,3V genauso stabil wie die 5V am LDO ausgang? LG
Jürgen schrieb: > Muss ich dafür zwei LDOs nehmen oder kann ich am Ausgang des 5V LDOs > auch einen Spannungsteiler machen um die 3,3V zu bekommen. Schlechte Lösung, sehr schlecht. Der Strom ist nicht konstant und du brauchst daher eine Regelung.
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.