如何用51单片机产生pwm 并利用pwm控制led灯的功率?
2个回答
展开全部
#include<reg52.h>
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CL = 0xE9;
sfr CH = 0xF9;
sfr CCAP0L = 0xEA;
sfr CCAP0H = 0xFA;
sfr CCAPM0 = 0xDA;
sfr CCAPM1 = 0xDB;
#define uint unsigned int
#define uchar unsigned char
uchar whith_p=50;
uchar max_p=255;
uchar min_p=1;
uint fre = 0xffff;
sbit CR = 0xDE;
sbit led = P2^0;
void timer0_int (void) interrupt 1 using 1
{
TH0 = fre >> 8;
TL0 = fre & 0xff;
led = ~led;
}
void timer0_init(void)
{
TMOD &= 0xf0;
TMOD |= 0x1;
TH0 = 0xff;
TL0 = 0xff;
TR0 = 1;
ET0 = 1;
}
void pwm_init(void)
{
CMOD = 0x4;
CL = 0x0;
CH = 0x0;
CCAP0H = whith_p;
CCAPM0 = 0x42;
CR = 1;
}
void soft_delay(uint _1ms)
{
unsigned int tmp;
while(_1ms--!=0) {
for(tmp=0;tmp<144;tmp++);
}
}
void pwm_out(void)
{
whith_p=50;
while(whith_p<max_p)
{ CCAP0H =whith_p;
soft_delay(10);
whith_p=whith_p+5;
CCAP0H = whith_p;
soft_delay(10);
}
whith_p=max_p;
while(min_p<whith_p)
{ CCAP0H = whith_p;
soft_delay(10);
whith_p=whith_p-5;
CCAP0H = whith_p;
soft_delay(10);
}
}
void main (void)
{
pwm_init();
timer0_init();
EA = 1;
while(1){
pwm_out();
}
}
STC单片机具有PWM输出功能,最近玩12864LCD万年历时,用的是杜洋的FT4时钟电路,用他提供的H文件控制时,具有调光功能,由于只是玩一玩,没有购买源码,而网上流行的程序都没有此功能,无奈,只能自己弄,好在杜老师及人所及早在网站中备下了资料,简单攒一下,居然成功了,并成功的汇入了万年历的程序中,现在将其改成完整的控制程序公开于此供参考。
/*************************************************
STC单片机单/双键控制LED亮度PWM调光程序 原创WanNengGong 2010/09/20
参考程序: 杜洋工作室PWM功能程序模块
*************************************************/
#include<STC12C5A60S2.H> //头文件
#define uchar unsigned char
#define uint unsigned int
uchar vx=5;
//vx=5在用于12864LCD的LED背光调整时上电为半亮度状态,可根据自己的用途及要求任意设定
sbit KEY_H=P2^4;
sbit KEY_L=P2^5;
/*******************************************************************************/
void PWM_init (void){//PWM初始化函数
CMOD=0x02; //设置PCA定时器
CL=0x00;
CH=0x00;
CCAPM1=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)
CCAP1L=0x00; //设置PWM0初始值与CCAP0H相同
CCAP1H=0x00; // PWM0初始时为0
CR=1; //启动PCA定时器
}
/******************************************************************************/
void PWM0_set (uchar a){//PWM0占空比设置函数
CCAP1L=a; //设置值直接写入CCAP1L
CCAP1H=a; //设置值直接写入CCAP1H
}
/*****************************************************************************/
void DelayM(unsigned int a){//延时函数 1mS/次(用于1T单片机)
unsigned char n,i,j;
while(--a!=0){
for(n=1;n>0;n--)
for(j=222;j>0;j--)
for(i=12;i>0;i--);
} }
/****************************************************************************/
void main(void)
{
KEY_H = 1;KEY_L = 1;
PWM_init ();
while(1)
{
PWM0_set(vx*24);
//数字24是配合vx调试取得的,此时vx的赋值范围约为1-10对应最暗-最亮
//--------减调整---------//
if (KEY_L == 0 ){
DelayM(20); //延时20毫秒消抖动
if(KEY_L == 0){ //如果20SM后KEY_L还是0状态则确认下调键是按下的
vx--;
if(vx<1){vx=5;}
//如果设定vx=10,将语句改为if(vx<1){vx=10;}则为单按键循环控制,则可去除加调整控制部分
}
while(KEY_L == 0);//等待键松开
}
//--------加调整---------//
if (KEY_H == 0 ){
DelayM(20);
if(KEY_H == 0){
vx++;
if(vx>10){vx=5;}
}
while(KEY_H == 0);
}
}
}
程序自己理解消化了,就可以编出你自己的程序了,你说的,完全可以实现,而且比这俩个例子简单N多。
这是百度里面别人的回答,感觉可以解决您单片机产生PWM的问题了,至于后面如何控制功率,那你就要搞清功率的单位是什么,除了w,还有什么,在时间一定的情况下,如何改变功率,只需要改变其PWM的占空比。如果一个周期里面,它有50%是高电平,那么它是正常输入的50%的功率,如果只有20%呢,10%呢?这不就在改变其功率么?
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CL = 0xE9;
sfr CH = 0xF9;
sfr CCAP0L = 0xEA;
sfr CCAP0H = 0xFA;
sfr CCAPM0 = 0xDA;
sfr CCAPM1 = 0xDB;
#define uint unsigned int
#define uchar unsigned char
uchar whith_p=50;
uchar max_p=255;
uchar min_p=1;
uint fre = 0xffff;
sbit CR = 0xDE;
sbit led = P2^0;
void timer0_int (void) interrupt 1 using 1
{
TH0 = fre >> 8;
TL0 = fre & 0xff;
led = ~led;
}
void timer0_init(void)
{
TMOD &= 0xf0;
TMOD |= 0x1;
TH0 = 0xff;
TL0 = 0xff;
TR0 = 1;
ET0 = 1;
}
void pwm_init(void)
{
CMOD = 0x4;
CL = 0x0;
CH = 0x0;
CCAP0H = whith_p;
CCAPM0 = 0x42;
CR = 1;
}
void soft_delay(uint _1ms)
{
unsigned int tmp;
while(_1ms--!=0) {
for(tmp=0;tmp<144;tmp++);
}
}
void pwm_out(void)
{
whith_p=50;
while(whith_p<max_p)
{ CCAP0H =whith_p;
soft_delay(10);
whith_p=whith_p+5;
CCAP0H = whith_p;
soft_delay(10);
}
whith_p=max_p;
while(min_p<whith_p)
{ CCAP0H = whith_p;
soft_delay(10);
whith_p=whith_p-5;
CCAP0H = whith_p;
soft_delay(10);
}
}
void main (void)
{
pwm_init();
timer0_init();
EA = 1;
while(1){
pwm_out();
}
}
STC单片机具有PWM输出功能,最近玩12864LCD万年历时,用的是杜洋的FT4时钟电路,用他提供的H文件控制时,具有调光功能,由于只是玩一玩,没有购买源码,而网上流行的程序都没有此功能,无奈,只能自己弄,好在杜老师及人所及早在网站中备下了资料,简单攒一下,居然成功了,并成功的汇入了万年历的程序中,现在将其改成完整的控制程序公开于此供参考。
/*************************************************
STC单片机单/双键控制LED亮度PWM调光程序 原创WanNengGong 2010/09/20
参考程序: 杜洋工作室PWM功能程序模块
*************************************************/
#include<STC12C5A60S2.H> //头文件
#define uchar unsigned char
#define uint unsigned int
uchar vx=5;
//vx=5在用于12864LCD的LED背光调整时上电为半亮度状态,可根据自己的用途及要求任意设定
sbit KEY_H=P2^4;
sbit KEY_L=P2^5;
/*******************************************************************************/
void PWM_init (void){//PWM初始化函数
CMOD=0x02; //设置PCA定时器
CL=0x00;
CH=0x00;
CCAPM1=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)
CCAP1L=0x00; //设置PWM0初始值与CCAP0H相同
CCAP1H=0x00; // PWM0初始时为0
CR=1; //启动PCA定时器
}
/******************************************************************************/
void PWM0_set (uchar a){//PWM0占空比设置函数
CCAP1L=a; //设置值直接写入CCAP1L
CCAP1H=a; //设置值直接写入CCAP1H
}
/*****************************************************************************/
void DelayM(unsigned int a){//延时函数 1mS/次(用于1T单片机)
unsigned char n,i,j;
while(--a!=0){
for(n=1;n>0;n--)
for(j=222;j>0;j--)
for(i=12;i>0;i--);
} }
/****************************************************************************/
void main(void)
{
KEY_H = 1;KEY_L = 1;
PWM_init ();
while(1)
{
PWM0_set(vx*24);
//数字24是配合vx调试取得的,此时vx的赋值范围约为1-10对应最暗-最亮
//--------减调整---------//
if (KEY_L == 0 ){
DelayM(20); //延时20毫秒消抖动
if(KEY_L == 0){ //如果20SM后KEY_L还是0状态则确认下调键是按下的
vx--;
if(vx<1){vx=5;}
//如果设定vx=10,将语句改为if(vx<1){vx=10;}则为单按键循环控制,则可去除加调整控制部分
}
while(KEY_L == 0);//等待键松开
}
//--------加调整---------//
if (KEY_H == 0 ){
DelayM(20);
if(KEY_H == 0){
vx++;
if(vx>10){vx=5;}
}
while(KEY_H == 0);
}
}
}
程序自己理解消化了,就可以编出你自己的程序了,你说的,完全可以实现,而且比这俩个例子简单N多。
这是百度里面别人的回答,感觉可以解决您单片机产生PWM的问题了,至于后面如何控制功率,那你就要搞清功率的单位是什么,除了w,还有什么,在时间一定的情况下,如何改变功率,只需要改变其PWM的占空比。如果一个周期里面,它有50%是高电平,那么它是正常输入的50%的功率,如果只有20%呢,10%呢?这不就在改变其功率么?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询