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
|