虽然是个简单的东西但是花了好长时间,写程序期间遇到了好多问题,然后慢慢的修改,直到完成,能够做出来感觉很欣慰,特此上传来共同学习进步。
头灯功能说明书原理图
1.按键按第一下LED1和LED3亮,再按亮LED2,再按全灭。如此循环。
2.关灯状态下,长按2秒以上进入电量指示,电池3.9V以上LED123全部微亮表示满电。
3.电池电压3.6-3.9V,LED2,LED3微亮,电池3.6V以下,LED3微亮。
4.另外,LED2点亮状态下,单片机检测电池电压,电压低于3.2V时,LED2亮5s,关0.5s,重复。
电路原理图如下:
程序截图:
单片机源程序如下:
- #include "syscfg.h"
- #include "MS83Fxx02.h"
- #define _XTAL_FREQ 4000000 //4T,此定义详解请看MS_Q&A_Sheet.pdf文档
- #define LED1 RC2
- #define LED2 RC4
- #define LED3 RA1
- #define KEY RA6
- //#define LED4 RC3//ad转换结果测试
- unsigned char keycount=0,LEDCOUNT=0,t=0;
- unsigned int flagecount=0,LED1COUNT=0,count=0,count1=0;
- unsigned long advalue=0;
- bit flage=0,flageled2=0,flageled=0,flage3=0;
- float adcvalue=0;
- void ENABLE_INTERRUPT(void);
- void interrupt ISR(void);
- void DEVICE_INIT(void);
- void Keycan(void);
- void ADC_INIT(void);
- void Led1_lighter(void);
- void Led2_lighter(void);
- void Led3_lighter(void);
- void Float_adcvalue(void);
- void Keycan(void);
- void TIMER1_INIT(void);
- /*====================================================
- *函数名:main
- *功能:主函数
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void main(void)
- {
- DEVICE_INIT(); //器件初始化
- ADC_INIT(); //adc初始化
- TIMER1_INIT(); //定时器1初始化
- keycount=0;
- LED1=0;
- LED2=0;
- LED3=0;
- ENABLE_INTERRUPT();//进入定时器中断
- while(1)
- { CLRWDT();
- if(!flage) Keycan();
- if(flage||flageled) Float_adcvalue();
- }
- }
- /*====================================================
- *函数名:interrupt ISR
- *功能:中断服务函数
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void interrupt ISR(void)
- {
- if(T0IE&&T0IF&&!flage3)
- {
- T0IF = 0;
- TMR0 = 6;//(256-6)*4=1000us=1ms
- if(flageled2) LEDCOUNT++;
-
- if(LEDCOUNT==100)
- {
- LEDCOUNT=0;
- count++;
- if(count==50)
- { count=0;
- LED2=0;
- //__delay_ms(500);
- TMR1ON=1;flage3=1;
- }
-
- }
-
-
-
- }
- if(TMR1IE&&TMR1IF)
- {
- TMR1IF = 0;
- TMR1H = 0xFC;
- TMR1L = 0x17;//重装初值定时时间1ms
- if(flage3){count1++;}
- else LED1COUNT++;
- if(count1==500){LED2=1;count1=0;flage3=0;}
- if(LED1COUNT==3000) {TMR1ON=0;flage=0;LED1COUNT=0;}
- }
- }
- /*====================================================
- *函数名:DEVICE_INIT
- *功能:上电器件初始化
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void DEVICE_INIT(void)
- {
- OSCCON = 0B01010001; //Bit7 >>> LFMOD=0 >>> WDT振荡器频率=32KHz
- //Bit6:4 >>> IRCF[2:0]=101 >>> 内部RC频率=4MHz
- //Bit0 >>> SCS=1 >>> 系统时钟选择为内部振荡器
- MSCKCON = 0B00000000;//Bit6 >>> VREG_OE=0 >>> 禁止稳压输出
- //Bit5 >>> T2CKSRC=0 >>> Timer2时钟源为系统时钟
- //Bit4 >>> SLVREN=0 >>> 关闭LVR
- INTCON = 0B00000000; //暂禁止所有中断
- CMCON0 = 0B00000111; //关闭比较器,CxIN为数字IO口
- ANSEL = 0B10000000; //所有IO口都为数字IO
- PORTA = 0B00000000;
- TRISA = 0B01000000; //RA0,RA6为输入,其他为输出
- WPUA = 0B01000000; //关闭PORTA口的内部上拉除RA6
- PORTC = 0B00000000;
- TRISC = 0B00000000; //设置所有PORTC口为输出
- WPUC = 0B00000000; //关闭启PORTC口所有上拉
- OPTION = 0B00000000; //bit7=0,开启PORTA内部上拉总闸
-
-
- }
- /*====================================================
- *函数名:ENABLE_INTERRUPT
- *功能:开启所需中断
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void ENABLE_INTERRUPT(void)
- {
- T0IF = 0; //清TIMER0中断标志位
- T0IE = 1; //使能TIMER0中断
- TMR1IF = 0; //清TIMER1中断标志位
- TMR1IE = 1; //使能TIMER1中断
- PEIE = 1; //开启外设总闸 timer1属于外设
- GIE = 1; //开启总中断
- }
- /*====================================================
- *函数名:TIMER1_INIT
- *功能:Tiemr1初始化
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void TIMER1_INIT(void)
- {
- TMR1H = 0xFC;
- TMR1L = 0x17; //Timer1初值为0xFC17=64535
- T1CON = 0B00000000; //预分频值5,4位 11=1:8
- // 10=1:4
- // 01=1:2
- // 00=1:1
-
- }
- /*====================================================
- *函数名:Keycan
- *功能:按键函数
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void Keycan(void)
- {if(KEY==0)
- __delay_ms(20);
- if(KEY==0)
- {
-
-
- while(!KEY)
- {__delay_ms(10);
- flagecount++;
- if((LED1==0)&&(LED2==0)&&(LED3==0)&&(flageled==0)&&(flagecount>299))//这里加flageled=0是为了处在LED2亮灯状态时长按出现电量提示
- break;
- }
-
- if(flagecount>299)
- {if((LED1==0)&&(LED2==0)&&(LED3==0)&&(flageled==0))//这里加flageled=0是为了处在LED2亮灯状态时长按出现电量提示
- {flage=1;
- flagecount=0;
- }
- else goto begin;
- }
- else
- {
- {if(flage==0)
- { begin:keycount++;
- flagecount=0;flage=0;
- switch(keycount)
- {case 1:LED1=1;LED2=0;LED3=1;flageled=0;flageled2=0;break;
- case 2:LED1=0;LED2=1;LED3=0;flageled=1;flageled2=0;break;
- case 3:LED1=0;LED2=0;LED3=0;keycount=0;flageled=0;flageled2=0;break;
- default: break;
- }
- }
- }
- }
- }
- }
- /*====================================================
- *函数名:ADC_INIT
- *功能:比较器初始化
- *输入参数:无
- *返回参数:无
- ====================================================*/
- void ADC_INIT(void)
- {
- ANSEL = 0B10000000; //设置RA0为模拟输入口
- ADCON1 = 0B01100000; //DIVS=0,时钟选FOSC
- //ADCS[2:0]=110,分频FOSC/64
- ADCON0 = 0B10111100; //B7,ADFM=1,结果右对齐
- //B6:5,VCFG=00,参考电压VDD
- //B6:5,VCFG=01,参考电压内部2V
- //B6:5,VCFG=10,参考电压内部3V
- //B6:5,VCFG=11,参考电压Vref
- //B4:2,CHS=000,选择AN7通道
- //B1,GO,AD转换状态位
- //B0,ADON=1,ADC使能
-
- }
- /*====================================================
- *函数名:GET_ADC_VALUE
- *功能:开启AD转换,参考电压为VDD
- *输入参数:ADC通道数
- *返回参数:采样到的AD值
- ====================================================*/
- unsigned int GET_ADC_VALUE()
- {
- unsigned int TempADCBuffer=0;
- ADCON0 |= 0b10000001; //开启ADC电路
- __delay_us(10); //等待采集到电压
- GO_DONE = 1; //开启转换
- while(GO_DONE==1) CLRWDT();//等待转换完成
- TempADCBuffer = ADRESH;
- TempADCBuffer = (TempADCBuffer<<8)|ADRESL;
- ADON = 0;
- return(TempADCBuffer);
- }
- /*====================================================
- *函数名:u16_adcvalue
- *功能:开启AD转换,参考电压为VDD
- *输入参数:ADC通道数
- *返回参数:采样到的AD值
- ====================================================*/
- void Float_adcvalue(void)
- { unsigned char i;
- for(i=0;i<20;i++)
- { advalue+=GET_ADC_VALUE();}
- advalue=advalue/20;
- adcvalue=advalue;
- adcvalue=adcvalue/1023*2.0000;
- //if(adcvalue>2) Led1_lighter();
- if(flageled)
- {if(adcvalue<0.80) flageled2=1;
- else {flageled2=0;LED1=0;LED2=1;LED3=0;}
- }
-
-
- else
- { flageled=0;flageled2=0;
- if(adcvalue>=1.07)
- { Led1_lighter();}
- if(adcvalue<1.07,adcvalue>=0.98)
- { Led2_lighter();}
- if(adcvalue<0.98)
- {Led3_lighter();}
- TMR1ON=1;
-
- }
- }
- /*====================================================
- *函数名:Led1_lighter()
- *功能:微亮3个灯
- *输入参数:
- *返回参数:
- ====================================================*/
- void Led1_lighter(void)//微亮3个灯
- {LED1=1;LED2=1;LED3=1;
- __delay_us(500);
- LED1=0;LED2=0;LED3=0;
- //__delay_us(1);
- }
- /*====================================================
- *函数名:Led2_lighter()
- *功能:微亮2个灯
- *输入参数:
- *返回参数:
- ====================================================*/
- void Led2_lighter(void)//微亮2个灯
- {LED1=0;LED2=1;LED3=1;
- __delay_us(500);
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
全部资料51hei下载地址:
头灯制作.zip
(201.87 KB, 下载次数: 89)
|