学习内容
写blog对个人的作用:将繁琐的知识碎片经过 思考->概括->总结 整合为较为完整独立的知识节点,复习时可快速体会其知识内核,方便建立知识体系。 ——YLAD
pwm驱动不同状态的led
1. pwm接口
周期为16ms,占空比根据ADC采集旋钮电阻分压得到led_level参数;
api参数:led_var指定让8个里面的哪些点亮(1:亮;0:灭),如:0x81就是将L1与L8同时用此pwm波驱动;
/*
原理:
pwm波图解:-表示1ms时间段,|表示根据led_level设置的占空比(题目要求平分4个等级)
如下是led_pwm_time在定时器中自增的时间标志(最大到16ms),|划分了4个等级(占空比)
led_pwm_time:----|----|----|----|(16ms)
参数:
led_pwm_time:中断中设置的pwm时间线0-16ms无限循环
led_level:通过ad旋钮调节占空比
api重点1:hc4设置需要的位时用到的是|与&,不会影响到其他位,因此要记得将其他位熄灭,具体操作只在改变led显示状态时执行1次就行,因此将熄灭操作放在void taskled();函数中即可
*/
void pwm_led(u8 led_var,u8 led_pwm_time,u8 led_level)//led_var指定让8个里面的哪些点亮,如:0x81就是将L1与L8同时用此pwm波驱动
{
if(led_pwm_time<led_level*4)//level=1时,led_level*4=4ms,即上图中的一个|
{//亮hc4&=0xfe;
select(Y0);hc4&=~led_var;P0=hc4;select(Y4);//据题目要求,等级越低,led越暗
}else{//灭hc4|=0x01;
select(Y0);hc4|=led_var;P0=hc4;select(Y4);
}
}
2.LED处理函数
重点:
每个时间间隔后(改变led显示状态)都要将数码管全部熄灭,熄灭操作
如下:select(Y0);hc4=0xff;P0=hc4;select(Y4);
void taskled()//多间隔时间标志
{
if(led_on==1)
{
//自定义时间间隔如500ms执行一次
if(led_mod_int>=led_int[led_mod])//==在改变间隔时间时容易出错
{
led_mod_int=0;//该led模式下的间隔时间标志
select(Y0);hc4=0xff;P0=hc4;select(Y4);//!!!!加这一句很重要,因为每次要改变led_var值后,要保证,hc4里面的数据消除之前的数据;!!!!
if(led_mod==0)
{
led_var=0x01<<led_mod_i;//led_var经过实验必须定义,将其传至hc4
led_mod_i++;if(led_mod_i==8)led_mod_i=0;//led移动
}else if(led_mod==1)
{
led_var=0x80>>led_mod_i;
led_mod_i++;if(led_mod_i==8)led_mod_i=0;
}else if(led_mod==2)
{
led_var=led_34[led_mod_i_34];
led_mod_i_34++;if(led_mod_i_34==4)led_mod_i_34=0;
}else if(led_mod==3)
{
led_var=led_34[led_mod_i_34];
led_mod_i_34--;if(led_mod_i_34==255)led_mod_i_34=3;
}
}
}
}
3.中断处理函数
调用pwm接口+taskled处理函数
/*全局变量总概览*/
//当前led的模式与该模式下的时间间隔参数
u8 led_mod=0;//通过按键切换led显示模式
u16 led_int[4];//四个模式的间隔,可通过按键设置间隔大小
u16 led_mod_int=0;//哎!!又忘了是16位
//pwm接口要用到的参数
u8 led_var;//pwm的接口,向pwm传输端口信息;在taskled()函数中根据模式进行改变;
u8 led_pwm_time=0;//该参数在中断中循环自增;
u8 led_level=1;//pwm频率为50hz,即在20ms内根据led_level调占空比;
//taskled任务要用到的具体led移动方式的参数
bit led_on=0;//通过按键决定taskled是否运行
u8 led_mod_i=0;//模式1,2的led移位标志
u8 led_mod_i_34=0;//模式3,4的led移位标志
u8 led_34[4]={0x81,0x42,0x24,0x18};/*模式3,4,led端口值,
/10000001/ /01000010/ /00100100/ /00011000/ (1:亮)
*/
void Timer1_Isr(void) interrupt 3
{
//led处理及标志位设置,如:模式1下时间间隔为400ms(即:led_mod=0;400=led_int[0])\
执行完成taskled()后向外部传出led_var,之后**pwm接口函数**使用led_var变量进行led的显示;
taskled();//400ms执行一次led状态的改变(led_var参数的改变)
if(led_mod_int<led_int[led_mod])led_mod_int++;
//pwm处理函数必要参数
pwm_led(led_var);
led_pwm_time++;
if(led_pwm_time>=16)led_pwm_time=0;//pwm周期为20ms
}
总结:
- https://musetransfer.com/s/kb3pliqo7 请点击链接获取《9届蓝桥杯省赛》程序源码, 有效期至2025年3月31日
- 视频链接https://live.youkuaiyun.com/v/375211?spm=1001.2014.3001.5501