Forum: Mikrocontroller und Digitale Elektronik STM32F4 TIM1 PWM funktioniert nicht bei aktivem USART1&6


von Ruphy .. (ruphy)


Lesenswert?

Hallo liebe µPC Community,

ich bastel gerade an einem Projekt in dem ich über USART1 eine
Temperatur auslese und über USART6 die RS232 Schnittstelle zum PC
herstelle.
Über ein Protokoll kann ich von meinem Rechner ein PWM Signal auf dem 
µpc erzeugen(TIM1 als PWM). Das bedeutet, ich beschreibe das CCR1 
register. Außerdem wird über RS232 Byteweise eine Temperatur zum Rechner 
übertragen (im Burst Modus).

Nun zu meinem Problem:
Wenn ich die einzelnen Komponente laufen lasse (PWM erzeugen oder
Temperatur auf PC anzeigen lassen) läuft alles super und ohne Probleme.
Sobald ich beide Projekte zusammenfüge, funktioniert die PWM nicht mehr.
Das bedeutet: im Debugging Modus kann ich nachweisen, dass das CCR1
Register beschrieben wird, aber der Timer1 läuft auf unerklärlicherweise
nicht. Sobald ich eines der die USART6 (Temperaturausgabe auf PC) NICHT
initalisiere funktioniert die PWM.

Ich hoffe ihr versteht mein Problem? Kurz: der TIM1 funktioniert nicht!!
RS232 (USART6) und Temperatur lesen(USART1) funktioniert einwandfrei.

Kann jemand Helfen?
Danke.

Schöne Grüßeee

von Ruphy .. (ruphy)


Lesenswert?

Problem gelöst:

erst die USART1 und USART6 initialisieren und dann erst den Timer 
initialisieren!

bsp:
FALSCH
  TIM1_PWM_init();
  init_USART6(9600);  // RS232 PWM Empfang
  init_USART1(9600);  // USART for Temp Sensor


RICHTIG
  init_USART6(9600);  // RS232 PWM Empfang
  init_USART1(9600);  // USART for Temp Sensor
  TIM1_PWM_init();


Kann mir jemand erklären warum das so ist?

von Rainer M. (excogitator)


Lesenswert?

Poste doch mal den Code deiner drei Init-Funktionen, dann kann man evtl. 
mehr sagen.

Gruß
Rainer

von Ruphy .. (ruphy)


Lesenswert?

Den Code habe ich aus dem Internet und dann an meine Bedürfnisse 
angepasst.

1
/ Temperatur USART Empfang
2
void init_USART1(uint32_t baudrate)
3
{
4
5
  /* This is a concept that has to do with the libraries provided by ST
6
   * to make development easier the have made up something similar to
7
   * classes, called TypeDefs, which actually just define the common
8
   * parameters that every peripheral needs to work correctly
9
   *
10
   * They make our life easier because we don't have to mess around with
11
   * the low level stuff of setting bits in the correct registers
12
   */
13
  GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX
14
  USART_InitTypeDef USART_InitStruct; // this is for the USART6 initilization
15
  NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)
16
17
  /* enable APB2 peripheral clock for USART6
18
   * note that only USART6 and USART6 are connected to APB2
19
   * the other USARTs are connected to APB1
20
   */
21
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
22
23
  /* enable the peripheral clock for the pins used by
24
   * USART1, PB6 for TX and PB7 for RX
25
   */
26
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
27
28
  /* This sequence sets up the TX and RX pins
29
   * so they work correctly with the USART6 peripheral
30
   */
31
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used
32
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;       // the pins are configured as alternate function so the USART peripheral has access to them
33
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    // this defines the IO speed and has nothing to do with the baudrate!
34
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;      // this defines the output type as push pull mode (as opposed to open drain)
35
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;      // this activates the pullup resistors on the IO pins
36
  GPIO_Init(GPIOB, &GPIO_InitStruct);          // now all the values are passed to the GPIO_Init() function which sets the GPIO registers
37
38
  /* The RX and TX pins are now connected to their AF
39
   * so that the USART6 can take over control of the
40
   * pins
41
   */
42
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);    // Enable Pin 6
43
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
44
45
  /* Now the USART_InitStruct is used to define the
46
   * properties of USART1
47
   */
48
  USART_InitStruct.USART_BaudRate = baudrate;        // the baudrate is set to the value we passed into this init function
49
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
50
  USART_InitStruct.USART_StopBits = USART_StopBits_1;    // we want 1 stop bit (standard)
51
  USART_InitStruct.USART_Parity = USART_Parity_No;    // we don't want a parity bit (standard)
52
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
53
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // we want to enable the transmitter and the receiver
54
  USART_Init(USART1, &USART_InitStruct);          // again all the properties are passed to the USART_Init function which takes care of all the bit setting
55
56
57
  /* Here the USART6 receive interrupt is enabled
58
   * and the interrupt controller is configured
59
   * to jump to the USART6_IRQHandler() function
60
   * if the USART1 receive interrupt occurs
61
   */
62
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);       // enable the USART1 receive interrupt
63
64
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;     // we want to configure the USART6 interrupts
65
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// this sets the priority group of the USART6 interrupts
66
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;     // this sets the subpriority inside the group
67
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       // the USART6 interrupts are globally enabled
68
  NVIC_Init(&NVIC_InitStructure);               // the properties are passed to the NVIC_Init function which takes care of the low level stuff
69
70
  // finally this enables the complete USART6 peripheral
71
  USART_Cmd(USART1, ENABLE);
72
}
73
74
// RS232 USART Empfang
75
void init_USART6(uint32_t baudrate)
76
{
77
78
  /* This is a concept that has to do with the libraries provided by ST
79
   * to make development easier the have made up something similar to
80
   * classes, called TypeDefs, which actually just define the common
81
   * parameters that every peripheral needs to work correctly
82
   *
83
   * They make our life easier because we don't have to mess around with
84
   * the low level stuff of setting bits in the correct registers
85
   */
86
  GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX
87
  USART_InitTypeDef USART_InitStruct; // this is for the USART6 initilization
88
  NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)
89
90
  /* enable APB2 peripheral clock for USART6
91
   * note that only USART6 and USART6 are connected to APB2
92
   * the other USARTs are connected to APB1
93
   */
94
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
95
96
  /* enable the peripheral clock for the pins used by
97
   * USART6, PB6 for TX and PB7 for RX
98
   */
99
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
100
101
  /* This sequence sets up the TX and RX pins
102
   * so they work correctly with the USART6 peripheral
103
   */
104
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used
105
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;       // the pins are configured as alternate function so the USART peripheral has access to them
106
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    // this defines the IO speed and has nothing to do with the baudrate!
107
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;      // this defines the output type as push pull mode (as opposed to open drain)
108
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;      // this activates the pullup resistors on the IO pins
109
  GPIO_Init(GPIOC, &GPIO_InitStruct);          // now all the values are passed to the GPIO_Init() function which sets the GPIO registers
110
111
  /* The RX and TX pins are now connected to their AF
112
   * so that the USART6 can take over control of the
113
   * pins
114
   */
115
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); //
116
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
117
118
  /* Now the USART_InitStruct is used to define the
119
   * properties of USART6
120
   */
121
  USART_InitStruct.USART_BaudRate = baudrate;        // the baudrate is set to the value we passed into this init function
122
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
123
  USART_InitStruct.USART_StopBits = USART_StopBits_1;    // we want 1 stop bit (standard)
124
  USART_InitStruct.USART_Parity = USART_Parity_No;    // we don't want a parity bit (standard)
125
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
126
  USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
127
  USART_Init(USART6, &USART_InitStruct);          // again all the properties are passed to the USART_Init function which takes care of all the bit setting
128
129
130
  /* Here the USART6 receive interrupt is enabled
131
   * and the interrupt controller is configured
132
   * to jump to the USART6_IRQHandler() function
133
   * if the USART6 receive interrupt occurs
134
   */
135
  USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);       // enable the USART6 receive interrupt
136
137
  NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;     // we want to configure the USART6 interrupts
138
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART6 interrupts
139
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     // this sets the subpriority inside the group
140
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       // the USART6 interrupts are globally enabled
141
  NVIC_Init(&NVIC_InitStructure);               // the properties are passed to the NVIC_Init function which takes care of the low level stuff
142
143
  // finally this enables the complete USART6 peripheral
144
  USART_Cmd(USART6, ENABLE);
145
}
146
147
void TIM1_PWM_init(void)
148
{
149
  // GPIO Config: PA8 als PWM Ausgang: TIM1_CH1
150
  GPIO_InitTypeDef GPIO_InitStructure;
151
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
152
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
153
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
154
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
155
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
156
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
157
  GPIO_Init(GPIOA, &GPIO_InitStructure);
158
  // Connect TIM1 pins to AF
159
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1);
160
161
162
  //timer 1 is clocked by APB2 at 84MHz, prescale by 42000 to get 2kHz clock
163
  //use a period of 100 cycles to get 0..100% granularity and 20Hz frequency
164
  TIM_TimeBaseInitTypeDef TIM_TimebaseStructure;
165
  TIM_OCInitTypeDef TIM_OCStructure;
166
167
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
168
169
  TIM_TimeBaseStructInit(&TIM_TimebaseStructure);
170
  TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // Time Base initialisieren
171
  TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
172
  TIM_TimebaseStructure.TIM_Prescaler= 840-1; // 84MHz / 840 = 100 kHz nach Prescaler
173
  TIM_TimebaseStructure.TIM_Period= 1000-1;   //  100 khz / 1000 = 1 Hz -> endgültige Updaterate des Timers
174
//  TIM_TimebaseStructure.TIM_Period= 42000-1;  //  84 khz /42k = 2 Hz
175
  TIM_TimeBaseInit(TIM1, &TIM_TimebaseStructure);
176
177
178
  //Output Compare Modus Config Channel1
179
  TIM_OCStructure.TIM_OCMode=TIM_OCMode_PWM1;
180
  TIM_OCStructure.TIM_OutputState=TIM_OutputState_Enable;
181
  TIM_OCStructure.TIM_Pulse=CCR1_Val;
182
  TIM_OCStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
183
  TIM_OC1Init(TIM1, &TIM_OCStructure);            // TIM_OC1Init => Channel 1 aktivieren
184
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
185
186
187
188
  TIM_ARRPreloadConfig(TIM1, ENABLE);
189
    //required for timers 1 or 8
190
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
191
192
  TIM_Cmd(TIM1,ENABLE); // timer starts
193
}

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.