原裝汽車警示燈是雙閃,頻率大概是1Hz±10%。本文介紹一種后裝鋰電池供電爆閃警示+照明燈,采用輝芒微單片機對閃燈控制和電池電量指示,803450軟包鋰電池+4056充電管理芯片,2835琥珀色LEDx16+2835冷白LEDx5,低成本完成電路制作。
先上成品圖:
再上原理圖:
然后上代碼:
/* 文件名:3.7V爆閃燈程序
* 功能:
* IC: FMD61FC22A-RB/S14
* 晶振: 16M/2T
* 說明: 程序通過KEY(PA4)端口低電平次數確定輸出模式
* 0.休眠狀態,電流小于4uA
* 1.爆閃狀態,峰值電流1A,可調
* 2.照明狀態。
* 充電和工作時4燈電量指示 。
*
* FT61F023 SOP16
* ---------------
* VDD---------|1(VDD) (VSS)14|--------GND
* LEDY--------|2(PA7) (PA0)13|---------TC
* LEDW--------|3(PA6) (PA1)12|---------NC
* KEY---------|4(PA4) (PA2)11|---------AD
* L1----------|5(PC3) (PA3)10|---------SW
* L2----------|6(PC2) (PC0)09|---------NC
* L3----------|7(PC4) (PC1)08|---------L4
* ---------------
*/
#include "SYSCFG.h"
//*************************宏定義***************************
#define U8 unsigned char
#define UF unsigned int
#define UL unsigned long
#define LY PA7 //黃燈
#define LW PA6 //白燈
#define AD PA2 //AD PIN
#define SW PA3 //ADC開關
#define TC PA0 //充電檢測
#define KEY PA4 //功能選擇
#define LD4 PC3 //電量25指示
#define LD3 PC2 //電量50指示
#define LD2 PC4 //電量75指示
#define LD1 PC1 //電量99指示
U8 ValT0 = 159;
U8 ReadAPin;
U8 KEYCNT;
U8 flashT;
U8 TMLY;
U8 T5MS;
volatile bit KEYT;
U8 TT20;
U8 T10S;
volatile bit FL2HZ;
volatile bit KEYSTA;
volatile UF TestADC;
/*-------------------------------------------------
* 函數名:POWER_INITIAL
* 功能: 上電系統初始化
* 輸入: 無
* 輸出: 無
--------------------------------------------------*/
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2T=8MHz,0.125us
INTCON = 0; //暫禁止所有中斷
PORTA = 0B00000000;
TRISA = 0B00010101; //PA輸入輸出 1-輸入 0-輸出
//PA.4.2.0-輸入,7.6.輸出
PORTC = 0B00000000;
TRISC = 0B00000000; //PC輸入輸出 1-輸入 0-輸出
WPUA = 0B00010000; //PA4,0口上拉
WPUC = 0; //禁止所有PC口上拉
OPTION = 0B00000000; //Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
MSCKCON = 0B00000000;
//Bit6: 0-禁止PA4,PC5穩壓輸出
//Bit5: 0-TIMER2時鐘為Fosc
//Bit4: 0-禁止LVR
WDTCON = 0B00001111;
CMCON0 = 0B00000111; //關閉比較器,CxIN為數字IO口
}
/*-------------------------------------------------
* 函數名:DelayUs
* 功能: 短延時函數 --16M-2T--大概快1%左右.
* 輸入: Time 延時時間長度 延時時長Time Us
* 輸出: 無
-------------------------------------------------*/
void DelayUs(U8 Time)
{
U8 a;
for(a=0;a{
NOP();
}
}
/*-------------------------------------------------
* 函數名:DelayUs
* 功能: 短延時函數 --16M-2T--大概快1%左右.
* 輸入: Time 延時時間長度 延時時長Time Us
* 輸出: 無
-------------------------------------------------*/
void Delayms(U8 Time)
{
U8 a,b;
b =250;
for(a=0;a{
while (b--)
{
NOP();
NOP();
}
}
}
/*-------------------------------------------------
* 函數名: ADC_INITIAL
* 功能: ADC初始化
* 輸入: 無
* 輸出: 無
--------------------------------------------------*/
void ADC_INITIAL (void)
{
ADCON1 = 0B01100000;
//DIVS=0,時鐘選FOSC
//ADCS[2:0]=110,分頻FOSC/64
ADCON0 = 0B10101001; //內部2V參考
//Bit7: ADFM=1,結果右對齊
//Bit[6:5]: VCFG參考電壓
// 00-參考電壓VDD
// 01-參考電壓內部2V
// 10-參考電壓內部3V
// 11-參考電壓Vref
//Bit[4:2]: CHS=010-選擇AN2通道
//Bit1: GO,AD轉換狀態位
//Bit0: ADON=1,ADC使能
ANSEL = 0B00000100; //使能AN2為模擬輸入
SW = 0; //對地導通
}
/*-------------------------------------------------
* 函數名: GET_ADC_DATA
* 功能: 讀取通道ADC值
* 輸入: AN_CN 通道序號
* 輸出: INT類型AD值(單次采樣無濾波)
--------------------------------------------------*/
UF GET_ADC_DATA (U8 AN_CH)
{
// U8 i;
U8 ADCON0Buff;
UF tBuffer = 0;
UF ADC_DATA=0;
ADCON0Buff = ADCON0 & 0B11100011;//清空通道值;a++)
;a++)
AN_CH <<=2; ? ? ? ? ? ? ?
ADCON0Buff |= AN_CH; //Bit[4:2]:CHS=010,選擇AN2通道
ADCON0 = ADCON0Buff; //重新加載通道值
DelayUs(30);
GO_DONE = 1; //啟動ADC
while( GO_DONE==1 ); //等待ADC轉換完成
ADC_DATA = ADRESH;
ADC_DATA <<=8;
ADC_DATA |= ADRESL; //10Bit ADC值整合
tBuffer = ADC_DATA;
return tBuffer;
}
/*-------------------------------------------------
* 函數名:PA2_Level_Change_INITIAL
* 功能: PA端口(PA2)電平變化中斷初始化
* 輸入: 無
* 輸出: 無
--------------------------------------------------*/
void PA2_Level_Change_INITIAL(void)
{
ANSEL &= 0B11101110; //關閉中斷引腳模擬輸入功能
// TRISA4 = 1; //設置A4輸入
// TRISA0 = 1; //設置A0輸入
TRISA |= 0x11;
ReadAPin = PORTA; //清PA電平變化中斷
PAIF = 0; //清PA INT中斷標志位
IOCA4 = 1; //使能PA4電平變化中斷
IOCA0 = 1;
PAIE = 1; //使能PA INT中斷
}
/*----------------------------------------------------
* 函數名:LEDON
* 功能: 按檢測電壓正確亮燈
----------------------------------------------------*/
void LEDON()
{
// FLTC = TC;
// TAAG = TC|FL2HZ;
if (TestADC<800) {LD1 = (flashT<10)&FL2HZ; LD2=0; LD3=0; LD4=0;} ? ? ?
//<25,3.3V,3.2/4.2*1024=780. ? F000
if ((TestADC>799)&&(TestADC<872)) {LD1=(flashT<10); LD2=(flashT<10)&FL2HZ; LD3=0; LD4=0;}?
//<50,3.6V/4.2*1024=902. ? ? ? 1F00
if ((TestADC>871)&&(TestADC<945)) {LD1=(flashT<10); LD2=(flashT<10); LD3=(flashT<10)&FL2HZ; LD4=0;}?
//<75,3.9V/4.2*1024=950 ? ? ? ?11F0
if ((TestADC>944)&&(TestADC<1013)) {LD1=(flashT<10); LD2=(flashT<10); LD3=(flashT<10); LD4=(flashT<10)&FL2HZ;}?
//<100,4.16V/4.2*1024=999 ? ? ? 111F
if (TestADC>1012) {LD1=(flashT<10); LD2=(flashT<10); LD3=(flashT<10); LD4=(flashT<10);}?
//>=100
}
/*----------------------------------------------------
* 函數名:TIMER0_INITIAL
* 功能: 初始化設置定時器
* 設置TMR0定時時長=4T*預分頻值*(255-VALT0)
----------------------------------------------------*/
void TIMER0_INITIAL (void)
{
OPTION = 0B00000001; //預分頻4(0:2,1:4,2:8,3:16)
TMR0 = ValT0;
T0IF = 0; //清空T0軟件中斷標志位
}
/*-------------------------------------------------
* 函數名:interrupt ISR
* 功能: 中斷處理函數
* 輸入: 無
* 輸出: 無
--------------------------------------------------*/
void interrupt ISR(void)
{
/*************************電平變化中斷*************************/
if(PAIE && PAIF)
{
ReadAPin = PORTA; //讀取PORTA數據清PAIF標志
PAIF = 0; //清PAIF標志位
PAIE = 0; //暫先禁止PA4中斷
IOCA4 = 0; //禁止PA4電平變化中斷
IOCA0 = 0;
if (!KEY)
{
Delayms(20);
if (!KEY) KEYCNT++;
}
if (KEYCNT>2) KEYCNT=0;
// while (KEY==0){PORTC = 0x00;}
}
/******************定時器0的中斷處理*************************/
if(T0IE && T0IF)
{
TMR0 = ValT0; //100us中斷一次
T0IF = 0;
CLRWDT();
flashT++;
if (flashT>50) //5mS計數
{
flashT=0;
T5MS++;
}
if (T5MS>9) //50mS計數
{
T5MS=0;
TT20++;
TMLY++;
}
if (TT20>24) //50*25=1250mS
{
TT20=0;
if (TC) FL2HZ = ~FL2HZ;
else FL2HZ = 1;
T10S++;
if (T10S>7) //1.25*8=10S
{
T10S = 0;
// if (TC)
// {
TestADC = GET_ADC_DATA(2);
NOP();
NOP();
// }
}
}
if ((KEYCNT>0)||(TC==1))
{
LEDON();
}
if (KEYCNT==1)
{
LW = 0;
if (TMLY<6) LY=1;
if (TMLY==6|TMLY==7) LY=0;
if (TMLY>7&TMLY<14) LY=1;
if (TMLY==14|TMLY==15) LY=0;
if (TMLY>15&TMLY<21) LY=1;
if (TMLY>20&TMLY<48) LY=0;
if (TMLY>47) TMLY=0;
}
if (KEYCNT==2) {LW = 1; LY = 0;}
}
}
/*-------------------------------------------------
* 函數名: main
* 功能: 主函數
* 輸入: 無
* 輸出: 無
--------------------------------------------------*/
void main()
{
POWER_INITIAL(); //系統初始化
TIMER0_INITIAL(); //定時器初始化
ADC_INITIAL(); //ADC初始化
PA2_Level_Change_INITIAL();
GIE = 1;
T0IE = 1; //開T0中斷
TestADC = GET_ADC_DATA(2);
NOP();
NOP();
KEYT = 1;
LW = 1;
DelayUs(250);
LW = 0;
while(1)
{
if (KEY) {GIE=1;PAIE=1;IOCA4=1;IOCA0 = 1;T0IE = 1;}
// if (TC==0) //未在充電
// {
if (KEYCNT==0) //按鍵0狀態
{
LW = 0;
LY = 0;
if (TC==0) //未在充電
{
PORTC = 0x00;
SW = 1; //上拉斷電
ADCON0 &=0xFE; //用電大戶
ANSEL = 0B00000000; //關閉模擬輸入
AD = 1; //上拉斷電
T0IE=0;
PA2_Level_Change_INITIAL();
KEYT = 1;
PSA = 1;
NOP();
SLEEP ();
}
}
else if (KEYT==1)
{
KEYT = 0;
PSA = 0;
PAIE = 1;
IOCA4 = 1;
IOCA0 = 1;
T0IE = 1;
ADC_INITIAL();
}
}
}
================================================
輸出波形:
BOM和成本:
品名 | 規格 | 用量 | 位置 | 單價 | 計價 |
PCB1 | 73*73*1.2單面22F | 1 | 主板 | ¥1.500 | ¥1.50 |
PCB2 | 30.5*31.5*1.2雙面FR4 | 1 | 指示燈 | ¥0.350 | ¥0.35 |
貼片LED | 0805普綠 | 4 | ¥0.020 | ¥0.08 | |
MicroUsb | B | 1 | ¥0.100 | ¥0.10 | |
輕觸開關 | 6*6*9 | 1 | ¥0.080 | ¥0.08 | |
0.1uF | C0603 | 2 | C4, C5 | ¥0.010 | ¥0.02 |
10K | R0603 | 2 | R3, R10 | ¥0.005 | ¥0.01 |
10K | R1206 | 6 | R1, R2, R6, R7, R8, R9 | ¥0.006 | ¥0.04 |
10uF | C0805 | 3 | C1, C2, C3 | ¥0.030 | ¥0.09 |
1K | R0603 | 1 | R5 | ¥0.005 | ¥0.01 |
20K | R0603 | 1 | R4 | ¥0.005 | ¥0.01 |
S8050 | SOT23 | 2 | Q3, Q4 | ¥0.030 | ¥0.06 |
CL4056 | ESOP8 | 1 | U2 | ¥0.200 | ¥0.20 |
MCU-SO8 | SO16 | 1 | U1 | ¥0.650 | ¥0.65 |
RED | LED3528-C | 6 | WD1-6 | ¥0.040 | ¥0.24 |
RED | LED3528-W | 16 | YD1-16 | ¥0.060 | ¥0.96 |
SI2302 | SOT23 | 2 | Q1, Q2 | ¥0.050 | ¥0.10 |
BAT803450 | 1500mAH | 1 | ¥1.750 | ¥1.75 | |
smt+焊接 | SMT:0.50,焊接:0.60 | 1 | ¥1.100 | ¥1.10 | |
合計 | ¥7.336 |
審核編輯:湯梓紅
-
原理圖
+關注
關注
1297文章
6338瀏覽量
233820 -
代碼
+關注
關注
30文章
4779瀏覽量
68525 -
小汽車
+關注
關注
0文章
7瀏覽量
9014
發布評論請先 登錄
相關推薦
評論