Hallo zusammen,
Ich möchte mit meinem STM8 einen PWM-Eingang auslesen, dazu kann ich
jedoch nicht das PWMI Register nutzen, da TIM1 und TIM2 für PWM-Ausgänge
benötigt werden.
Nun wollte ich mir über einen externen Interrupt und mitlaufenden Timer
4 ein workaround basteln um die PWM auslesen zu können. Dazu zähle ich
die Takte zwischen den Flanken.
Hier die ISR für den externen Port und TIM 4:
1 | INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
|
2 | {
|
3 | bool Turn = TRUE; //FASLE on default
|
4 | uint16_t curVal = 0;
|
5 | GPIO_Pin_TypeDef CurPin = GPIO_PIN_4; //undef
|
6 |
|
7 | if(Turn){
|
8 | TIM4_Cmd(ENABLE);
|
9 | curVal = TIM4_GetCounter()+ OverflowFlag*250;
|
10 | if(GPIO_ReadInputPin(GPIOB,CurPin) == SET)
|
11 | {
|
12 | if(FlankFlag == 0)
|
13 | {
|
14 | CurrentTim1 = curVal;
|
15 | }else if(FlankFlag == 2){
|
16 | CurrentTim2 = curVal - CurrentTim2;
|
17 | }
|
18 | FlankFlag++;
|
19 | }
|
20 | else if(GPIO_ReadInputPin(GPIOB,CurPin) == RESET)
|
21 | {
|
22 | if(FlankFlag == 1)
|
23 | {
|
24 | CurrentTim1 = curVal - CurrentTim1;
|
25 | CurrentTim2 = curVal;
|
26 | FlankFlag++;
|
27 | }
|
28 | }
|
29 | if(FlankFlag == 3)
|
30 | {
|
31 | TIM4_Cmd(DISABLE);
|
32 | TIM4_SetCounter(0);
|
33 | CurrentPeriod = CurrentTim1 + CurrentTim2; //n = CurrentPeriod * 60 (250 = 62,5Hz = 16ms => 1 = 0,064ms)
|
34 | CurrentDutyCycle = (CurrentTim1/CurrentPeriod); //90% - 10%
|
35 |
|
36 | TIM1_SetCompare3(1000*CurrentDutyCycle);
|
37 | TIM2_SetCompare1(1000*CurrentDutyCycle);
|
38 |
|
39 | OverflowFlag = 0;
|
40 | CurrentTim1 = 0;
|
41 | CurrentTim2 = 0;
|
42 | FlankFlag = 0;
|
43 | }
|
44 | }
|
45 | }
|
46 |
|
47 | INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
|
48 | {
|
49 | OverflowFlag++;
|
50 | }
|
Um das alles zu testen wollte ich (wie unten aufgezeigt) die PWM einfach
auf meine PWM-Ausgänge legen, jedoch bekomme ich kein Signal.
Die PWM-Ausgänge funktionieren so, wie sie sollten. Bei meiner
Fehlersuche bin ich dann darauf gestoßen, dass sobald ich die Methode
interruptEnable() aufrufe jeder der PWM-Ausgänge "lahm gelegt" wird
(habe hierzu einen einfach fest nebenbei laufen lassen).
Woran liegt das? Muss ich für mein EXTI und TIM4 register die Interrupts
einzeln zuschalten oder liegt das daran, dass meine ISRs zu lang sind
oder einfach keinen Sinn ergeben? Sobald ich debuggen möchte bekomme ich
leider auch einen St-Link error, programmieren funktioniert jedoch
einwandfrei..
Hierzu auch noch die Inits von Tim4 und EXTI:
1 | void configEXTI(void)
|
2 | {
|
3 | EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB,EXTI_SENSITIVITY_RISE_FALL);
|
4 | EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC,EXTI_SENSITIVITY_RISE_FALL);
|
5 | //enableInterrupts();
|
6 |
|
7 | }
|
8 |
|
9 | void configTIM4(void)
|
10 | { //Timer to count PWMI
|
11 | TIM4_DeInit();
|
12 | TIM4_TimeBaseInit(TIM4_PRESCALER_128,250);
|
13 | TIM4_SetAutoreload(0);
|
14 | TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
|
15 | TIM4_Cmd(DISABLE);
|
16 | //enableInterrupts();
|
17 | }
|