define _51LED_define led P1 //P1总线连8个led灯,灯连573锁存器,P1置低电平点亮 define LED led define ON(x) P1&(~(1<<(x))) //打开某个灯,开多个灯用 ON(m) & ON(n)define OFF(x)
实现你的要求有简单的办法,就是采用单片机产生可控的PWM(PWM(Pulse Width Modulation)控制——脉冲宽度调制技术。 通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。 )通过光电耦合隔离电路并经过
大概可以这样做。在图中采用2个隔离二极管将充电回路和放电回路的电阻分开,再用调整电位器的方法使充电电阻和放电电阻阻值发生变化来改变脉冲占空比。这样就可以实现宽范围的占空比可调PWM电路了。我所用的555工作在无稳态方式,
用T0定时器控制PWM的占空比,T1定时器控制脉宽(最大:65536微妙)。T0、T1定时器设置成:16位定时器。程序清单:(12MHz)PwmData0 ;T0定时t1所需的定时初值(字)PwmData1 ;T1定时T所需的定时初值(字);setb
51单片机输出pwm波控制led灯亮度 频率50HZ,周期是20ms 看你调节的精度 如定时器定时1ms,高电平宽度一次变化是5% 如果想要调节精度高,定时器定时时间小,就要频繁地发生中断,会影响主程序的运行 如 要求占空比每步调
51单片机pwm调光电路参考源程序:int potpin=0;//定义模拟接口0 int ledpin=11;//定义数字接口11(PWM 输出)int val=0;// 暂存来自传感器的变量数值 void setup(){ pinMode(ledpin,OUTPUT);//定义数字接口11 为输
51单片机pwm调光电路
用汇编语言让51单片机八个灯从左到右依次点亮且都不灭,每个灯亮的时间间隔0.5秒,然后全灭,再循环之前的步骤。参考如下:电路 代码 LED_COUNTDATA30H T0_COUNTDATA31H ORG0000HLJMPMAINORG000BHLJMPT0_INTORG0030HMAIN:
P3=0xfe;//第一个灯亮 delay();//延时 P3=0xfd;//第二个灯亮 delay();P3=0xfb;//第三个灯亮 delay();P3=0xf7;//第四个灯亮 delay();P3=0xef;//第五个灯亮 delay();P3=0xdf;//第六个灯亮 delay
假设P1接8 个LED,高电平时LED点亮,主程序如下:void main(void){ uchar i;while(1){ for(i=0;i<7;i++){ P1=1<>i;delay_ms(500);} } }
LED = 0xfe;EA = 0;while(1){ for(i=0;i<7;i++){delay(100);LED = (LED<<1)|0x01;P3 = LED;} for(i=0;i<7;i++){delay(100);LED = (LED>>1)|0x80;P3 = LED;} } } 汇编语言 LEDEQU 3
Count = LEDx * 36; //最小0,最大 7 * 36 = 252,char型最大不能超过255; Count = Count + 1; // 加1的目的是针对LED0不亮 if(x <= Count) // <= 是针对LED0不亮 PORTA |= (1 <<
用51单片机c语言让八个led亮度自左向右逐渐变亮(pwm)
sbit PWM = P2^0;void key_control();void init ();void create_PWM(uchar);void delay(uint);void main (){ init ();while(1);{ key_control();create_PWM(count);} } void delay(uint z){ uint x,y;
else led=1;//关灯 f(t>80)t=0;//t置零,要改呼吸频率就改掉“80”这个数还有下面的一个“80”也一起改 } } void Timer0Interrupt(void) interrupt 1 //T0中断,用来控制PWM电平,每50微秒,t自加一次 {
第三,每进入中断一次count++,满足条件count==PWM_ON或count==CYCLE时改变LED的当前状态。作用是给小灯亮或灭的时间不同。第四,LED的亮度与其通电时间有关,也可以说成是占空比。上面的条件要理解成是呈线性增加或减小的
void loop(){ val=analogRead(potpin);// 读取传感器的模拟值并赋值给val Serial.println(val);//显示val 变量 analogWrite(ledpin,val/4);// 打开LED 并设置亮度(PWM 输___出最大值255)delay(10);//延时0.01
可以设两个按键,一个调亮一个调暗 用定时器就可以产生不同占空比的PWM信号,占空比越高LED越亮,占空比越低就越暗 检测两个按键动作,然后调整PWM信号的占空比就行了 只能说说原理,具体细节无法一一说清了
pwm,用定时器T1溢出做pwm周期,在每次T1开始计数时触发输出,软件边增1计数边检查溢出标志。如果软件计数满则清输出,否则直到溢出清输出、清软件计数满值。改变软件计数满值就能改变亮度。51单片机输出pwm波控制led灯亮度 频率
u8 PWM_keyChange=10; //初值,按键调整在1~20之间变化 //占空比 PWM_keyChange/grading void T0_work() //本函数由T0定时器中断函数调用 { if(timeMultiple1Flag){ led=off(7); //关闭7号灯 timeMu
51单片机如何用一个按键和一个定时器来模拟PWM控制一个LED灯的亮度??
第三,每进入中断一次count++,满足条件count==PWM_ON或count==CYCLE时改变LED的当前状态。作用是给小灯亮或灭的时间不同。第四,LED的亮度与其通电时间有关,也可以说成是占空比。上面的条件要理解成是呈线性增加或减小的
void Timer0Interrupt(void) interrupt 1 //T0中断,用来控制PWM电平,每50微秒,t自加一次 { TH0 = 0xff;TL0 = 0xce;t++;} void Timer1Interrupt(void) interrupt 3//T1中断,控制PWM电平宽度,使电平宽度由短变
再做一个pwm的模拟程序,占空比(0-100)是三角波发生器的输出,pwm模拟程序控制某个端口输出1和0的占空比来控制灯 的明暗。pwm的思路是:检查设置值是否不等于0,是则端口置1,程序开始加1计数,计数后检查计数值是否等于
51单片机pwm调光电路参考源程序:int potpin=0;//定义模拟接口0 int ledpin=11;//定义数字接口11(PWM 输出)int val=0;// 暂存来自传感器的变量数值 void setup(){ pinMode(ledpin,OUTPUT);//定义数字接口11 为输
51单片机输出pwm波控制led灯亮度 频率50HZ,周期是20ms 看你调节的精度 如定时器定时1ms,高电平宽度一次变化是5% 如果想要调节精度高,定时器定时时间小,就要频繁地发生中断,会影响主程序的运行 如 要求占空比每步调
请教51单片机利用PWM控制灯的亮度的程序
第一,要理解中断在这里的作用是固定的“一小段”时间进入一次。 第二,PWM_ON在程序中的作用很大,它会由0------>CYCLE------>0并且一直循环下去。可以把它看成一个有规律的变化的量。 第三,每进入中断一次count++,满足条件count==PWM_ON或count==CYCLE时改变LED的当前状态。作用是给小灯亮或灭的时间不同。 第四,LED的亮度与其通电时间有关,也可以说成是占空比。上面的条件要理解成是呈线性增加或减小的频率。可以理解成三角波,对应的面积就是通电时间。 不知能不能给你讲明白!#include #define uint unsigned int #define uchar unsigned char uchar count ,z; sbit key_1 = P3^7; sbit key_2 = P3^6; sbit PWM = P2^0; void key_control(); void init (); void create_PWM(uchar); void delay(uint); void main () { init (); while(1); { key_control(); create_PWM(count); } } void delay(uint z) { uint x,y; for(x = z;x>0;x--) for(y = 110;y>0;y--); } void init() { TMOD = 0x10; TH1 = (65536-4608)/256;//50sm TL1 = (65536-4608)%256; TR1 = 1; } void create_PWM(uchar count) { static i; if(TF1 == 1) { TF1 = 0; TH1 = (65536-4608)/256;//50sm TL1 = (65536-4608)%256; i++; if(i == 100) i=0; if(i <= count) PWM = 1; else PWM = 0; } } void key_control() { if(key_1 ==0) { delay(10); if(key_1 == 0) { count+= 5; if(count >= 100)count = 0; } } if(key_2 ==0) { delay(10); if(key_2 ==0) { count-= 5; if(count <= 0)count =100; } } }
如果用STC90系列以后的单片机,由于内置了PWM模块,直接按手册中的例程就可以,如果是AT89系列的,就要用定时器模拟了,这个比较复杂,你百度一下,网上有的
#include #define uchar unsigned char #define uint unsigned int sbit lamp=P2^0;//输出 sbit k1=P3^3;//加键 sbit k2=P3^2;//减键 sbit k3=P3^4;//停止 uchar a=10; void delay(uint x)//延时函数 { uchar i; while(x--) for(i=0;i<110;i++); } void init() { TMOD=0X01;//晶振11.0592,定时器定时方式1 TH0=0XFF;//100us定时 TL0=0XA4; EA=1;//开总中断 ET0=1;//开定时器中断 TR0=1;//开定时器 } void key() { if(!k1) { delay(10); if(!k1) { a++; if(a==99) a=1; } } // while(!k1); if(!k2) { delay(10); if(!k2) { a--; if(a==1) a=99; } } // while(!k2); if(!k3) { delay(10); if(!k3) { TR0=~TR0;//开定时器 } } while(!k3); } void main() { init(); while(1) { key(); } } void timer0() interrupt 1 using 3 { uchar count; /*中断次数计数器变量*/ TH0=0xFF; /*恢复定时器初始值*/ TL0=0xA4; count++; if (count>=100) count=0; if (count<=a) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ lamp=0; else lamp=1; }
这个要用到软件的pwm,因为51的没有硬件的pwm所以只好自己写软件的了。首先,要做一个软件三角波发生器子程序,频率自己定,就是变亮变暗的周期。此函数的返回值作为pwm的输入值。再做一个pwm的模拟程序,占空比(0-100)是三角波发生器的输出,pwm模拟程序控制某个端口输出1和0的占空比来控制灯 的明暗。pwm的思路是:检查设置值是否不等于0,是则端口置1,程序开始加1计数,计数后检查计数值是否等于设置值,如果等于则跳转,不等则继续加一,如果到100或者计数值等于设置值则使端口置0,一个pwm周期结束,如此重复就可以了。pwm周期自己看实际情况定义。如果要控制电灯泡的话,频率不用太高,50hz可以了。关键是要做隔离,用光电隔离加双向可控硅来控制。 呵呵,声明两点:1 源程序网上应该有的,或者自己买本书就什么也有了。2 不鼓励直接给别人源程序,给你思路再动手就应该很好弄了,总看别人的,不自己思考永远都是别人的。 http://www.programsalon.com/downloads88/sourcecode/embed/detail337156.html
#include #define uint unsigned int #define uchar unsigned char uchar count ,z; sbit key_1 = P3^7; sbit key_2 = P3^6; sbit PWM = P2^0; void key_control(); void init (); void create_PWM(uchar); void delay(uint); void main () { init (); while(1); { key_control(); create_PWM(count); } } void delay(uint z) { uint x,y; for(x = z;x>0;x--) for(y = 110;y>0;y--); } void init() { TMOD = 0x10; TH1 = (65536-4608)/256;//50sm TL1 = (65536-4608)%256; TR1 = 1; } void create_PWM(uchar count) { static i; if(TF1 == 1) { TF1 = 0; TH1 = (65536-4608)/256;//50sm TL1 = (65536-4608)%256; i++; if(i == 100) i=0; if(i <= count) PWM = 1; else PWM = 0; } } void key_control() { if(key_1 ==0) { delay(10); if(key_1 == 0) { count+= 5; if(count >= 100)count = 0; } } if(key_2 ==0) { delay(10); if(key_2 ==0) { count-= 5; if(count <= 0)count =100; } } }
大概可以这样做。 在图中采用2个隔离二极管将充电回路和放电回路的电阻分开,再用调整电位器的方法使充电电阻和放电电阻阻值发生变化来改变脉冲占空比。 这样就可以实现宽范围的占空比可调PWM电路了。 我所用的555工作在无稳态方式,也就是多谐振荡,请楼主考虑下,希望能提供些参考价值。 将可调电阻选一个阻值10M以上的(越大越好),其他电阻均选择1K,可以实现占空比0.01%~99.99% 向左转|向右转
#include 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 //头文件 #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%呢?这不就在改变其功率么?