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