由于低功耗的要求,需要把SAM4S芯片的主频从120M降低到24M工作,这样工作功率可以降低到原来的1/2,但是主频一旦变化,就需要重新设置串口波特率了。
首先是降低系统工作时钟:
- #define PLL_DEFAULT_MUL 7
- #define PLL_DEFALUT_DIV 1
- #define MCK_DEFAULT_DIV PMC_MCKR_PRES_CLK_4
- /**
- * @brief Set default clock(MCK = 24MHz).
- * @param None
- * @retval None
- */
- void set_default_working_clock(void)
- {
- // Switch MCK to slow clock
- pmc_switch_mck_to_sclk(PMC_MCKR_PRES_CLK_1);
- // Switch mainck to external xtal
- pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US);
- /************************************************************************/
- /* Configure PLL and switch clock
- /* MCK = XTAL*(PLL_DEFALUT_MUL+1) / PLL_DEFAULT_DIV / MCK_DEFAULT_DIV
- /* = 120MHz
- /************************************************************************/
- pmc_enable_pllack(PLL_DEFAULT_MUL, PLL_COUNT, PLL_DEFALUT_DIV);
- pmc_switch_mck_to_pllack(MCK_DEFAULT_DIV);
- // Disable unused clock to save power
- pmc_osc_disable_fastrc();
- // Save current clock
- g_ul_current_mck = 24000000; // 24MHz
- }
执行完后,系统工作时钟就降低到了24M,但是使用函数sysclk_get_cpu_hz()查询,输出的时钟频率依然是120M。这是因为系统时钟没变,只是工作频率变了。同时受影响的有delay函数,延时时间全部变为原来的5倍;还有SysTick_Handler(),中断周期也变为原来的5倍,这个还好处理,把中断频率改为之前的5倍就行了,但是延时这个我还没有调试出来,只能在延时时间上缩减了。
然后重设串口波特率,由于我用了两个串口,两个需要分别重设才行。
UART1:
- /**
- * @brief Reconfigure UART console for changed MCK and baudrate.
- * @param None
- * @retval None
- */
- void reconfigure_console(uint32_t ul_mck, uint32_t ul_baudrate)
- {
- const sam_usart_opt_t uart_console_setting =
- { ul_mck, ul_baudrate, UART_MR_PAR_NO };
- // Configure PMC
- pmc_enable_periph_clk(CONSOLE_UART_ID);
- // Configure PIO
- pio_configure_pin_group(PINS_UART1_PIO, PINS_UART1, PINS_UART1_FLAGS);
- // Configure UART
- uart_init(CONSOLE_UART, &uart_console_setting);
- }
这里传入的参数ul_mck=24M,ul_baudrate自定义。
USART0:
- /**
- * @brief Reconfigure USART console for changed MCK and baudrate.
- * @param None
- * @retval None
- */
- void reconfigure_console_usart(uint32_t ul_mck, uint32_t ul_baudrate)
- {
- const sam_usart_opt_t uart_console_setting =
- { ul_mck, ul_baudrate, UART_MR_PAR_NO };
- // Configure PMC
- pmc_enable_periph_clk(CONSOLE_USART_ID);
- // Configure PIO
- gpio_configure_pin(PIN_USART0_RXD_IDX, PIN_USART0_RXD_FLAGS);
- gpio_configure_pin(PIN_USART0_TXD_IDX, PIN_USART0_TXD_FLAGS);
- // Configure UART
- //uart_init(CONF_USART, &uart_console_setting);
- //usart_init_hw_handshaking(CONSOLE_USART, &uart_console_setting, ul_mck);
- usart_set_async_baudrate(CONSOLE_USART, ul_baudrate, ul_mck);
- }
之前我照搬UART的重设函数,结果发现两个串口都不能正常工作,直接到asf头文件里寻找可以用的函数,发现有专门的重设同步串口波特率的函数usart_set_async_baudrate(),把参数带入就可以了。