mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 PWM Output const 3.3V


Autor: JASEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich hab das Problem das ich nur konstante 3,3V am Ausgnag von PA6,Pa7, 
PB0 und PB1 sehe.

Ist n STm32F103RBT6 STm32H103-Board von Olimex.

Nach dem Programm sollten z.B. an PA6 TIM3_CH1 eine PWM mit 36khz und 
Duty Cycle von 50% zu sehen sein aber das Oszi zeigt mir was anderes, 
eingestellt hab ich dieses auf 10µs pro div.

Ich hab n Tektronix 2225 50Mhz ich denke damit sollte ich ja das 
Ausgangssignal angucken können.
#include "stm32f10x_lib.h"
#include "stm32f10x_map.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"

#include "bits.h"

#define STACK_TOP 0x20000800
#define NVIC_CCR ((volatile unsigned long *)(0xE000ED14))

//--------------- Private Functions ---------------------------------------------

void nmi_handler(void);
void hardfault_handler(void);
int main(void);
void myDelay(unsigned long delay );
void RCC_Configuration(void);
void GPIO_Configuration(void);


//-------------------------------------------------------------------------------
// Define the vector table
  unsigned int * myvectors[4]
     __attribute__ ((section("vectors")))= {
     (unsigned int *)  0x20000800,  // stack pointer
     (unsigned int *)   main,    // code entry point
     (unsigned int *)  nmi_handler,    // NMI handler (not really)
     (unsigned int *)  hardfault_handler    // hard fault handler (let's hope not)
};

// VARIABLES

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;
u16 CCR1_Val = 500;
u16 CCR2_Val = 375;
u16 CCR3_Val = 250;
u16 CCR4_Val = 125;
ErrorStatus HSEStartUpStatus;

GPIO_InitTypeDef GPIO_InitStructure;

//------------------------- MAIN -----------------------------------------------

int main(void)
{

  *NVIC_CCR = *NVIC_CCR | 0x200; // Set STKALIGN in NVIC

  // System Clocks Configuration
  RCC_Configuration();

  // GPIO Configuration
  GPIO_Configuration();

   /* -----------------------------------------------------------------------
      TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
      TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
      TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
      TIM3 Frequency = 36 KHz.
      TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
      TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
      TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
      TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
     ----------------------------------------------------------------------- */

  // Time base configuration
    TIM_TimeBaseStructure.TIM_Period = 999;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    // PWM1 Mode configuration: Channel1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

    TIM_OC2Init(TIM3, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel3
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

    TIM_OC3Init(TIM3, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel4
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

    TIM_OC4Init(TIM3, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM3, ENABLE);

    // TIM3 enable counter
    TIM_Cmd(TIM3, ENABLE);

    while (1)
    {}


}

//SUB Routines-----------------------------------------------------------------

void nmi_handler(void)
{
  return ;
}

void hardfault_handler(void)
{
  return ;
}
//Functions definitions
void myDelay(unsigned long delay )
{
  while(delay) delay--;
}

/*************************************************************************
 * Function Name: Clk_Init
 * Parameters: Int32U Frequency
 * Return: Int32U
 *
 * Description: Init clock system
 *
 *************************************************************************/

void RCC_Configuration (void)
{
  // RCC system reset(for debug purpose)
  RCC_DeInit();

  // Enable HSE
  RCC_HSEConfig(RCC_HSE_ON);

  // Wait till HSE is ready
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
    {
      // Enable Prefetch Buffer
      FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

      // Flash 2 wait state
      FLASH_SetLatency(FLASH_Latency_2);

      // HCLK = SYSCLK
      RCC_HCLKConfig(RCC_SYSCLK_Div1);

      // PCLK2 = HCLK
      RCC_PCLK2Config(RCC_HCLK_Div1);

      // PCLK1 = HCLK/4
      RCC_PCLK1Config(RCC_HCLK_Div4);

      // PLLCLK = 8MHz * 9 = 72 MHz
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

      // Enable PLL
      RCC_PLLCmd(ENABLE);

      // Wait till PLL is ready
          while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
          {}

          // Select PLL as system clock source
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

          // Wait till PLL is used as system clock source
          while (RCC_GetSYSCLKSource() != 0x08)
          {}
        }

    // TIM3 clock enable
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // GPIOA and GPIOB clock enable
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

}



void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  //GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //GPIOB Configuration: TIM3 channel 3 and 4 as alternate function push-pull
 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

Jemand ne Idee was ich falsch mache?

Mfg

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JASEN schrieb:

> // Define the vector table
>   unsigned int * myvectors[4]
>      _attribute_ ((section("vectors")))= {
>      (unsigned int *)  0x20000800,  // stack pointer
>      (unsigned int *)   main,    // code entry point

Wer hat dir denn diese Variante beigebracht? Bischen sehr schräg, den 
kompletten Startup-Code zu überspringen. Neben anderen lustigen Effekten 
hat das auch zur Folge, das initialisierte globale Variablen zwar immer 
noch variabel, aber nicht initialisiert sind.

Autor: JASEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hiho,

als Grundlage hab ich das beispielprogramm genommen, weil ich mich noch 
nicht sooo viel mit dem stm32 beschäftigt hab hatte nur die Main und die 
Funktionen angepasst.

Wieso ist das falsch was soll ich ändern? ;)

Mfg

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwo hier auf der Site liegt m.W. eine Anleitung rum, wie man dem 
STM32 zu Leibe rückt, wenn man für den Compiler nicht löhnen will. Und 
falls es Löhn/Demoware ist: RTFM.

Autor: Markus Müller (mmvisual)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Initialisierung macht der StartUp-Code. Aber wenn man einen selbst 
geschriebenen Boot-Loader verwendet, dann ist dieser Start-Code so 
ziemlich witzlos und man macht die Initialisierung selbst in der Main:
  {  // Initialisieren Speicher
    extern unsigned long _etext;
    extern unsigned long _data;      /* start address for the .data section. defined in linker script */
    extern unsigned long _edata;    /* end address for the .data section. defined in linker script */
    extern unsigned long _bss;      /* start address for the .bss section. defined in linker script */
    extern unsigned long _ebss;      /* end address for the .bss section. defined in linker script */

    unsigned long *pulSrc, *pulDest;
    // Copy the data segment initializers from flash to SRAM.
    pulSrc = &_etext;
    for(pulDest = &_data; pulDest < &_edata; )
      *(pulDest++) = *(pulSrc++);
    // Zero fill the bss segment.
    for(pulDest = &_bss; pulDest < &_ebss; )
      *(pulDest++) = 0;
  }

Ausserdem ist Assembler für den ARM ziemlich schwierig.

Autor: JASEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, vielen Dank das ihr mir helfen wollt aber leider hab ich NULL 
verstannden.

Wo ist jetzt genau das Problem an meinem Code?

Das die Variablen nicht richtig initialisiert werden oder was?

Ich bin sicher noch nicht so weit das ich euch beiden folgen kann also 
bitte habt Verstädnis dafür.

Naja ich hab nun einfach das Beispielprogramm von ST übernommen das 
funktioniert auch nicht :/
#include "stm32f10x_lib.h"
#include "bits.h"

//--------------- Private Functions ---------------------------------------------

void nmi_handler(void);
void hardfault_handler(void);
int main(void);
void myDelay(unsigned long delay );
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);


//-------------------------------------------------------------------------------

// VARIABLES

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;
u16 CCR1_Val = 500;
u16 CCR2_Val = 375;
u16 CCR3_Val = 250;
u16 CCR4_Val = 125;
ErrorStatus HSEStartUpStatus;

GPIO_InitTypeDef GPIO_InitStructure;

//------------------------- MAIN -----------------------------------------------

int main(void)
{
#ifdef DEBUG
  debug();
#endif

  // System Clocks Configuration
  RCC_Configuration();

  // NVIC Configuration
  NVIC_Configuration();

  // GPIO Configuration
  GPIO_Configuration();

   /* -----------------------------------------------------------------------
      TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
      TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
      TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
      TIM3 Frequency = 36 KHz.
      TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
      TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
      TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
      TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
     ----------------------------------------------------------------------- */

  // Time base configuration
    TIM_TimeBaseStructure.TIM_Period = 999;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    // PWM1 Mode configuration: Channel1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

    TIM_OC2Init(TIM3, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel3
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

    TIM_OC3Init(TIM3, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

    // PWM1 Mode configuration: Channel4
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

    TIM_OC4Init(TIM3, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM3, ENABLE);

    // TIM3 enable counter
    TIM_Cmd(TIM3, ENABLE);

    while (1)
    {}


}

//SUB Routines-----------------------------------------------------------------

void nmi_handler(void)
{
  return ;
}

void hardfault_handler(void)
{
  return ;
}
//Functions definitions
void myDelay(unsigned long delay )
{
  while(delay) delay--;
}

/*************************************************************************
 * Function Name: Clk_Init
 * Parameters: Int32U Frequency
 * Return: Int32U
 *
 * Description: Init clock system
 *
 *************************************************************************/

void RCC_Configuration (void)
{
  // RCC system reset(for debug purpose)
  RCC_DeInit();

  // Enable HSE
  RCC_HSEConfig(RCC_HSE_ON);

  // Wait till HSE is ready
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
    {
      // Enable Prefetch Buffer
      FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

      // Flash 2 wait state
      FLASH_SetLatency(FLASH_Latency_2);

      // HCLK = SYSCLK
      RCC_HCLKConfig(RCC_SYSCLK_Div1);

      // PCLK2 = HCLK
      RCC_PCLK2Config(RCC_HCLK_Div1);

      // PCLK1 = HCLK/4
      RCC_PCLK1Config(RCC_HCLK_Div4);

      // PLLCLK = 8MHz * 9 = 72 MHz
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

      // Enable PLL
      RCC_PLLCmd(ENABLE);

      // Wait till PLL is ready
          while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
          {}

          // Select PLL as system clock source
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

          // Wait till PLL is used as system clock source
          while (RCC_GetSYSCLKSource() != 0x08)
          {}
        }

    // TIM3 clock enable
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    // GPIOA and GPIOB clock enable
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

}



void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  //GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //GPIOB Configuration: TIM3 channel 3 and 4 as alternate function push-pull
 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures Vector Table base location.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}

#ifdef  DEBUG
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert_param error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  while (1)
  {}
}
#endif

Ich kann es noch nicht mal auf den uC flashen geschweige den debuggen.

Folgende Meldung kriege ich:
Warning: /cygdrive/C/gccfd/projects/robosoccer: No such file or directory.
mi_cmd_break_watch: Missing <expression>
No registers.
target remote localhost:3333
0xf8f4f000 in ?? ()
symbol-file main.out
monitor soft_reset_halt
requesting target halt and executing a soft reset
monitor flash erase_sector 0 0 31
erased sectors 0 through 31 on flash bank 0 in 1.000000s
monitor flash write_image main.bin 0x08000000
not enough working area available(requested 8192, free 8144)
wrote 15876 byte from file main.bin in 1.968750s (7.875000 kb/s)
thbreak main
Hardware assisted breakpoint 1 at 0x4: file main.c, line 42.
cont

Program received signal 0, Signal 0.
0xfffffffe in ?? ()

Komischeerweise bleibt das Programm genau an der Stelle hängen an dem 
RCC_Configuration() aufgerufen wird

Mfg

Autor: Markus Müller (mmvisual)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mache die Initialisierung der Variablen "CCR1_Val"..."CCR4_Val" in die 
main(), dann gehts.

Genau das wird mit meinem Code-Fragment initialisiert, der in Deinem 
Code Fehlt.
Also eine Variablendeklaration mit Zuweisung ausserhalb einer Funktion 
tut nicht.

PS: hab jetzt nicht den ganzen Code durchgeschaut.

Autor: JASEN (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yeah es klappt damit. Vielen Dank

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.