STM32L562的系统时钟有4种来源:HSE、HSI16、MSI、PLL
HSE:高速外部时钟,可选用4~48MHz的晶振使用,支持PLL
HSI16:高速内部时钟,16MHz的内部震荡器,支持PLL
MSI:多频率内部时钟,可产生从100KHz到48MHz的12种频率,支持PLL
PLL:通过与HSE、HSI16、MSI结合使用,可以配置最高110MHz的频率
另外还有个HSI48,可以为USB、SDMMC、RNG外设提供48MHz的时钟
对于这块板子来说HSE的位置是留空的没法使用外部晶振,工程默认配置的是MSI
MSI的频率可以在STM32CubeMX中通过这个下拉框进行修改
低速时钟部分和其他的大部分芯片一样,可以由外部32.768KHz的晶振(LSE)或内部32KHz的低速振荡器(LSI)提供,用来支持RTC工作
定时器是一个非常重要的功能模块,用于处理定时、计数和事件触发等任务。在单片机开发中,或多或少都会用到定时器,定时器可以在应用程序中产生周期性中断,常用于精确的时间延迟、事件计数等场合。STM32L562的定时器资源很丰富,拥有2个高级定时器、最多9个通用定时器、2个基础定时器和2个低功耗定时器
接下来使用Timer8实现一个触发周期为1s的定时器,在定时器的中断中翻转LED的状态,使2个LED交替闪烁
打开STM32CubeMX选中TIM8,时钟源选择内部时钟,配置好预分频系数和重载值
切换到中断设置标签开启Update中断
生成的代码并没有开启定时器和Update中断,需要手动添加以下代码
LL_TIM_EnableIT_UPDATE(TIM8);
LL_TIM_EnableCounter(TIM8);
在中断函数中切换LED状态
void Tim8UpdateInt(void)
{
LL_GPIO_TogglePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin);
LL_GPIO_TogglePin(LED_RED_GPIO_Port,LED_RED_Pin);
}
void TIM8_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_UP_IRQn 0 */
if(LL_TIM_IsActiveFlag_UPDATE(TIM8))
{
LL_TIM_ClearFlag_UPDATE(TIM8);
Tim8UpdateInt();
}
/* USER CODE END TIM8_UP_IRQn 0 */
/* USER CODE BEGIN TIM8_UP_IRQn 1 */
/* USER CODE END TIM8_UP_IRQn 1 */
}
运行效果如图
除了运行普通的定时任务外,还可以通过定时器输出PWM,通过调节占空比可以控制输出的电流大小,接下来使用PWM控制这个RGB的LED模块实现彩色渐变效果
使用PA0 PA1 PC6这三个还没有被使用的IO,可以通过背面的Arduino接口来连接
三个IO对应的定时器通道如下
PA0——TIM2CH1
PA1——TIM2CH2
PC6——TIM3CH1
打开STM32CubeMX配置IO为定时器通道输出,并对定时器参数进行设置,这个LED模块是共阳极的所以设置有效电平为低电平
和前面一样需要手动开启定时器和PWM输出
LL_TIM_EnableCounter(TIM2);
LL_TIM_CC_EnableChannel(TIM2,LL_TIM_CHANNEL_CH1);
LL_TIM_CC_EnableChannel(TIM2,LL_TIM_CHANNEL_CH2);
LL_TIM_EnableCounter(TIM3);
LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH1);
实现颜色渐变效果
uint16_t led_r = 1000;
uint16_t led_g = 0;
uint16_t led_b = 0;
uint8_t led_rgb_step = 0;
void AppSetRGB(uint16_t r,uint16_t g,uint16_t b)
{
if(r > 1000)
r = 1000;
if(g > 1000)
g = 1000;
if(b > 1000)
b = 1000;
LL_TIM_OC_SetCompareCH1(TIM2,r);
LL_TIM_OC_SetCompareCH2(TIM2,g);
LL_TIM_OC_SetCompareCH1(TIM3,b);
}
void AppLEDShowColors()
{
switch(led_rgb_step)
{
case 0:
if(led_r > 0)
{
led_g += 1;
led_r -= 1;
}
if(led_r == 0)
led_rgb_step = 1;
break;
case 1:
if(led_g > 0)
{
led_b += 1;
led_g -= 1;
}
if(led_g == 0)
led_rgb_step = 2;
break;
case 2:
if(led_b > 0)
{
led_r += 1;
led_b -= 1;
}
if(led_b == 0)
led_rgb_step = 0;
break;
default:
break;
}
AppSetRGB(led_r,led_g,led_b);
}
void AppUserLoop(void)
{
AppLEDShowColors();
LL_mDelay(1);
}
最终运行效果如下
|