本帖最后由 yang_alex 于 2020-4-8 11:40 编辑
只是让灯闪烁还是有点简单了,那我们就玩点稍微复杂的------呼吸灯。
呼吸灯的简单原理就是用PWM波驱动LED,逐渐调大占空比,到达最大占空比后再逐渐调小占空比。
赛元的SC95F861X系列MCU 提供了最多 8 路共用周期、单独可调占空比的 12 位 PWM。我们这里只用其中一路。PWM类型可设为中心对齐型或边沿对齐型,我们这里简单地采用边沿对齐型;PWM模式可设为独立模式或互补模式(对于需要设置死区的上下管驱动非常有用),我们这里只简单地采用独立模式。PWM还支持 故障检测功能,故障检测功能常应用于电机系统的防护,发现故障马上停止驱动,非常实用的一个功能,我们这里暂时用不上。
先进行外设初始化和相关参数初始化。
void main(void)
{
IO_Init();
Timer_Init();
PWM_Init();
T_ms = 0;
V_Duty = 0;
while(1);
}
IO外设初始化
/*****************************************************
*函数名称:void IO_Init(void)
*函数功能:IO初始化
*入口参数:void
*出口参数:void
*****************************************************/
void IO_Init(void)
{
P4CON = 0xFF; //设置P4为强推挽模式
P4PH = 0x01;
}
定时器初始化
/*****************************************************
*函数名称:void Timer_Init(void)
*函数功能:T0/T1/T2初始化
*入口参数:void
*出口参数:void
*****************************************************/
void Timer_Init(void)
{
TMCON = 0X00; //------111 ;Timer0、Tiemr1和Tiemr2选择时钟Fsys/12
//T0设置
TMOD |= 0x01; //0000 0001;Timer0设置工作方式1
TL0 = (65536 - 7192)%256; //时钟为Fsys/12,则溢出时间=7192*(1/Fsys);
TH0 = (65536 - 7192)/256;
TR0 = 0;
ET0 = 1;//定时器0允许
TR0 = 1;//打开定时器0
EA = 1;
}
定时器中断,用来定时调整PWM的占空比(先逐渐增大,后逐渐减小)
/**************************************************
*函数名称:void timer0/1/2/3/4() interrupt 1/3/5/13/14
*函数功能:定时器中断产生方波
*入口参数:void
*出口参数:void
**************************************************/
void timer0() interrupt 1
{
TL0 = (65536 - 7192)%256;
TH0 = (65536 - 7192)/256;
T_ms ++;
if(T_ms < 400)
{
V_Duty = V_Duty + 1;
}
else
{
V_Duty = V_Duty - 1;
}
if(T_ms == 800)
{
T_ms = 0;
V_Duty = 0;
}
}
PWM初始化./*****************************************************
*函数名称:void PWM_Init(void)
*函数功能:PWM独立模式初始化
*入口参数:void
*出口参数:void
*****************************************************/
void PWM_Init(void)
{
//设置了周期为100us的PWM波形
PWMMOD = 0x00; //独立模式,边沿对齐
PWMCFG = 0xB1; //7:开关 5-4:时钟源选择 3-0:周期设置高4位 10k----018F
PWMCON = 0x8F; //周期设置低8位,50us 10k----018F
PWMRD_41 = 0x8000 | V_Duty; //开启PWM口,设置占空比
IE1 |= 0x02; //开启中断标志位
EA = 1;
}
PWM中断处理程序,加载调整后的占空比参数.
/*****************************************************
*函数名称:void PWM_Interrup() interrupt 8
*函数功能:PWM中断服务函数
*入口参数:void
*出口参数:void
*****************************************************/
void PWM_Interrup() interrupt 8
{
if(PWMCFG & 0x40)
{
PWMCFG &= ~0x40; //清除中断标志位
PWMRD_41 = 0x8000 | V_Duty; //开启PWM口,设置占空比
}
}
OK.大功告成,看看运行的效果吧。
|