2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 呼吸灯51单片机c语言编程 51单片机基于定时器实现呼吸灯(C8051F020单片机)

呼吸灯51单片机c语言编程 51单片机基于定时器实现呼吸灯(C8051F020单片机)

时间:2019-04-25 10:54:35

相关推荐

呼吸灯51单片机c语言编程 51单片机基于定时器实现呼吸灯(C8051F020单片机)

一、实现思路

原理:利用PWM信号控制LED灯的亮暗程度,实现LED灯由暗到亮又由亮到暗的渐变过程。

方法:通过定时器设置LED所接引脚的高低电平持续时间,模拟出PWM波。

二、关键问题——PWM的频率和占空比

1.设定PWM的频率:

由于人眼的视觉暂留效果,为避免视觉上灯的闪烁,PWM方波的频率至少大于30Hz。可以取PWM的周期为10ms,即频率为100Hz。

实现方式:使用定时器0的实现10ms定时。并使用定时器2控制PWM高低电平的持续时间。

2.设定占空比的步进间隔

步进时间间隔应小于人眼的视觉暂留效果,即小于30Hz,保证LED亮暗的变化能够被人眼捕捉到,我们设定步进时间的间隔为100ms(10Hz)。

实现方式:

(1)每隔100ms修改一次占空比,可通过进入10次定时器0(上文提到的)的溢出中断实现。

(2)定时器中断ISR中修改占空比:占空比从0开始,每次步进10%,递增到100%;再从100%每次递减10%到0%。

3.总结:利用两个定时器互相配合来模拟PWM波的生成,PWM波的频率和占空比均可控。

三、实现代码

注:C8051F020是增强型51单片机,与传统51相比增加了看门狗(watchdog)、交叉开关(crossbar)等外设,编程时应额外注意它们的使用。

步骤:各外设的初始化——打开定时器中断——在中断服务函数中写逻辑

#include #define Duty_Max 10 //10代表占空比最大为100%

#define STEP 1 //1代表每次步进10%

#define SYSCLK 2000000 //2MHz system clock

sfr16 RCAP2 = 0xCA; // Timer2 Reload Register

sfr16 TMR2 = 0xCC; // Timer2 Register

unsigned char duty = 0; //占空比的范围0~10, 代表0%~100%

sbit LED = P2^4; //开发板上P2.4连接LED

bit direction = 1; //占空比增加/减少的方向: 1代表增加; 0代表减少

void Timer0_Init(void);

void Port_Init (void);

void Wait_MS(unsigned char ms); //定时器2轮询方式实现ms级延时

void main()

{

WDTCN = 0xDE;// Disable watchdog timer

WDTCN = 0xAD;

OSCICN = 0x04; //2MHz system clock

Port_Init();

Timer0_Init();

LED = 0;

EA = 1;

while(1);

}

void Timer0_ISR(void) interrupt 1

{

static unsigned char n = 0;

TH0 = 0xB1;

TL0 = 0xE0;

n++;

LED = 1;

Wait_MS(duty);

LED = 0;

Wait_MS(10-duty);

if(n==10)

{

n = 0;

if(direction == 1)

{

duty += STEP;

if(duty == Duty_Max)

{

direction = 0;

}

}

if(direction == 0)

{

duty -= STEP;

if(duty == 0)

{

direction = 1;

}

}

}

}

void Port_Init (void)

{

XBR2 = 0x40; //enable crossbar

P2MDOUT = 0xFF;

}

void Wait_MS(unsigned char ms)

{

CKCON |= 0x20; //use SYSCLK

RCAP2 = -(SYSCLK/1000); // Timer 2 overflows at 1 kHz

TMR2 = RCAP2;

TR2 = 1; // Start Timer 2

while(ms)

{

TF2 = 0;

while(!TF2); // Wait until timer overflows

ms--; // Decrement ms

}

TR2 = 0; // Stop Timer 2

}

void Timer0_Init(void)

{

CKCON |= 0x08; //use SYSCLK

TMOD = 0x01; // 16-bit Mode Timer0

TH0 = 0xB1; // 10ms

TL0 = 0xE0;

ET0 = 1; // Timer0 interrupt enabled

TR0 = 1;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。