Forum: Mikrocontroller und Digitale Elektronik SAM4S4C PWM Frequenz


von Fabian K. (farbenjan)


Lesenswert?

Hallo,
ich bin langsam am verzweifeln. Ich habe einen SAM4S4C und bekomme als 
max. PWM Frequenz immer nur CPU Takt/100. Im Datenblatt steht aber dass 
die PWM mit dem CPU Takt läuft. Hat jemand von euch Erfahrung mit dem 
Prozessor? Der PMC ist richtig konfiguriert und die im Datenblatt 
angeben Testmethode mit dem auslesen des MAINFRDY Werts ergibt auch 
120Mhz.

gruß Fabian

von Jim M. (turboj)


Lesenswert?

Zeig doch mal den Code als Anhang. Meine Glaskugel ist in Reparatur.

von Fabian K. (farbenjan)


Lesenswert?

Hier das sollte alles sein was damit in Verbindung steht. Danke
1
Main.c mit einer PWM
2
_______________________________________________________________________________________________
3
4
  #include "asf.h"
5
  #include "conf_board.h"
6
  #include "conf_clock.h"
7
8
9
  #define PWM_DRIVE_FREQUENCY        400000
10
  #define PWM_DRIVE_PERIOD_VALUE      100
11
  #define PWM_DRIVE_DUTY_VALUE      50
12
  #define PWM_DRIVE_CHANNEL        PWM_CHANNEL_0
13
  #define PWM_CLK_SRC          PWM_CMR_CPRE_MCK  
14
  pwm_channel_t pwm_drive;
15
16
17
  int main (void)
18
  {
19
    board_init();
20
    sysclk_init();
21
    pmc_enable_periph_clk(ID_PIOC);
22
    pmc_enable_periph_clk(ID_PWM);
23
    pio_set_output(PIOC,PIO_PC11, LOW, DISABLE, ENABLE);
24
    
25
    
26
    pio_set_peripheral(PIOA,PIO_PERIPH_A,PIO_PA0);    
27
    pwm_channel_disable(PWM, PWM_DRIVE_CHANNEL);
28
    
29
    pwm_clock_t clock_setting = {                    
30
      .ul_clka = PWM_DRIVE_FREQUENCY * PWM_DRIVE_PERIOD_VALUE,
31
      .ul_clkb = 0,
32
      .ul_mck =  sysclk_get_cpu_hz()
33
    };
34
    pwm_init(PWM, &clock_setting);
35
    
36
    pwm_drive.alignment = PWM_ALIGN_LEFT;
37
    pwm_drive.polarity = PWM_LOW;
38
    pwm_drive.ul_prescaler = PWM_CLK_SRC; 
39
    pwm_drive.ul_period = PWM_DRIVE_PERIOD_VALUE;
40
    pwm_drive.ul_duty = PWM_DRIVE_DUTY_VALUE;
41
    pwm_drive.channel = PWM_DRIVE_CHANNEL;
42
    pwm_channel_init(PWM, &pwm_drive);
43
    pwm_channel_enable(PWM, PWM_DRIVE_CHANNEL);
44
    
45
    while (1) {
46
    }
47
    
48
    
49
  }
50
51
  
52
Der clock_conf Header
53
_______________________________________________________________________________________________
54
55
#ifndef CONF_CLOCK_H_INCLUDED
56
#define CONF_CLOCK_H_INCLUDED
57
58
// ===== System Clock (MCK) Source Options
59
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_RC
60
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_XTAL
61
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_BYPASS
62
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_4M_RC
63
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_8M_RC
64
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_12M_RC
65
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_XTAL
66
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_BYPASS
67
#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLLACK
68
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLLBCK
69
70
// ===== System Clock (MCK) Prescaler Options   (Fmck = Fsys / (SYSCLK_PRES))
71
#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_1
72
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_2
73
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_4
74
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_8
75
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_16
76
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_32
77
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_64
78
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_3
79
80
// ===== PLL0 (A) Options   (Fpll = (Fclk * PLL_mul) / PLL_div)
81
// Use mul and div effective values here.
82
#define CONFIG_PLL0_SOURCE          PLL_SRC_MAINCK_XTAL
83
#define CONFIG_PLL0_MUL             6
84
#define CONFIG_PLL0_DIV             1
85
#endif /* CONF_CLOCK_H_INCLUDED */
86
87
88
Und der Clock Treiber
89
_______________________________________________________________________________________________
90
91
#include <sysclk.h>
92
93
/// @cond 0
94
/**INDENT-OFF**/
95
#ifdef __cplusplus
96
extern "C" {
97
#endif
98
/**INDENT-ON**/
99
/// @endcond
100
101
/**
102
 * \weakgroup sysclk_group
103
 * @{
104
 */
105
106
#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
107
/**
108
 * \brief boolean signalling that the sysclk_init is done.
109
 */
110
uint32_t sysclk_initialized = 0;
111
#endif
112
113
/**
114
 * \brief Set system clock prescaler configuration
115
 *
116
 * This function will change the system clock prescaler configuration to
117
 * match the parameters.
118
 *
119
 * \note The parameters to this function are device-specific.
120
 *
121
 * \param cpu_shift The CPU clock will be divided by \f$2^{mck\_pres}\f$
122
 */
123
void sysclk_set_prescalers(uint32_t ul_pres)
124
{
125
  pmc_mck_set_prescaler(ul_pres);
126
  SystemCoreClockUpdate();
127
}
128
129
/**
130
 * \brief Change the source of the main system clock.
131
 *
132
 * \param src The new system clock source. Must be one of the constants
133
 * from the <em>System Clock Sources</em> section.
134
 */
135
void sysclk_set_source(uint32_t ul_src)
136
{
137
  switch (ul_src) {
138
  case SYSCLK_SRC_SLCK_RC:
139
  case SYSCLK_SRC_SLCK_XTAL:
140
  case SYSCLK_SRC_SLCK_BYPASS:
141
    pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK);
142
    break;
143
144
  case SYSCLK_SRC_MAINCK_4M_RC:
145
  case SYSCLK_SRC_MAINCK_8M_RC:
146
  case SYSCLK_SRC_MAINCK_12M_RC:
147
  case SYSCLK_SRC_MAINCK_XTAL:
148
  case SYSCLK_SRC_MAINCK_BYPASS:
149
    pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK);
150
    break;
151
152
  case SYSCLK_SRC_PLLACK:
153
    pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK);
154
    break;
155
156
  case SYSCLK_SRC_PLLBCK:
157
    pmc_mck_set_source(PMC_MCKR_CSS_PLLB_CLK);
158
    break;
159
  }
160
161
  SystemCoreClockUpdate();
162
}
163
164
#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__)
165
/**
166
 * \brief Enable USB clock.
167
 *
168
 * \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1
169
 * is hidden in this implementation. Use div as div effective value.
170
 *
171
 * \param pll_id Source of the USB clock.
172
 * \param div Actual clock divisor. Must be superior to 0.
173
 */
174
void sysclk_enable_usb(void)
175
{
176
  Assert(CONFIG_USBCLK_DIV > 0);
177
178
#ifdef CONFIG_PLL0_SOURCE
179
  if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL0) {
180
    struct pll_config pllcfg;
181
182
    pll_enable_source(CONFIG_PLL0_SOURCE);
183
    pll_config_defaults(&pllcfg, 0);
184
    pll_enable(&pllcfg, 0);
185
    pll_wait_for_lock(0);
186
    pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1);
187
    pmc_enable_udpck();
188
    return;
189
  }
190
#endif
191
192
#ifdef CONFIG_PLL1_SOURCE
193
  if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL1) {
194
    struct pll_config pllcfg;
195
196
    pll_enable_source(CONFIG_PLL1_SOURCE);
197
    pll_config_defaults(&pllcfg, 1);
198
    pll_enable(&pllcfg, 1);
199
    pll_wait_for_lock(1);
200
    pmc_switch_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1);
201
    pmc_enable_udpck();
202
    return;
203
  }
204
#endif
205
}
206
207
/**
208
 * \brief Disable the USB clock.
209
 *
210
 * \note This implementation does not switch off the PLL, it just turns off the USB clock.
211
 */
212
void sysclk_disable_usb(void)
213
{
214
  pmc_disable_udpck();
215
}
216
#endif // CONFIG_USBCLK_SOURCE
217
218
void sysclk_init(void)
219
{
220
  /* Set a flash wait state depending on the new cpu frequency */
221
  system_init_flash(sysclk_get_cpu_hz());
222
223
  /* Config system clock setting */
224
  if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) {
225
    osc_enable(OSC_SLCK_32K_RC);
226
    osc_wait_ready(OSC_SLCK_32K_RC);
227
    pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
228
  }
229
230
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
231
    osc_enable(OSC_SLCK_32K_XTAL);
232
    osc_wait_ready(OSC_SLCK_32K_XTAL);
233
    pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
234
  }
235
236
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) {
237
    osc_enable(OSC_SLCK_32K_BYPASS);
238
    osc_wait_ready(OSC_SLCK_32K_BYPASS);
239
    pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
240
  }
241
242
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) {
243
    /* Already running from SYSCLK_SRC_MAINCK_4M_RC */
244
  }
245
246
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) {
247
    osc_enable(OSC_MAINCK_8M_RC);
248
    osc_wait_ready(OSC_MAINCK_8M_RC);
249
    pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
250
  }
251
252
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) {
253
    osc_enable(OSC_MAINCK_12M_RC);
254
    osc_wait_ready(OSC_MAINCK_12M_RC);
255
    pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
256
  }
257
258
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) {
259
    osc_enable(OSC_MAINCK_XTAL);
260
    osc_wait_ready(OSC_MAINCK_XTAL);
261
    pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
262
  }
263
264
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) {
265
    osc_enable(OSC_MAINCK_BYPASS);
266
    osc_wait_ready(OSC_MAINCK_BYPASS);
267
    pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
268
  }
269
270
#ifdef CONFIG_PLL0_SOURCE
271
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) {
272
    struct pll_config pllcfg;
273
274
    pll_enable_source(CONFIG_PLL0_SOURCE);
275
    pll_config_defaults(&pllcfg, 0);
276
    pll_enable(&pllcfg, 0);
277
    pll_wait_for_lock(0);
278
    pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);
279
  }
280
#endif
281
282
#ifdef CONFIG_PLL1_SOURCE
283
  else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLBCK) {
284
    struct pll_config pllcfg;
285
286
    pll_enable_source(CONFIG_PLL1_SOURCE);
287
    pll_config_defaults(&pllcfg, 1);
288
    pll_enable(&pllcfg, 1);
289
    pll_wait_for_lock(1);
290
    pmc_switch_mck_to_pllbck(CONFIG_SYSCLK_PRES);
291
  }
292
#endif
293
294
  /* Update the SystemFrequency variable */
295
  SystemCoreClockUpdate();
296
297
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
298
  /* Signal that the internal frequencies are setup */
299
  sysclk_initialized = 1;
300
#endif
301
}
302
303
//! @}
304
305
/// @cond 0
306
/**INDENT-OFF**/
307
#ifdef __cplusplus
308
}
309
#endif
310
/**INDENT-ON**/
311
/// @endcond

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.