PCA9544 4 channel I2C bus multiplexer with interrupt logic分流器
上传时间: 2016-05-03
上传用户:lixin52590379
#include "STC90.h" #include < intrins.h > #define uchar unsigned char #define uint unsigned int #define led_port P1 sbit IR_RE = P3^2; sbit led_r = P1^3; sbit led_g = P1^4; sbit led_b = P1^5; sbit led_wd = P1^7; sbit K1 =P3^0 ; //增加键 sbit K2 =P3^1 ; //减少键 sbit BEEP =P3^7 ; //蜂鸣器 uchar temp,temp1; bit k=0; //红外解码判断标志位,为0则为有效信号,为1则为无效 bit Flag2; uchar date[4]={0,0,0,0}; //date数组为存放地址原码,反码,数据原码,反码 uint lade_1,lade_2,lade_3,lade_4; uint num; uchar date_ram,ee_temp,ee_temp1; uchar WDT_NUM=0; uchar const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值01234567 uchar code seg[]={7,6,5,4,3,2,1,0};//分别对应相应的数码管点亮,即位码 unsigned long disp_date; void fade(); void fade1(); /*************************** 看门狗子程序*************************/ void watchdog_timer() { if(WDT_NUM==5) { WDT_NUM=0; led_wd=!led_wd; } WDT_NUM++; WDT_CONTR=0x3f; } /******************************************************************/ void delay(unsigned int cnt) { while(--cnt); } /*--------------------------延时1ms程子程序-----------------------*/ void delay_1ms(uint z) { uint x,y; for(x=z;x>0;x--) for(y=126;y>0;y--); } /*--------------------------延时1ms程子程序-----------------------*/ delay1000() { uchar i,j; i=5; do{j=95; do{j--;} while(j); i--; } while(i); } /*---------------------------延时882us子程序-----------------------*/ delay882() { uchar i,j; i=6; do{j=71; do{j--;} while(j); i--; }while(i); } /*--------------------------延时2400us程子程序-----------------------*/ delay2400() { uchar i,j; i=5; do{j=237; do{j--;} while(j); i--; }while(i); } /**********************************************************************/ /* void display() { uchar i; for(i=0;i<8;i++) { P0=dofly[disp_date%10];//取显示数据,段码 P2=seg[i]; //取位码 delay_1ms(1); disp_date/=10; } } */ /*********************************************************************/ uchar EEPROM_read(uint addr)//EEPROM字节读 { ISP_CONTR=0x83; //系统时钟<12M时,对ISP_CONTR寄存器设置的值,本电路为11.0592M ISP_CMD=1; //字节读 ISP_ADDRH=(addr&0xff00)>>8; ISP_ADDRL=addr&0x00ff; ISP_TRIG=0x46; ISP_TRIG=0xb9; _nop_(); _nop_(); return ISP_DATA; } //-------------------------------------------------------------------- void EEPROM_write(uint addr,uchar dat)//EEPROM字节写 { ISP_CONTR=0x83; //系统时钟<12M时,对ISP_CONTR寄存器设置的值,本电路为11.0592M ISP_CMD=2; //字节编程 ISP_ADDRH=(addr&0xff00)>>8; ISP_ADDRL=addr&0x00ff; ISP_DATA=dat; ISP_TRIG=0x46; ISP_TRIG=0xb9; _nop_(); _nop_(); } //-------------------------------------------------------------------- void EEPROM_ERASE(uint addr)//EEPROM扇区擦除 { ISP_CONTR=0x83; //系统时钟<12M时,对ISP_CONTR寄存器设置的值,本电路为11.0592M ISP_CMD=3; //扇区擦除 ISP_ADDRH=(addr&0xff00)>>8; ISP_ADDRL=addr&0x00ff; ISP_TRIG=0x46; ISP_TRIG=0xb9; _nop_(); _nop_(); } //************************************************************** /*----------------------------------------------------------*/ /*-----------------------红外解码程序(核心)-----------------*/ /*----------------------------------------------------------*/ void IR_decode() { uchar i,j; while(IR_RE==0); delay2400(); if(IR_RE==1) //延时2.4ms后如果是高电平则是新码 { delay1000(); delay1000(); for(i=0;i<4;i++) { for(j=0;j<8;j++) { while(IR_RE==0); //等待地址码第1位高电平到来 delay882(); //延时882us判断此时引脚电平 ///CY=IR_RE; if(IR_RE==0) { date[i]>>=1; date[i]=date[i]|0x00; } else if(IR_RE==1) { delay1000(); date[i]>>=1; date[i]=date[i]|0x80; } } //1位数据接收结束 } //32位二进制码接收结束 } } /* void LED_PWM() { lade_2=num; //384 lade_4=num; //384 while(lade_2!=0&Flag2==1) { for(lade_3=512;lade_3>lade_4;lade_3--) //512 { led_port=0x00; delay(1); } lade_3=512; //512 lade_4--; for(lade_1=0;lade_1<lade_2;lade_1++) { led_port=0x38; //c7 delay(1); } lade_1=0; lade_2--; if(temp!=0x0c&Flag2==1) { lade_2=0; } lade_2=num; //384 lade_4=num; //384 } } */ void calc() { EEPROM_read(0x2000); ee_temp1=ISP_DATA; ee_temp=ee_temp1&0x0f; //************************************* 1 /* if(date[3]==0xff&Flag2==1) { if(num>=20) { num=num-80; } //else num=1; LED_PWM(); } if(date[3]==0xfe&Flag2==1) { if(num<=500) { num=num+80; } // else num=511; LED_PWM(); } if(ee_temp1==0xfd) { led_port=0x00; watchdog_timer(); } if(ee_temp1==0xfc) { led_port=0x00; led_r=1; led_g=1; led_b=1; watchdog_timer(); } */ //********************************************** 2 if(ee_temp1==0xfb) { led_port=0x00; led_r=1; watchdog_timer(); } if(ee_temp1==0xfa) { led_port=0x00; led_g=1; watchdog_timer(); } if(ee_temp1==0xf9) { led_port=0x00; led_b=1; watchdog_timer(); } if(ee_temp1==0xf8) { led_port=0x00; led_r=1; led_g=1; led_b=1; watchdog_timer(); } //************************************** 3 if(ee_temp1==0xf7) { uint fade_1,fade_2,fade_3,fade_4; fade_2=448; //384 fade_4=448; //384 while(fade_2!=0&ee_temp==0x07) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x10; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x08; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x07) { fade_2=0; } watchdog_timer(); fade_2=448; //384 fade_4=448; //384 } } if(ee_temp1==0xf6) { uint fade_1,fade_2,fade_3,fade_4; fade_2=448; //384 fade_4=448; //384 while(fade_2!=0&ee_temp==0x06) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x20; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x10; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x06) { fade_2=0; } watchdog_timer(); fade_2=448; //384 fade_4=448; //384 } } if(ee_temp1==0xf5) { uint fade_1,fade_2,fade_3,fade_4; fade_2=448; //384 fade_4=448; //384 while(fade_2!=0&ee_temp==0x05) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x08; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x20; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x05) { fade_2=0; } watchdog_timer(); fade_2=448; //384 fade_4=448; //384 } } if(ee_temp1==0xf4) { while(ee_temp==4) { led_port=0x00; led_r=1; delay_1ms(200); led_port=0x00; led_r=1; led_g=1; delay_1ms(200); led_port=0x00; led_g=1; delay_1ms(200); watchdog_timer(); led_port=0x00; led_g=1; led_b=1; delay_1ms(200); led_port=0x00; led_b=1; delay_1ms(200); led_port=0x00; led_b=1; led_r=1; delay_1ms(200); watchdog_timer(); } } //************************************** 4 if(ee_temp1==0xf3) { uint fade_1,fade_2,fade_3,fade_4; fade_2=416; //384 fade_4=416; //384 while(fade_2!=0&ee_temp==0x03) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x10; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x08; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x03) { fade_2=0; } watchdog_timer(); fade_2=416; //384 fade_4=416; //384 } } if(ee_temp1==0xf2) { uint fade_1,fade_2,fade_3,fade_4; fade_2=384; //384 fade_4=384; //384 while(fade_2!=0&ee_temp==0x02) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x20; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x10; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x02) { fade_2=0; } watchdog_timer(); fade_2=384; //384 fade_4=384; //384 } } if(ee_temp1==0xf1) { uint fade_1,fade_2,fade_3,fade_4; fade_2=348; //384 fade_4=348; //384 while(fade_2!=0&ee_temp==0x01) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x08; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x20; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x01) { fade_2=0; } watchdog_timer(); fade_2=348; //384 fade_4=348; //384 } } if(ee_temp1==0xf0) { while(ee_temp==0) { led_port=0x00; led_r=1; delay_1ms(500); watchdog_timer(); led_port=0x00; led_g=1; delay_1ms(500); led_port=0x00; led_b=1; delay_1ms(500); watchdog_timer(); } } //******************************************** 5 if(ee_temp1==0xef) { uint fade_1,fade_2,fade_3,fade_4; fade_2=384; //384 fade_4=384; //384 while(fade_2!=0&ee_temp==0x0f) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x10; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x08; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x0f) { fade_2=0; } watchdog_timer(); fade_2=384; //384 fade_4=384; //384 } } if(ee_temp1==0xee) { uint fade_1,fade_2,fade_3,fade_4; fade_2=320; //384 fade_4=320; //384 while(fade_2!=0&ee_temp==0x0e) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x20; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x10; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x0e) { fade_2=0; } watchdog_timer(); fade_2=320; //384 fade_4=320; //384 } } if(ee_temp1==0xed) { uint fade_1,fade_2,fade_3,fade_4; fade_2=320; //384 fade_4=320; //384 while(fade_2!=0&ee_temp==0x0d) { for(fade_3=512;fade_3>fade_4;fade_3--) //512 { led_port=0x08; delay(1); } fade_3=512; //512 fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x20; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x0d) { fade_2=0; } watchdog_timer(); fade_2=320; //384 fade_4=320; //384 } } if(ee_temp1==0xec) fade(); //******************************************* 6 if(ee_temp1==0xeb) { led_port=0x00; led_r=1; led_g=1; watchdog_timer(); } if(ee_temp1==0xea) { led_port=0x00; //led_r=0; led_g=1; led_b=1; watchdog_timer(); } if(ee_temp1==0xe9) { led_port=0x00; led_r=1; //led_g=0; led_b=1; watchdog_timer(); } if(ee_temp1==0xe8) fade1(); } void fade() { // uchar i; uint fade_1,fade_2,fade_3,fade_4; fade_2=512; fade_4=511; while(fade_2!=0&ee_temp==0x0c) { for(fade_3=512;fade_3>fade_4;fade_3--) { led_port=0x10; delay(1); } fade_3=512; fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x08; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x0c) { fade_2=0; } } watchdog_timer(); fade_2=512; fade_4=511; while(fade_2!=0&ee_temp==0x0c) { if(ee_temp!=0x0c) { fade_2=0; } for(fade_3=512;fade_3>fade_4;fade_3--) { led_port=0x20; delay(1); // watchdog_timer(); } fade_3=512; fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x10; delay(1); // watchdog_timer(); } fade_1=0; fade_2--; } watchdog_timer(); fade_2=512; fade_4=511; while(fade_2!=0&ee_temp==0x0c) { if(ee_temp!=0x0c) { fade_2=0; } for(fade_3=512;fade_3>fade_4;fade_3--) { led_port=0x08; delay(1); watchdog_timer(); } fade_3=512; fade_4--; watchdog_timer(); for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x20; delay(1); watchdog_timer(); } fade_1=0; fade_2--; } watchdog_timer(); } void fade1() { // uchar i; uint fade_1,fade_2,fade_3,fade_4; fade_2=128; fade_4=127; while(fade_2!=0&ee_temp==0x08) { for(fade_3=128;fade_3>fade_4;fade_3--) { led_port=0x10; delay(1); } fade_3=128; fade_4--; for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x08; delay(1); } fade_1=0; fade_2--; if(ee_temp!=0x08) { fade_2=0; } } watchdog_timer(); fade_2=128; fade_4=127; while(fade_2!=0&ee_temp==0x08) { if(ee_temp!=0x08) { fade_2=0; } for(fade_3=128;fade_3>fade_4;fade_3--) { led_port=0x20; delay(1); } fade_3=128; fade_4--; for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x10; delay(1); } fade_1=0; fade_2--; } watchdog_timer(); fade_2=128; fade_4=127; while(fade_2!=0&ee_temp==0x08) { if(ee_temp!=0x08) { fade_2=0; } for(fade_3=128;fade_3>fade_4;fade_3--) { led_port=0x08; delay(1); } fade_3=128; fade_4--; for(fade_1=0;fade_1<fade_2;fade_1++) { led_port=0x20; delay(1); } fade_1=0; fade_2--; } watchdog_timer(); } void init() { led_port=0x00; /* led_r=1; delay_1ms(500); led_port=0x00; led_g=1; delay_1ms(500); led_port=0x00; led_b=1; delay_1ms(500); led_port=0x00; */ delay_1ms(2); WDT_CONTR=0x3f; delay_1ms(500); } //******************************** void main() { init(); Flag2=0; SP=0x60; //堆栈指针 EX0=1; //允许外部中断0,用于检测红外遥控器按键 EA=1; num=255; while(1) { calc(); } } //******************************************************************** /*------------------------外部中断0程序-------------------------*/ /*------------------主要用于处理红外遥控键值--------------------*/ void int0() interrupt 0 { uchar i; Flag2=0; /////// k=0; EX0=0; //检测到有效信号关中断,防止干扰 for(i=0;i<4;i++) { delay1000(); if(IR_RE==1){k=1;} //刚开始为9ms的引导码. } led_port=0x00; if(k==0) { IR_decode(); //如果接收到的是有效信号,则调用解码程序 if(date[3]>=0xe8) { if(date[3]<=0xfb) { temp1=date[3]; EEPROM_ERASE(0x2000); //STC_EEROM_0X2000 temp1 EEPROM_write(0x2000,temp1); EEPROM_read(0x2000); ee_temp1=ISP_DATA; ee_temp=ee_temp1&0x0f; /* temp=date[3]&0x0f; EEPROM_ERASE(0x2004); //STC_EEROM_0X2004 temp EEPROM_write(0x2004,temp); */ } else { EEPROM_read(0x2000); ee_temp1=ISP_DATA; ee_temp=ee_temp1&0x0f; } } delay2400(); delay2400(); delay2400(); delay_1ms(500); } EX0=1; //开外部中断,允许新的遥控按键 }
上传时间: 2016-07-02
上传用户:184890962
/*#include<reg52.h> #define uint unsigned int #define uchar unsigned char #define uchar unsigned char sbit K1=P3^4; sbit K2=P3^5; sbit ledr=P1^0; sbit ledg=P1^1; sbit ledb=P1^2; bit LEDDirection=0;//LED控制方向0:渐亮1:渐灭 char pwm=0; char pwmr=0; char scw=0;//中断记数 char tt=0; char n; void dealy(uint z); void Timer0Init(void) { TMOD=0x01; TH0=0xff; TL0=0x47; EX0=1; IT0=0; PX0=1; ET0=1; TR0=1; EA=1; } void main() { Timer0Init(); while(1){ if(K1==0) { dealy (1); if(K1==0) {TR0=1; ledr=0; dealy(5); TR0=0; } } if(K2==0) { dealy (1); if(K2==0) { while(1) { ledr=0; //亮 dealy(100-n*10); ledr=1; //熄 dealy(n*10); } } } } } void Time0Isr(void) interrupt 1 { // pwm=0; TH0=0xff; TL0=0x47; scw++; }*/ #include<reg52.h> #define uchar unsigned char bit LEDDirection=0; sbit P2_0=P1^0; sbit key1=P3^4; sbit key2=P3^5; sbit key3=P3^6; uchar zkb,i,t;// zkb指占空比 uchar pwm; void delay(uchar z) { uchar x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void init() //初始化函数 { TMOD=0X01; TH0=(65536-1000)/256; TL0=(65536-1000)%256; EA=1; ET0=1; TR0=1; } void keyscan() //键盘扫描 { P3=0XFF; if(key1==0) { delay(5); if(key1==0) { while(!key1); if(zkb<9) { zkb++; } } } if(key2==0) { delay(5); if(key2==0) { while(!key2); if(zkb>0) { zkb--; } } } if(key3==0) {TR0=1; delay(5); if(key3==0) {while(!key3); if((zkb<=9)&&(0==LEDDirection)) { zkb++; if(zkb>9) { LEDDirection=1; zkb=9; } } if((zkb>=0 )&&(1==LEDDirection)) { zkb--; if(zkb<0 ) { LEDDirection=0; zkb=0 ; //dealy(3000); } } } //pwm=pwmr; } } void main() //主函数 { zkb=2; init(); while(1) { keyscan(); } } void time0(void) interrupt 1 //中断函数 { TH0=(65536-200)/256; TL0=(65536-200)%256; ++i; if(i>10) { i=0; }; if(i<=zkb) { P2_0=1; } else P2_0=0; } /*void time0(void) interrupt 0 //中断函数 { TH0=(65536-1000)/256; TL0=(65536-1000)%256; ++i; if(i>10) { i=0; }; if(i<=zkb) { P2_0=1; } else P2_0=0; }*/
标签: 调光
上传时间: 2016-07-02
上传用户:184890962
MC30E6060 是一款码带 2K 位串行 EEPROM 的高性能 8 位 OTP 型 MCU,内置高精度 RC 振荡器。产品的高 抗干扰性能为小家电产品提供良好的解决方案。
标签: MC30E6060
上传时间: 2016-08-18
上传用户:zengduo
MC30P011 是一款高性能 8 位 OTP 型 MCU,内置高精度 RC 振荡器。产品的高抗干扰性能为小家电产品提 供良好的解决方案。
标签: MC30P011
上传时间: 2016-08-18
上传用户:zengduo
8 位 RISC CPU 内核 1K*14 位程序存储器空间(OTP),5 级深度硬件堆栈 48 字节 SRAM
标签: MC30P081
上传时间: 2016-08-18
上传用户:zengduo
MC30P6060采用高速低功耗CMOS工艺设计开发的8位高性能精简指令单片机,内部有1k*14位一次性可编程ROM(OTP-ROM),49×8位的数据存储器(RAM),两个双向i/o,1个8位Timer定时器/计数器
标签: MC30P6060
上传时间: 2016-08-18
上传用户:zengduo
MC30P6060采用高速低功耗CMOS工艺设计开发的8位高性能精简指令单片机,内部有1k*14位一次性可编程ROM(OTP-ROM),49×8位的数据存储器(RAM),两个双向i/o,1个8位Timer定时器/计数器
标签: MC30P6060
上传时间: 2016-08-18
上传用户:zengduo
在本课中,我们要用一个按键来实现跑马灯的 10 级调速。这又会涉及到键的去抖的问 题。 本课的试验结果是,每按一次按键,跑马速度就降低一级,共 10 级。 这里我们又增加了一个变量 speedlever,来保存当前的速度档次。 在按键里的处理中,多了当前档次的延时值的设置。 请看程序: ―――――――――――――――― #define uchar unsigned char //定义一下方便使用 #define uint unsigned int #define ulong unsigned long #include <reg52.h> //包括一个 52 标准内核的头文件 sbit P10 = P1^0; //头文件中没有定义的 IO 就要自己来定义了 sbit P11 = P1^1; sbit P12 = P1^2; sbit P13 = P1^3; sbit K1= P3^2; bit ldelay=0; //长定时溢出标记,预置是 0 uchar speed=10; //设置一个变量保存默认的跑马灯的移动速度 uchar speedlever=0; //保存当前的速度档次 char code dx516[3] _at_ 0x003b;//这是为了仿真设置的 //一个按键控制的 10 级变速跑马灯试验 void main(void) // 主程序 { uchar code ledp[4]={0xfe,0xfd,0xfb,0xf7};//预定的写入 P1 的值 uchar ledi; //用来指示显示顺序 uint n; RCAP2H =0x10; //赋 T2 的预置值 0x1000,溢出 30 次就是 1 秒钟 RCAP2L =0x00; TR2=1; //启动定时器 ET2=1; //打开定时器 2 中断 EA=1; //打开总中断 while(1) //主程序循环 { if(ldelay) //发现有时间溢出标记,进入处理 { ldelay=0; //清除标记 P1=ledp[ledi]; //读出一个值送到 P1 口 ledi++; //指向下一个 if(ledi==4) { ledi=0; //到了最后一个灯就换到第一个 } } if(!K1) //如果读到 K1 为 0 { for(n=0;n<1000;n++); //等待按键稳定 while(!K1); //等待按键松开 for(n=0;n<1000;n++); //等待按键稳定松开 speedlever++; if(speedlever==10)speedlever=0; speed=speedlever*3; //档次和延时之间的预算法则,也可以用查表方法,做出 不规则的法则 } } } //定时器 2 中断 timer2() interrupt 5 { static uchar t; TF2=0; t++; if((t==speed)||(t>30)) //比较一个变化的数值,以实现变化的时间溢出,同时限制了最慢速 度为 1 秒 { t=0; ldelay=1;//每次长时间的溢出,就置一个标记,以便主程序处理 } } ―――――――――――――――――――――― 请打开 lesson11 目录的工程,编译,运行,看结果: 按 K1,速度则降低一次,总共 10 个档次。
上传时间: 2017-11-06
上传用户:szcyclone
LED 一般是恒流操作的,如何改变 LED 的亮度呢?答案就是 PWM 控制。在一定的 频率的方波中,调整高电平和低电平的占空比,即可实现。比如我们用低电平点亮一个 LED 灯,我们假设把一个频率周期分为 10 个时间等份,如果方波中的高低电平占空比是 9:1, 这是就是一个比较暗的亮度,如果方波中高低电平占空比是 10:0,这时,全部是高电平, 灯是灭的。如果占空比是 5:5,就是一个中间亮度,如果高低比是 1:9,是一个比较亮的 亮度,如果高低是 0:10,这时全部是低电平,就是最亮的。 实际上应用中,电视屏幕墙中的几十百万 LED 象素都是这样控制的,而且每一个象素 都有红绿蓝 3 个 LED,每个 LED 可以变化的亮度是几百到几万或者更多的级别,以实现真 彩色的显示。还有在您的手机中,背光灯的亮度如果是可以变化的,也应该是这种工作方式。 目前的城市彩灯也有很多都使用了 LED,需要控制亮度是也是 PWM 控制。 下面来分析我们的例程,在这个例程中,我们将定时器 2 溢出定为 1/1200 秒。每 10 次脉冲输出一个 120HZ 频率。这每 10 次脉冲再用来控制高低电平的 10 个比值。这样,在 每个 1/120 秒的方波周期中,我们都可以改变方波的输出占空比,从而控制 LED 灯的 10 个 级别的亮度。 为什么输出方波的频率要 120HZ 这么高?因为如果频率太低,人眼就会看到闪烁感 觉。一般起码要在 60HZ 以上才感觉好点,120HZ 就基本上看不到闪烁,只能看到亮度的变 化了。 下面请看程序,程序中有比较多的注释: ――――――――――――――――――――――― #define uchar unsigned char //定义一下方便使用 #define uint unsigned int #define ulong unsigned long #include <reg52.h> //包括一个 52 标准内核的头文件 sbit P10 = P1^0; //要控制的 LED 灯 sbit K1= P3^2; //按键 K1 uchar scale;//用于保存占空比的输出 0 的时间份额,总共 10 份 char code dx516[3] _at_ 0x003b;//这是为了仿真设置的 //模拟 PWM 输出控制灯的 10 个亮度级别 void main(void) // 主程序 { uint n; RCAP2H =0xF3; //赋 T2 的预置值,溢出 1 次是 1/1200 秒钟 RCAP2L =0x98; TR2=1; //启动定时器 ET2=1; //打开定时器 2 中断 EA=1; //打开总中断 while(1) //程序循环 { ;//主程序在这里就不断自循环,实际应用中,这里是做主要工作 for(n=0;n<50000;n++); //每过一会儿就自动加一个档次的亮度 scale++; if(scale==10)scale=0; } } //1/1200 秒定时器 2 中断 timer2() interrupt 5 { static uchar tt; //tt 用来保存当前时间在一秒中的比例位置 TF2=0; tt++; if(tt==10) //每 1/120 秒整开始输出低电平 { tt=0; if(scale!=0) //这里加这一句是为了消除灭灯状态产生的鬼影 P10=0; } if(scale==tt) //按照当前占空比切换输出高电平 P10=1; } ―――――――――――――――――― 在主程序中,每延时一段时间,就自动换一个占空比,以使亮度自动变化,方便观察。 编译,运行,看结果。 可以看到,LED 的亮度以每种亮度 1 秒左右不断变化,共有 10 个级别。
上传时间: 2017-11-06
上传用户:szcyclone