STM32F4-Ausgang auf PD15 erzeugt ein unerwünschtes PWM-Signal auf PD9

        #include "stm32f4xx.h"
        #include "stm32f4xx_hal_def.h"
        #include "stm32f4xx_hal_rcc.h"
        #include "stm32f4xx_hal_gpio.h"

        int main(void) {
        uint32_t  S1S2, S11S12,S21S22,S31S32,S41S42,S51S52,S61S62;
        uint32_t  comp1,notComp1, comp2,notComp2,comp3,notComp3,inj,notInj,ssgn,notSsgn;

          //Define the structure
         GPIO_InitTypeDef GPIO_InitStruct;

//Start the clock on port D
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;

//Configure the GPIOD OUTPUT pin registers
// port D OUTPUT PIN
GPIO_InitStruct.Pin =
        GPIO_PIN_15  //s1 s2
        | GPIO_PIN_14 //s61 s62
        |GPIO_PIN_13 //s51 s52
        |GPIO_PIN_12  //s41 s42
        |GPIO_PIN_11 //s31 s32
        |GPIO_PIN_10 //s21 s22
        |GPIO_PIN_9; //s11 s12
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

    //Configure the GPIOD INPUT pin registers
    // Port A INPUT PINs
GPIO_InitStruct.Pin =
GPIO_PIN_15   //COMP 1
|GPIO_PIN_14  //COMP 2
|GPIO_PIN_13; //COMP 3
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

    //Configure the GPIOD INPUT pin registers
    // port B INPUT PIN
GPIO_InitStruct.Pin =
GPIO_PIN_15 //Ssgn
|GPIO_PIN_14  //Sinj
|GPIO_PIN_13; //Sinj-
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

while (1)
    {
                notInj = ~GPIOB->IDR&GPIO_PIN_14;
                notInj = notInj << 1;
                comp1 = GPIOA->IDR&GPIO_PIN_15;
                notComp1 = ~GPIOA->IDR&GPIO_PIN_15;
                ssgn = GPIOB->IDR&GPIO_PIN_15;
                notSsgn = ~GPIOB->IDR&GPIO_PIN_15;
                comp3 = GPIOA->IDR&GPIO_PIN_13;
                comp3 = comp3 << 2;
                notComp3 = ~GPIOA->IDR&GPIO_PIN_13;
                notComp3 = notComp3 << 2;
                inj =  GPIOB->IDR&GPIO_PIN_14;
                inj = inj << 1;
                comp2 = GPIOA->IDR&GPIO_PIN_14;
                comp2 = comp2 << 1;
                notComp2 = ~GPIOA->IDR&GPIO_PIN_14;
                notComp2 = notComp2 << 1;

 ///////////////S1S2//////////////////////////////////////////////////////////////////////

        S1S2 = notInj;
        GPIOD->ODR = S1S2; //output is now on pin 15
  /////////////////////S11S12////////////////////////////////////////////////////////

        S11S12 = ((comp1&notComp3)&(ssgn&inj)) | ((notComp1&comp3)&(notSsgn&inj));
        S11S12 = S11S12 >> 6;
        GPIOD->ODR = S11S12; //output on pin 9
   }
}

Wenn ich diesen Code auf die Platine flashe und das Oszilloskop an Pin 9 anschließe, erhalte ich ein PWM-Signal, wenn ich eine gerade Linie für die Gleichspannung erhalten sollte, wenn ich jedoch //GPIOD->ODR = S1S2 auskommentiere, bekomme ich eine gerade Linie das Oszilloskop, wie ich sollte.

Eingänge PA15 HIGH, PB15 HIGH und PA13 HIGH, alles andere niedrig.

Wenn jemand versteht, was ich falsch mache, wäre ich für eine Antwort dankbar, danke im Voraus.

sollte eine gerade Linie bekommen, nicht das. http://imgur.com/gallery/YBWom

Können Sie uns ein vollständiges Codebeispiel geben?
sichere Sache in einer Sekunde

Antworten (1)

Das liegt daran, dass eine Zuweisung wie GPIOD->ODR = valuealle 16 Portbits auf einmal setzt, sodass jede Zuweisung das Portbit zurücksetzt, das die andere gerade gesetzt hat.

Sie können alle Ausgangs-Pin-Werte berechnen und auf einmal einstellen

S1S2 = notInj;
// will do later : GPIOD->ODR = S1S2; //output is now on pin 15
S11S12 = ((comp1&notComp3)&(ssgn&inj)) | ((notComp1&comp3)&(notSsgn&inj));
S11S12 = S11S12 >> 6;
GPIOD->ODR = S11S12 | S1S2; //output on pin 9 AND 15

oder Sie können die Portbitwerte maskieren

GPIOD->ODR = (GPIOD->ODR & ~GPIO_PIN_15) | S1S2;
// ...
GPIOD->ODR = (GPIOD->ODR & ~GPIO_PIN_9) | S11S12;

oder verwenden Sie das BSRR-Register, um einzelne Portbits zu ändern

GPIOD->BSRR = S1S2 ? (1 << 15) : (1 << (15 + 16));
// ...
GPIOD->BSRR = S11S12 ? (1 << 9) : (1 << (9 + 16));

oder ermitteln Sie die Bit-Banding-Adresse der Port-Bits und setzen Sie sie direkt

#define GPIOD_ODR_OFFSET ((uint32_t)&(GPIOD->ODR) - (PERIPH_BASE))
#define GPIOD_ODR_BB (PERIPH_BB_BASE + GPIOD_ODR_OFFSET * 32U)
#define GPIOD_ODR_PIN(x) ((volatile uint32_t *)(GPIO_ODR_BB + (x) * 4))
// calculate S1S2 ...
GPIOD_ODR_PIN(15) = S1S2;
// calculate S11S12 ...
GPIOD_ODR_PIN(9) = S11S12;
Ja, ich habe das Momente später herausgefunden, nachdem ich das gepostet habe ... hahaha, danke für die sehr ausführliche Antwort, die ich wirklich schätze