原创小汽车车顶警示灯照明灯系统,含原理图和代码

电子说

1.2w人已加入

描述

 

原装汽车警示灯是双闪,频率大概是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


  审核编辑:汤梓红
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
h1654155285.9614 2023-10-24
0 回复 举报
这个电路是匹配锂电池使用的。如果改9V供电,电路和代码全部要改,相当于一个新项目了 收起回复
jf_00311415 2023-06-02
0 回复 举报
如果led是9V供电,请问电路需要修改哪里? 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分