请教51单片机利用PWM控制灯的亮度的程序

有很多不懂!!程序的解释看不懂,谁能更明白的解释下,主要不明白定时中断函数那部分和主函数的PWM_ON++、PWM_ON--。谢谢#include<reg52.h>sbi... 有很多不懂!!程序的解释看不懂,谁能更明白的解释下,主要不明白定时中断函数那部分和主函数的
PWM_ON++、 PWM_ON--。 谢谢

#include <reg52.h>
sbit LED = P1^2;
unsigned char CYCLE; //定义周期 该数字X基准定时时间 如果是10 则周期是10 x 0.1ms
unsigned char PWM_ON ;//定义高电平时间
void delay(unsigned int cnt)
{
while(--cnt);
}
void main()
{
bit Flag;
TMOD |=0x01;//定时器设置 0.1ms in 12M crystal
TH0=(65536-100)/256;
TL0=(65536-100)%256;//定时0.1mS
IE= 0x82; //打开中断
TR0=1;
CYCLE = 10;// 时间可以调整 这个是10调整 8位PWM就是256步
while(!Flag)
{
delay(20000); //延时时间,从一个亮度到下一个亮度的间隔时间,速度快就能看到连续效果
PWM_ON++; //这个使用较长延时,以便能看清楚变化过程
if(PWM_ON == CYCLE)
{ //这个里可以添加其他程序 如到最亮时候控制设备
Flag=1;
}
}
while(Flag) //亮度递减 同上,是个相反的过程
{
delay(20000);
PWM_ON--;
if(PWM_ON == 0)
{
Flag=0;
}
}
}
/********************************/
/* 定时中断 */
/********************************/
void tim(void) interrupt 1 using 1
{
static unsigned char count; //
TH0=(65536-100)/256;
TL0=(65536-100)%256;//定时0.1mS
if (count==PWM_ON)
{
LED = 1; //灯灭
}
count++;
if(count == CYCLE)
{
count=0;
if(PWM_ON!=0) //如果左右时间是0 保持原来状态
LED = 0;//灯亮
}
}
展开
 我来答
小灰灰_LI
推荐于2017-12-16 · 超过12用户采纳过TA的回答
知道答主
回答量:46
采纳率:0%
帮助的人:17.2万
展开全部

第一,要理解中断在这里的作用是固定的“一小段”时间进入一次。

第二,PWM_ON在程序中的作用很大,它会由0------>CYCLE------>0并且一直循环下去。可以把它看成一个有规律的变化的量。

第三,每进入中断一次count++,满足条件count==PWM_ON或count==CYCLE时改变LED的当前状态。作用是给小灯亮或灭的时间不同。

第四,LED的亮度与其通电时间有关,也可以说成是占空比。上面的条件要理解成是呈线性增加或减小的频率。可以理解成三角波,对应的面积就是通电时间。

不知能不能给你讲明白!

追问
我知道是利用高低电平的时间控制,但是不知道怎样控制,例如定时器计时周期为1ms,第一次高电平1ms那低电平9ms,下一次高电平2ms,低电平8ms,就是不知道程序应该怎样写。
追答
多钻研就会,不要把不会当理由,用好编程语言,想通怎么样去控制,多花一点点时间,希望你成功!
施西贝虎
2014-03-20 · TA获得超过414个赞
知道小有建树答主
回答量:331
采纳率:100%
帮助的人:182万
展开全部
首先说下整体思路吧:
1)通过定时器的中断来判断是否需要切换灯的状态;
2)通过CYCLE设置了PWM的频率,当然这个频率不能超过定时器的中断频率;
3)通过PWM_ON来改变灯亮的时间长度(有时候也可以做到,时间的长短来控制灯的亮度)

知道了这些,你就应该明白程序是如何运行了:
两个while循环控制PWM_ON的值,而中断程序来不断查看是否需要关掉灯/点亮灯。

若满意请采纳。
追问
我知道是利用高低电平的时间控制,但是不知道怎样控制,例如定时器计时周期为1ms,第一次高电平1ms那低电平9ms,下一次高电平2ms,低电平8ms,就是不知道程序应该怎样写。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
做而论道
高能答主

2014-03-21 · 把复杂的事情简单说给你听
知道大有可为答主
回答量:3万
采纳率:80%
帮助的人:1.1亿
展开全部
主函数中,缺少大循环 while(1);,是不是有问题呀 ?

参考:

http://hi.baidu.com/do_sermon/item/5011f5c4c8d1bd2b47d5c00d
追问
我知道是利用高低电平的时间控制,但是不知道怎样控制,例如定时器计时周期为1ms,第一次高电平1ms那低电平9ms,下一次高电平2ms,低电平8ms,就是不知道程序应该怎样写。
追答
例如定时器计时周期为1ms,
第一次高电平1ms,低电平9ms,
下一次高电平2ms,低电平8ms,

--每中断一次,就变一次占空比?
--哪能变化这么快?

--高电平1ms,低电平9ms,这不是需要中断十次吗?
--以后,需要再中断十次,才能实现高电平2ms,低电平8ms。
---------------------
看看你给出的程序,注释如下:

//主函数:
//CYCLE = 10;
//PWM_ON++,是变化的,假设当时为7。

//--------------------------------------------------

void tim(void) interrupt 1 //每隔0.1ms中断一次
{
static unsigned char count; //中断次数

TH0 = (65536 - 100) / 256; //重设初值
TL0 = (65536 - 100) % 256; //定时0.1ms

if (count == PWM_ON) { //假设PWM_ON=7
LED = 1; //灯灭 //如中断7次了,就关灯
}

count++; //中断次数加一

if(count == CYCLE) { //如中断了10次
count = 0; //次数清零

LED = 0;//灯亮
}
}

//--------------------------------------------------

//以上中断程序,经过10次执行,方可实现:
//亮 0.7ms,灭0.3ms。

//然后,经过多长时间,再改成另一种占空比呢?
//你根本就没有时间概念。

-----------------------

楼主采纳的答案,是讲空洞道理的。

你原来不会编程,采纳之后,你还是不会编程。

关键,你是不理解,要多长时间,改变一次占空比。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式