完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
来源 灵动MM32 呼吸灯,就是指电子产品上的LED灯的亮度随着时间由暗到亮逐渐增强,再由亮到暗逐渐衰减,有节奏感地一起一伏,就像是在呼吸一样,因而被广泛应用于手机、电脑等电子设备的指示灯中。在使用MCU开发相关的应用产品中也可以加入呼吸灯功能,增强用户的体验感,在本实验中将介绍如何使用MM32L0系列产品芯片做呼吸灯功能。 在平时应用中可以知道,MCU的GPIO输出高低电平变化可以实现LED灯的亮、灭两个过程,如果GPIO的电平一直维持高电平或者低电平,LED灯就处于长亮或长灭的状态,呼吸灯就是通过较高频率的电平变化来实现亮灭的切换,由于人的视觉暂留效应,肉眼无法迅速捕捉快速亮灭变化的过程,所以在视觉中一直出现一直亮或者灭的状态,通过调整占空比可以控制LED灯的亮度,给人视觉上一种灯光由暗到亮逐渐增强,然后又由亮到暗逐渐衰减。 正常的成年人的吸气呼气时间整个过程持续大约3秒时间,即吸气时间(LED灯亮度逐渐变亮)时间为1.5S,吸、呼气时间(LED灯亮度逐渐变暗)时间为1.5S。 亮度随着时间逐渐变强再衰减,可以用两种算数方式实现:半周期的正弦函数曲线和指数上升曲线及对称的下降沿曲线。 指数方式曲线图 要控制 LED 灯达到呼吸灯的效果,实际上就是要控制 LED 灯的亮度拟合呼吸特性曲线,在本次实验中,将采用指数上升曲线及对称的下降沿曲线方式,用户如果对正弦方式感兴趣也可以进行尝试。在本次实验中,我们使用MM32L0xx输出较高频率的PWM信号,通过调制信号的占空比,控制LED灯的亮度。 生成指数方式的曲线图主要因素: tiMPeriod:定时器的计数周期,它的值必须与PWM 表中的极大值相等(应用中赋值需要减1),而 PWM表的极大值决定了控制的分辨率。例如极大值为 10时,PWM 占空比只有10个等级,精确到0.1,当极大值为1000 时,PWM 占空比1000个等级,精确到0.001。在本次实验中设置定时器的计数周期值为255+1,即PWM表中的极大值也是256。 TIM_Prescaler:定时器时钟分频因子,它控制定时器计数器 CNT计数加1所需要的时间,它的值太大会导致输出的单个PWM波周期过长,影响控制的动态特性。如控制LED灯时,该值太大会导致LED灯开关时间变长,闪烁明显。一般来说,该值越小越好。在本次实验中设置定时器时钟分频因子为1757+1,即对时钟1758分频。 PWM 表的点数:PWM表的点数即对拟合曲线的采样点数,即把LED灯的亮度分为0-255个等级,采样点越多,能更好地还原拟合曲线,采样点太少,可能会导致失真。在本次实验中设置PWM 表的点数为40。 Period_class:周期倍数,即 PWM 表中每个元素的循环次数,它影响拟合曲线的周期。 在本次实验中设置设置周期倍数为8。 本次实验程序直接从MM32L073的定时器PWM输出的例程的基础上修改得来,TIM3配置成向上计数,PWM通道输出也被配置成当计数器 CNT 的值小于输出比较寄存CCR1的值时,PWM通道输出低电平,点亮 LED 灯。在函数的最后还使能了定时器中断,每当定时器的一个计数周期完成时,产生中断,配合中断服务函数,即可切换CCR1 比较寄存器的值。 程序配置如下: TIM3初始化配置 //LED亮度等级列表 uint8_t PWM_Wave[] = {1,1,2,2,3,4,6,8,10,14,19,25,33,44,59,80,107,143,191,255,255 ,191,143,107,80,59,44,33,25,19,14,10,8,6,4,3,2,2,1,1}; TIM3的初始化、中断及PWM输出配置: void TIM3_PWM_Init(u16arr,u16 psc) { GPIO_InitTypeDefGPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDefNVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);//使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin= GPIO_Pin_4; //TIM3_CH1 GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); NVIC_InitStructure.NVIC_IRQChannel= TIM3_IRQn; //TIM3中断源 NVIC_InitStructure.NVIC_IRQChannelPriority= 0x01; //设置中断优先级 NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器 TIM_TimeBaseStructure.TIM_Period= arr;//设置自动装载寄存器值 TIM_TimeBaseStructure.TIM_Prescaler=psc; //设置预分频值 TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置时钟分割 TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;//设置计数模式 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //初始化TIM3寄存器 TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode= TIM_OCMode_PWM1; //配置PWM模式 TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable; //输出使能 TIM_OCInitStructure.TIM_Pulse= 0; //设置初始脉冲宽度为0 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//小于CCR1值为低电平 TIM_OC1Init(TIM3,&TIM_OCInitStructure); //初始化TIM3_OC1寄存器 TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //预装载使能 TIM_ARRPreloadConfig(TIM3,ENABLE); //使能 TIM 重载寄存器 ARR TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE); //使能TIM3的更新中断 TIM_Cmd(TIM3,ENABLE);//使能TIM3 } 中断服务函数: voidTIM3_IRQHandler(void) { static uint8_t a =0;//PWM表的成员数,用于PWM查表 static uint8_t b = 0;//计算周期数 if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//判断更新中断标志位 { b++; if(b >= 8) //周期倍数 { TIM3->CCR1 =PWM_Wave [a]; //修改定时器比较寄存器值 a++;//查表指向下一个成员变量 if( a >= 40)//查表查到最后一位,重新指向表头 { a=0; } b=0; //重置周期计数标志 } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } } 主程序: int main(void) { TIM3_PWM_Init(255,1757); while(1) { } } 本次实验配置拟合曲线周期计算: TIMPeriod=255+1; TIM_Prescaler=1757+1; PWM 表的点数(a)=40; Fpwm = 48M /((arr+1)*(psc+1))(单位:Hz) 定时器 update 事件周期,即定时器中断周期:t1= 1/ Fpwm = 9376us 每个 PWM 点的时间:t2= t1*8= 75008us 遍历PWM表的周期时间为:t3=t2*40= 3000320us 通过公式的计算可知本工程的配置可使得输出的拟合曲线周期约等于3秒,符合成年人的吸气呼气时间整个过程持续大约3秒时间。 利用GPIO模拟PWM波形设计呼吸灯功能: void LedOnOff(uint16_tt,uint16_t i) { LED1_ON(); delay_us(i); LED1_OFF(); delay_us(t-i); } int main(void) { int i,j; LED_Init(); TIM3_PWM_Init(255,1757); while(1) { for(i=0;i<100;i+=1){ for(j=0;j<47;j+=1) { LedOnOff(100,i); } } for(i=100;i>0;i--) { for(j=0;j<46;j+=1) { LedOnOff(100,i); } } } } 使用MM32L0系列MCU上述两种方式都可以实现呼吸灯功能,两种方法GPIO分别是PB4和PB5,download到MiniBoard中,可以对比测试两种实现方法的差异性,选择合适的呼吸灯实现方式。 |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
2248个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11665 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5920 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10950 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4571 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4296 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
963浏览 1评论
792浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 23:14 , Processed in 0.603456 second(s), Total 42, Slave 33 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号