完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
设计要求:
STC15W101芯片,1脚按键接地,5脚PWM输出用于调光,6脚接红LED,7脚接绿LED,8脚接蓝LED,三个自检灯负极接地(高电平亮) 通电时,芯片自检,三个灯闪亮一下。 开机时,按住按键,达到1秒钟时,三个指示灯按8绿→7红→6蓝的顺序依次点亮一下,一次只亮一个灯,每个灯亮的时间约1秒,这期间5脚无输出。 三个自检灯依次亮完后,蓝灯熄灭,返回到绿灯长亮,此时5脚有输出,是最小档(即1档,占空比20%)。 点一下按键(要求是按下去的时刻),会增加一档PWM,指示灯点亮的组合也不同(此时是绿+蓝,2档),依次点击按钮,共有五档,5脚占空比逐档变大,第五档最大(100%),再按一下又回到最低档(绿灯亮,占空比20%),继续按又增加一档,指示灯的组合也 同步变化……点击按钮可以反复循环……12345档的PWM宽度依次加大(20%,40%,60%,80%,100%),每档对应点亮的指示灯是:1、绿。2、绿+蓝。3、蓝。4、蓝+红。5、红。 不管在哪个档位工作时,按住按键达到1秒时就关机,三个指示灯和负载全灭。芯片进入掉电状态。 PWM频率500Hz。 程序部分: /************* 功能说明 ************** 使用timer0模拟16通道PWM驱动程序。 定时器中断频率一般不要超过100KHZ, 留足够的时间给别的程序运行. 本例子使用33.1776MHZ时钟, 50K的中断频率, 100级PWM, 周期为2ms. 中断里处理的时间不超过4us, 占CPU时间大约为25%. pwm 频率为500HZ ******************************************/ #include #define MAIN_Fosc 33177600UL //定义主时钟 #define Timer0_Rate 50000 //中断频率 typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; //sfr AUXR = 0x8E; #define Timer0_Reload (65536UL -(MAIN_Fosc / Timer0_Rate)) //Timer 0 重装值 //************** PWM8 变量和常量以及IO口定义 *************** //******************** 8通道8 bit 软PWM ******************** #define PWM_DUTY_MAX 100 // 0~255 PWM周期, 最大255 #define PWM_ON 1 // 定义占空比的电平, 1 或 0 #define PWM_OFF (!PWM_ON) #define PWM_ALL_ON (0xff * PWM_ON) /// #define LAMP_ON 1 #define LAMP_OFF 0 //I/O设置 ***it pwm_out=P3^0; ***it red_lamp=P3^1; ***it green_lamp=P3^2; ***it blue_lamp=P3^3; ***it key_in=P3^4; // //档位占空比设置 #define one_dang 20 //一档 #define two_dang 40 //二档 #define three_dang 60 //三档 #define four_dang 80 //四档 #define five_dang 100 //五档 six seven eight nine ten #define dianan 2000 //点按 #define duanan 4000 //短按 #define changan 8000 //长按 u8 dangshu; //在某个档,存某个档的占空比数 u8 dangcount; //档位存储 u8 pwm_duty; //周期计数值 u16 key_jishu; bit key_down; bit kaiji_f; //标志开机 bit huandang; //档位记录 /**********************************************/ void delay(u16 x) { do{x=x-1;WDT_CONTR=0x3c;}while(x>0); } // //开机自检 void kaiji_lamp_out(void) { u8 i; //绿红兰依次点亮一下,每次只亮一个灯,每个亮灯时间约0.4秒(0.2~0.4秒) green_lamp=LAMP_ON; for(i=0;i<100;i++){delay(15000);} green_lamp=LAMP_OFF; red_lamp=LAMP_ON; for(i=0;i<100;i++){delay(15000);} red_lamp=LAMP_OFF; blue_lamp=LAMP_ON; for(i=0;i<100;i++){delay(15000);} blue_lamp=LAMP_OFF; for(i=0;i<100;i++){delay(15000);} green_lamp=LAMP_ON; pwm_out=PWM_ON; for(i=0;i<100;i++){delay(15000);} pwm_out=PWM_OFF; } /////按键 void int2() interrupt 10 { INT_CLKO&=0xef; //先关中断,系统会自动清除中断标志 } ///// void huandang_chuli() { if(huandang) { huandang=0; green_lamp=blue_lamp=red_lamp=LAMP_OFF; switch(dangcount) { case 0: dangshu=one_dang; green_lamp=LAMP_ON; break; case 1: dangshu=two_dang; green_lamp=blue_lamp=LAMP_ON; break; case 2: dangshu=three_dang; blue_lamp=LAMP_ON; break; case 3: dangshu=four_dang; blue_lamp=red_lamp=LAMP_ON; break; case 4: dangshu=five_dang; red_lamp=LAMP_ON; break; default: dangshu=one_dang; green_lamp=LAMP_ON; break; } } } void main(void) { //char i; green_lamp=blue_lamp=red_lamp=LAMP_OFF; dangshu=one_dang; dangcount=0; key_jishu=0; pwm_out=PWM_OFF; key_down=0; kaiji_f=0; huandang=0; pwm_duty=0; //INT_CLKO|=0x10; //打开按键唤醒功能 AUXR |= (1<<7); // Timer0 set as 1T mode TMOD &= ~(1<<2); // Timer0 set as Timer TMOD &= ~0x03; // Timer0 set as 16 bits Auto Reload TH0 = Timer0_Reload / 256; //Timer0 Load TL0 = Timer0_Reload % 256; ET0 = 1; //Timer0 Interrupt Enable PT0 = 1; //高优先级 //TR0 = 1; //Timer0 Run EA = 1; //打开总中断 while(1) { if(!key_in){ if(key_jishu<60000){key_jishu++;} if(!kaiji_f) //若是关机时,长按则开机 { if(key_jishu>duanan) {kaiji_f=1;kaiji_lamp_out();pwm_out=PWM_ON; dangshu=one_dang;TR0 = 1;key_jishu=0;do{delay(1000);}while(!key_in);} else { delay(200); if(key_in){key_jishu=0;} } } else //开机时 {key_down=1; delay(200); if(!key_in) { if((key_jishu>(dianan-2000))&&(key_jishu<(dianan+1000))&&(kaiji_f)) //换档 {huandang=1;if(dangcount<4)dangcount++;else{dangcount=0;}} huandang_chuli(); key_jishu=0; do{delay(1000); if(key_jishu<60000){key_jishu++;} if((key_jishu>changan)&&(kaiji_f)) //按1秒关机 {key_down=0;kaiji_f=0; key_jishu=0;TR0 = 0;pwm_out=PWM_OFF;green_lamp=blue_lamp=red_lamp=LAMP_OFF;INT_CLKO|=0x10;PCON|=0x02;} }while(!key_in); key_down=0; key_jishu=0; } } } delay(200); //假如10000次延时200US,如果不是需要调整 } } /********************** Timer0 40us中断函数 ************************/ void timer0 (void) interrupt 1 { if(++pwm_duty == PWM_DUTY_MAX) //PWM周期结束,重新开始新的周期 { pwm_duty = 0; pwm_out=PWM_ON; } if(pwm_duty>=dangshu){pwm_out=PWM_OFF;} } 现在的问题是: 一直不断电工作,长按按键1秒关机后可以掉电,再开机,按第一下无反应,但已经重新上电了(此时灯不亮,但有十几mA电流,电池会耗尽哦!!!),松手再长按一次才可以开机成功(亮灯开始自检),为什么要按两下?怎么解决? 另外,按键有点跳档的状况(就像连续按了两次一样),如何改善?特别是自检完后,1档转2档时,按一下很容易到3档(按键没问题) 如何精简程序?(现在编译后是530字节,如何小于500字节,这样可以选择STC15W100芯片) 恳请各位高手帮忙分析改善程序,小弟感激不尽。。。 |
|
相关推荐
2个回答
|
|
这个我也是,同样的问题,怎么解决呢
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
327 浏览 0 评论
527 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-串口通讯编程示例之串口编写程序
1045 浏览 0 评论
STM32系列单片机可以让自己的GPIO去控制自己的RESET吗?有什么风险?可以规避吗?
1402 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-串口通讯编程示例之串口参数设置
836 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11581 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-10-31 18:56 , Processed in 0.644323 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号