Forum: Mikrocontroller und Digitale Elektronik STM32f103TB PWM auf Timer 2 läuft nicht.


von Jan K. (jan_k)


Lesenswert?

Hi Leute,

bin etwas verwirrt, ich möchte einen einfachen PWM Ausgang mit Timer 2 
am Port PA1 auf einem STM32F103TB VFQFPN36 realisieren. Laut Datenblatt 
ist TIM2 _CH2 auf PA1 gemappt.
Problem: Am Ausgang tut sich nix.

Ich stelle jetzt nur die gekürzten Versionen der Timer und GPIO Inits 
rein, vielleicht fällt direkt etwas auf. Sonst mache ich eine 
abgespeckte kompilierbare Version.

Der Timer1 funktioniert wie gewünscht, ebenso springt der Controller in 
die ISR vom Timer 2.
1
/* ... header .... */
2
3
4
// masks for setting GPIO bits
5
#define OUT_PP_MASK     ((uint32_t)( (0x01 << 1 | 0x01) | 0x00 << 2) )
6
#define IN_ANALOG_MASK    ((uint32_t)(0x00 | 0x00 << 2) )
7
#define IN_FLOAT_MASK      ((uint32_t)(0x00 | 0x01 << 2) )
8
#define OUT_ALT_PP_MASK    ((uint32_t)( ( 0x01 << 1 | 0x01 ) | ((0x01 << 1 | 0x00) << 2) ) )
9
10
#define CORE_CLOCK ((uint32_t) 64000000)
11
12
13
void PCBA_Configuration( void ) // wird vor dem main loop aufgerufen
14
{
15
  ConfigureGPIO();
16
  ConfigureTimer();
17
  ConfigurePWM();
18
}
19
20
void ConfigureGPIO( void )
21
{
22
  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // clock port a
23
  RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // clock port b
24
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // enable alternative function clock
25
26
  GPIOA->CRL = ( GPIOA->CRL & 0x00000000 )  // each half byte for mode and config for each Port. 0x00 = reset state there. here: alter every port
27
               | ( IN_ANALOG_MASK << 4 * 0 | OUT_ALT_PP_MASK << 4 * 1 | OUT_ALT_PP_MASK << 4 * 2 | IN_FLOAT_MASK << 4 * 3
28
                   | IN_ANALOG_MASK << 4 * 4 | IN_ANALOG_MASK << 4 * 5 | OUT_PP_MASK << 4 * 6 | OUT_PP_MASK << 4 * 7 );
29
30
  GPIOB->CRL = ( GPIOB->CRL & 0x00FFFFF0 )// only alter pb0, pb6, pb7
31
               | ( OUT_PP_MASK << 4 * 0 | OUT_ALT_PP_MASK << 4 * 6 | IN_FLOAT_MASK << 4 * 7 ) ;
32
33
  // debug pins: pa2, pa3
34
  GPIOA->CRL = ( GPIOA->CRL & 0xFFFF00FF )   //
35
               | ( OUT_PP_MASK << 4 * 2 | OUT_PP_MASK << 4 * 3 ) ;
36
  //GPIOA->BRR = GPIO_Pin_2 | GPIO_Pin_3;
37
38
  AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1; // trace on
39
}
40
41
42
void ConfigurePWM( void )
43
{
44
  // output pins are defined in ConfigureGPIO!
45
46
  /* -----------------------------------------------------------------------
47
    Time base configuration
48
    TIM2CLK = APB1clk = CORE_CLOCK/2 = 32MHz usually, TIM2 counter clock frequency = TIM2CLK/(PSC + 1) = 100Hz => APB1ck / (TimSollClock*ARR) - 1 = PSC
49
    TIM2 ARR Register; TIM1 Frequency = TIM1 counter clock frequency/(ARR+1) = x kHz.
50
    TIM2 Frequency = 100 Hz.
51
    TIM2 Channel2 duty cycle = (TIM2_CCR2/ TIM2_ARR) * 100 = 50%
52
  ----------------------------------------------------------------------- */
53
54
  #define ARR_VAL ((uint16_t)4000)
55
  #define PWM_FREQ ((uint16_t)100)
56
57
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;       // enable clock for TIM2
58
59
  TIM2->PSC = ( uint16_t )( ( CORE_CLOCK / ( 2 * PWM_FREQ * ARR_VAL ) ) - ( uint32_t )1 );   // 800 kHz counter @ 32 MHz
60
  TIM2->ARR = ARR_VAL - 1;
61
62
  TIM2->CCR2  = ARR_VAL / 2;                                            // set channel 2 duty cycle
63
  TIM2->CCMR1 = TIM_CCMR1_OC2M | TIM_CCMR1_OC2PE;         // set channel 2 PWM mode 2, pre load enabled.
64
65
  TIM2->CCER = TIM_CCER_CC2E;    // enable capture and compare, active high
66
  TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;            // downcounter, arr preload active, only over/underflow generate interrupt
67
  TIM2->DIER = TIM_DIER_UIE;                          // Enable Update event interrupt
68
  NVIC_SetPriority( TIM2_IRQn, 0 );                                               // set interrupt priority TIM2
69
  NVIC_EnableIRQ( TIM2_IRQn );                                                        // enable TIM2 interrupts
70
71
  TIM2->EGR |= TIM_EGR_UG; // generate update event
72
  TIM2->CR1 |= TIM_CR1_CEN; // start
73
}
74
75
void SetPWMOut( float fValue )
76
{
77
  float dc, ccr;
78
  dc = .028125 * fValue + .5; // 95% = +16mm, 5% = -16mm, 50% = 0mm
79
  ccr = dc * ARR_VAL;
80
  TIM2->CCR2 = ( uint16_t )ccr;
81
}
82
83
void TIM2_IRQHandler( void )
84
{
85
  if ( TIM2->SR & 0x01 )
86
  {
87
    TIM2->SR &= ~TIM_IT_Update;
88
  }
89
}
90
91
void ConfigureTimer( void )
92
{
93
  RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;                     // enable clock for TIM1
94
  /* -----------------------------------------------------------------------
95
    Time base configuration
96
    TIM1CLK = APB2 clock = 64 MHz,  TIM1 counter clock frequency = TIM1CLK/(PSC + 1) = 20 kHz => APB2ck / TimSollClock*ARR - 1 = PSC
97
    TIM1 ARR Register = 4 => TIM1 Frequency = TIM1 counter clock frequency/(ARR+1) = 5 kHz.
98
  ----------------------------------------------------------------------- */
99
  TIM1->PSC = CORE_CLOCK / 20e3 - 1;                             // set prescaler
100
  TIM1->ARR = 4 - 1;                                  // set auto-reload
101
102
  TIM1->CCR1  = 0x0000;                           //
103
  TIM1->CCR2  = 0x7D00;                           //
104
  TIM1->CCR3  = 0x0000;                           //
105
  TIM1->CCR4  = 0x0000;                           //
106
  TIM1->CCMR1 = 0x0100;                           //
107
  TIM1->CCMR2 = 0x0000;                           //
108
  TIM1->CCER  = 0x0000;                           // set capture/compare enable register
109
  TIM1->SMCR  = 0x0000;                           // set slave mode control register
110
111
  TIM1->CR1 = 0x0000 & 0xFFFE;                    // set command register 1
112
  TIM1->CR2 = 0x0010;                             // set command register 2
113
114
  TIM1->DIER = 0x0001;                            // enable interrupt
115
116
  NVIC_EnableIRQ( TIM1_UP_IRQn );
117
  NVIC_SetPriority( TIM1_UP_IRQn, 1 );
118
}

Vielen Dank fürs drüber gucken!

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
Noch kein Account? Hier anmelden.