|
| | | | | 单片机程序
18WLED灯管的应急电源 锂电池7.4V 4400 MA 不带保护板
#include<KF8F213.h>
//__sfr __at(0x2007) CONFIG =0x04C8;
unsigned int ADC_Buf;
unsigned int ADC_Res;
unsigned int SumOfAd;
unsigned int ADC_TEMP;
void ADC(void);
void BJQ(void);
void PWM(void);
void ClosePWM(void);
unsigned long microse; //微秒单元2字节变量;
unsigned char annuijis; //按钮计时变量
unsigned char baojingjis; //报警计时变量
unsigned char lvdjis1; //1hz计时变量
unsigned char lvdjis3; //3hz指示灯计时变量
unsigned int zijianjis; //自检计时变量
unsigned char ms50; //50毫秒
unsigned char yingjjs1; //
unsigned char yingjjs2; //
unsigned int second;
unsigned int hour;
unsigned char yue;
unsigned int YANS;
unsigned int YANS1;
unsigned int YANS2;
void chushihua(void); //声明初始化子程序
void shizhong(void); //声明时钟子程序
void yanshi(void); //声明延时子程序
void baojing(void); //声明报警子程序
void shurupanduan(void); //声明输入判断子程序
void anniu(void); //声明按钮子程序
void yingjl(void);
void yingjm(void);
void ADC1(void);
union
{
struct
{ //定义位变量于同一字节
unsigned bit0 :1;
unsigned bit1 :1;
unsigned bit2 :1;
unsigned bit3 :1;
unsigned bit4 :1;
unsigned bit5 :1;
unsigned bit6 :1;
unsigned bit7 :1;
} onebit;
unsigned char allbits;
} GP;
struct bitDefine0
{
unsigned bit0 :1;
unsigned bit1 :1;
unsigned bit2 :1;
unsigned bit3 :1;
unsigned bit4 :1;
unsigned bit5 :1;
unsigned bit6 :1;
unsigned bit7 :1;
} K;
#define K0 (K.bit0) //K0应急标号
#define K1 (K.bit1) //K1自检动作
#define K2 (K.bit2) //报警2秒标号
#define K3 (K.bit3) //报警20秒标号
#define K4 (K.bit4) //故障标号
#define K5 (K.bit5) //关灯标号
#define K6 (K.bit6) //闪烁标号
#define K7 (K.bit7) //闪烁标号
//------------------------------------------------------------
struct bitDefine1
{
unsigned bit0 :1;
unsigned bit1 :1;
unsigned bit2 :1;
unsigned bit3 :1;
unsigned bit4 :1;
unsigned bit5 :1;
unsigned bit6 :1;
unsigned bit7 :1;
} YY;
//然后我们用宏定义的方法将我们需要的位名称赋予相对应的位。如:
#define YY0 (YY.bit0) //电池电压充满标号
#define YY1 (YY.bit1) //按钮按下3秒
#define YY2 (YY.bit2) //按钮按下5秒
#define YY3 (YY.bit3) //应急关灯标号,关灯电压到或者按钮按下7秒
#define YY4 (YY.bit4) //48小时计时标号
#define YY5 (YY.bit5) //16小时充电标号
#define YY6 (YY.bit6) //月自检动作
#define YY7 (YY.bit7) //年自检动作
//-------------------------------------------------------------
struct bitDefine2
{
unsigned bit0 :1;
unsigned bit1 :1;
unsigned bit2 :1;
unsigned bit3 :1;
unsigned bit4 :1;
unsigned bit5 :1;
unsigned bit6 :1;
unsigned bit7 :1;
} X;
//然后我们用宏定义的方法将我们需要的位名称赋予相对应的位。
#define X0 (X.bit0) //自检计时秒标号
#define X1 (X.bit1) //自检计时秒标号
#define X2 (X.bit2) //自检计时标号
#define X3 (X.bit3) //应急动作标号
#define X4 (X.bit4) //光源开路计时标号
#define X5 (X.bit5)
#define X6 (X.bit6)
#define X7 (X.bit7)
//MCU引脚 1.Vcc 2.空 3.空 4.按钮 5.推诿PWM输出 6.推诿PWM输出 7.ADC电池电压测量
//8.蜂鸣器 9.红指示灯 10 应急供电 11.电池充电 12.电流反馈 13.主电检测 14.绿15.黄。
#define hongd P26//红灯
#define huangd P00//黄灯
#define lvd P01//绿灯
#define fengm P27//蜂鸣器
#define yjgd P25//应急供电
#define ann P03//按钮
#define zdsu P02//主电输入
#define cdsc P11//充电输出
#define _nop_() __asm NOP __endasm
///////////////////初始化////////////////////////////////////////
void init(void)
{
INTCTL = 0; //关闭中断
//--------IO口---------------------------------
TR2 = 0B00000000; //GJ
P2 = 0X00;
TR0 = 0B00001100; //GJ
P0 = 0X00;
TR1 = 0B00001001; //GJ
P1 = 0X00;
//-----------------------------
OSCCTL = 0b01100000; //主频设置 rc8M
ANSEL = 0B10010000; //设置模拟通道AN7模拟输入口
// ANSEH = 0B00000000; //设置模拟通道
ADCCTL0 = 0B10011101; //右对齐,AN7为模拟通道,参考电压为 VDD ADC 使能
ADCCTL1 = 0B01010000; // 转换时钟101 FOSC/16
//....adc............................
AMPCTL = 0; //禁止运放
CMCTL0 = 0B00000000;
//CMCTL1 = 0B00000011; //开比较器,11 = 1/2VDD作为CMP1的负端输入
CMCTL1 = 0B00000000;
//----PWM----------------------------
PP2 = 60; //pp2=31-60khz
//PWM2L = 50;
PWMCTL = 0b11000000;
T1CTL = 0b00000001;
T1L = 0;
T1H = 0;
//-----PWM3---------------------------------
PWM3CTL1 = 0X02; //死区时间
PP3 = 0X46; //设置周期 28K
PWM3L = 0X23; //设置占空比
//----------T0定时器-------------------------
OPTR = 0B10000100; // T0模式 预分频为1:32
EIE1 =0X00;
INTCTL = 0B11110000; //中断控制
GP.onebit.bit0 = 1;
GP.onebit.bit1 = 0;
GP.onebit.bit2 = 1;
GP.onebit.bit3 = 1;
GP.onebit.bit4 = 0;
K0 = 0;
K1 = 0;
K2 = 0;
K3 = 0;
K4 = 0;
K5 = 0;
K6 = 0;
K7 = 0;
YY0 = 0;
YY1 = 0;
YY2 = 0;
YY3 = 0;
YY4 = 0;
YY5 = 0;
YY6 = 0;
YY7 = 0;
X0 = 0;
X1 = 0;
X2 = 0;
X3 = 0;
X4 = 0;
X5 = 0;
X6 = 0;
X7 = 0;
ms50 = 0;
second = 0;
hour = 0;
yue = 0; //月归零
annuijis = 0; //按钮计时加一
baojingjis = 0; //报警计时加一
zijianjis = 0; //自检计时加一
microse = 0; //微秒单元2字节变量;
lvdjis1 = 0; //1hz计时变量
lvdjis3 = 0; //3hz指示灯计时变量
yingjjs1 = 0; //
yingjjs2 = 0; //
YANS = 0;
YANS1 = 0;
YANS2 = 0;
//-------------------------------------------
}
///////////////////////////////////////////////////////////////////////
void ADC(void)
{
unsigned char ad_convert_times; //8次 求平均
SumOfAd = 0;
ADC_Res = 0;
ADC_Buf = 0;
ADC_TEMP = 0;
for (ad_convert_times = 0; ad_convert_times < 8; ad_convert_times++)
{
START = 1; //启动ADC
while (START)
{
_NOP();
}
ADC_Res = ADCDATAL; //读取ADC低8位结果值
ADC_Res |= ADCDATAH << 8; //高4位数据左移8次与低8位数据相加,存储在AD_Result中
SumOfAd += ADC_Res;
_NOP();
}
ADC_Buf = SumOfAd >> 3;
//------------------------------数据判断---------------------//
if (GP.onebit.bit2)
{ //主电时的判断
if (ADC_Buf < 300) //电池电压低于1V 测量0.5V
GP.onebit.bit0 = 0; //电池短路标号
else GP.onebit.bit0 = 1; //电压高压1V ,消短路标号
if (ADC_Buf > 889) //电池电压高于8.4V测量4.2V 电池开路VDD4.95
GP.onebit.bit1 = 1; //电池开路标号
if (ADC_Buf < 875)
GP.onebit.bit1 = 0; //电压正常消开路标号
if (ADC_Buf > 869) //电池电压8.4V电池充满 ,实际测量
YY0=1;
if(GP.onebit.bit0){ //没有电池短路
if (ADC_Buf < 849) //电池电压低于电池充电
YY0=0;
}
}
if (CHS0) //--------电池电压检测-----
{
if (X3) //应急动作标号X3
{
if(X5){ //应急动作后延时2秒钟测电压
if (ADC_Buf < 620) //电压低于655 6.5V关掉
{
GP.onebit.bit4 = 1;
YY3 = 1;
} //电池没电标号 关灯
else
{
GP.onebit.bit4 = 0;
}
}
}
}
if (CHS0==0)
{
if (X3) //应急动作标号X3
{
if (ADC_Buf < 3) //16w led荧光灯 18处在临界 电流2.2A
{ X4 = 1; //
P05=1; }
else
{ X4 = 0; //应急工作正常 标号归零
P05=0; }
}
}
//-----------------------------通道切换----------//
if (X3) //应急动作标号X3
{
if (CHS0)
ADCCTL0 = 0B10010001; //右对齐,AN4为模拟通道,应急电流通道
else
ADCCTL0 = 0B10011101; //右对齐,AN7为模拟通道,电池通道
}
else //没有应急标号 主电测电池
ADCCTL0 = 0B10011101; //右对齐,AN7为模拟通道,电池通道
}
//////////////////////中断程序///////////
void INT_FUN()
__interrupt //定时中断
{
if(T0IF) //判断tmr0中断
{
T0IF=0; //清除中断标志位
microse+=4096;//加上一次中断时间
if(zdsu)
GP.onebit.bit2=1;//主电标号
else
GP.onebit.bit2=0;
if(ann)
GP.onebit.bit3=1;//按钮标号
else
GP.onebit.bit3=0;
//----------------------------------------
}
if(INT0IF) //判断是否是外部中断,停电立即开应急
{
INT0IF=0;
// if(YY3==0)
// {
yjgd = 1; //应急供电打开
T2ON = 1; //打开T2
PWM3CTL0=0X8C; //输出PWM3
GP.onebit.bit2=0;//清主电标号
// }
}
}
//////////////////////时钟子程序/////////////////////
void shizhong(void) //
{
if (microse > 50000)
{
microse -= 50000;
ms50++;
lvdjis1++;
lvdjis3++;
}
if (ms50 > 20)
{
ms50 = 0;
second++; //秒计时加一
if(X3)
{
YANS2++;
if(YANS2 > 2)
X5=1;
}
else {
YANS2=0;
X5=0;
}
if (X4) YANS++; //应急光源开路动作计时
else YANS = 0;
if (YANS > 2){
YY3 = 1; //光源开路3秒 后关灯 --光源电流检测--
K5 = 1;
}
//------------------------------------------------
if (GP.onebit.bit4) //电池电压低关灯标号
{
YANS1++;
if (YANS1 > 2)
K5 = 1;
}
else
YANS1 = 0;
//----------------------------------------------------
if (GP.onebit.bit3 == 0) //按钮按下
annuijis++; //按钮计时加一
baojingjis++; //报警计时加一
zijianjis++; //自检计时加一
}
if (second >3600)
{
second = 0;
hour++;
if (YY4 == 0) //检测计时标号48小时到否
{
//if (hour == 16)
// YY5 = 1; //看16小时充电计时到否,到置充满标号Y5
if (hour >48)
{
YY4 = 1; //置开始计时标号
YY5 = 0;
hour = 0; //小时归零
second = 0;
ms50 = 0;
}
}
if(YY7==0){
if(hour>720) //1个月等于 24*30=720小时
{
hour=0; //小时归零
YY6=1; //置月自检标号
yue++;
}
} //
if(yue>12) //年自检等于12个月
{
yue=0;
YY6=0; //月归零
YY7=1; //置年自检标号
}
}
}
/////////////////////////计时程序///////////////////////////
void jishi(void)
{
if (annuijis == 7)
YY3 = 1; //按钮安下7秒到置Y3 为1
if (annuijis == 5)
YY2 = 1; //按钮安下5秒到置Y2 为1
if (annuijis == 3)
YY1 = 1; //按钮安下3秒到置Y1 为1
if (K4 == 0) //故障标号
{
baojingjis = 0;
K3 = 0;
K2 = 0;
} //没有故障标号,计时器,各标号归零FP54=0;
if (baojingjis == 20)
K3 = 1; //到20秒置报警发声20秒标号K3
if (baojingjis == 2)
K2 = 1; //到2秒置报警发声2秒标号K2
if (K1)
{
if (zijianjis == 1800)
X2 = 1; //到30分钟 自检记时30分钟标号
if (zijianjis == 60)
X1 = 1; //到1分钟 自检记时1分钟标号
if (zijianjis == 1)
X0 = 1; //到1秒钟 自检记时1秒钟标号
}
else
{
X0 = 0;
X1 = 0;
X2 = 0;
zijianjis = 0;
}
//--------------------------------------指示灯闪烁
if (lvdjis3 == 3) //指示灯3HZ闪烁时间50MS*3
{
lvdjis3 = 0; //到计时器清零,闪烁标志位取反
if (K7)
K7 = 0;
else
K7 = 1;
}
if (lvdjis1 == 10) //指示灯1HZ闪烁时间50MS*10
{
lvdjis1 = 0; //到计时器清零,闪烁标志位取反
if (K6)
K6 = 0;
else
K6 = 1;
}
}
////////////////////////////////////////////////////
void huangd3hz(void)
{
if (K7)
{
huangd = 1;
} //k7是3HZ
else
{
huangd = 0;
}
}
///////////////////////////////////////////////////
void huangd1hz(void)
{
if (K6)
{
huangd = 1;
} //k6是1hz
else
{
huangd = 0;
}
}
//////////////////////////////////////////////////
void lvd3hz(void)
{
if (K7)
lvd = 1;
else
lvd = 0;
}
//////////////////////////////////////////////////
void lvd1hz(void)
{
if (K6)
lvd = 1;
else
lvd = 0;
}
void anniu1(void) //按钮按下的处理子程序
{ //
if(GP.onebit.bit3==1)return; //按钮没按下返回
if(K4==1)return; //有K4故障标号,退出
yingjl();
if(YY2==1) //计时5秒到否
{fengm=0; // 到停提示音
}
else //计时5秒没到
{if(YY1==0)return; //看计时3秒到否,没到返回
fengm=1; //3秒到启动提示音
}
}
////////////////////////////////////////////////////
void anniu2(void) //按钮弹起的处理子程序
{
if(GP.onebit.bit3==0)return; //按钮在按下时退出
if(YY7==1)return; //有年自检标号退出
if(YY6==1)return; //有月自检标号退出
if(K4==1)return; //有K4故障标号退出
fengm=0; //停止发声
if(YY2==0){
if(YY1==0)yingjm();
else YY6=1;
}
else YY7=1;
YY1=0;
YY2=0;
YY3=0;
annuijis=0;
}
//////////////////////////////////////////////////
void yuezij(void) //-----------------月自检
{
K1 = 1; //置自检标号
lvd1hz(); //
if (K5 ) //亮黄灯,调报警
{
yingjm();
huangd = 1;
baojing();
}
else
{
if (X1) //自检记时1分钟标号
{
YY6 = 0; //月自检标号
K1 = 0; //清自检标号
}
else
{
yingjl();
}
}
}
//////////////////////////////////////////////////////
void nianzij(void) //-----------------年自检
{
K1 = 1; //自检标号
lvd3hz(); //自检指示
if (K4) //亮黄灯,调报警
{
yingjm();
huangd = 1;
baojing();
}
else//没有故障标号
{
if (X2)
{
if (K5)
{
YY7 = 0; //年自检标号归零
K1 = 0; //自检标号归零
YY4 = 0; //48小时充电标号归零
YY5 = 0; //充电标号为零
hour = 0; //小时归零
K5=0;
}
else
{
yingjl();
}
}
else //30分钟没到
{
if (K5)//亮黄灯,调报警
{
yingjm();
huangd = 1;
baojing();
}
else//没到关灯电压 亮灯
{
yingjl();
}
}
}
}
//////////////////////报警声程序//////////////////////////
void baojing(void)
{
K4 = 1;
if (K3)
{
K2 = 0;
K3 = 0;
baojingjis = 0;
}
else
{
if (K2)
fengm = 0;
else
fengm = 1;
}
}
/////////////////指示灯///////////////////////////////////
void CD(void)
{
if (K1)
return; //按钮按下退出
if(GP.onebit.bit3 == 0)
return; //按钮按下退出
if(X3==1)
return; //应急动作退出
lvd = 1;
//if (YY5==0) //充电时间标号,到设定时间YY5为1
//{
if(YY0){
PWM2ON = 0; //关闭充电的PWM
cdsc = 0; //下啦端口
hongd = 0; //红灯灭
}
else {
PWM2ON = 1; //关闭充电的PWM
PWM2L = 60;
hongd = 1; //红灯亮
}
//}
//--------------------故障判断--------------------------------------
/*
if (GP.onebit.bit0)
{
if (GP.onebit.bit1 == 0)
{
K4 = 0;
huangd = 0;
return;
}
}
PWM2ON = 0; //关闭充电的PWM
cdsc = 0; //下啦端口
huangd1hz();
baojing();
}
*/
if (GP.onebit.bit0 == 0) {
PWM2ON = 0; //关闭充电的PWM
cdsc = 0; //下啦端口
huangd1hz();
baojing();
return;
}
if (GP.onebit.bit1 == 1){
PWM2ON = 0; //关闭充电的PWM
cdsc = 1; //
huangd1hz();
baojing();
return;
}
if (GP.onebit.bit0)
{
if (GP.onebit.bit1 == 0)
{
K4 = 0;
huangd = 0;
fengm = 0;
}
}
}
//////////////////////应急动作/////////////////////////////
void yingjl(void)
{ yjgd = 1; //应急供电打开
T2ON = 1;
PWM3CTL0=0X8C;//0b10001100
PWM2ON = 0; //关闭充电的PWM
cdsc = 0; //下啦端口
if (K1 == 0)
lvd = 0; //绿灯灭
X3 = 1; //应急动作标号
hongd = 0; //红灯灭
huangd = 0;
//fengm = 0;
}
/////////////////////应急关闭///////////////////////////////
void yingjm(void)
{
//P3ON0 = 0; //关闭PWM3
PWM3CTL0=0X00;
T2ON = 0;
yjgd = 0; //应急供电关闭
X3 = 0; //应急动作标号
P14 = 0; //下啦端口
P15 = 0; //下啦端口
}
/////////////////////主程序////////////////////////////////
void main()
{
init(); //初始化
while (1)
{
__asm
CWDT
__endasm;
shizhong(); //时钟子程序
jishi(); //计时程序
ADC();
if (GP.onebit.bit2)
{
if (K0)
{ //有主电有应急标号 进行初始化
T2ON=0;
P3ON0=0;
K0 = 0;
K1 = 0;
K2 = 0; //
K3 = 0;
K4 = 0;
K5 = 0;
K6 = 0;
K7 = 0;
YY0 = 0;
YY1 = 0;
YY2 = 0;
YY3 = 0;
YY4 = 0;
YY5 = 0;
YY6 = 0;
YY7 = 0;
X0 = 0;
X1 = 0;
X2 = 0;
X3 = 0;
X4 = 0;
X5 = 0;
X6 = 0;
X7 = 0;
ms50 = 0;
second = 0;
hour = 0;
yue = 0; //月归零
annuijis = 0; //按钮计时加一
baojingjis = 0; //报警计时加一
zijianjis = 0; //自检计时加一
GP.onebit.bit0 = 1;
GP.onebit.bit1 = 0;
GP.onebit.bit2 = 1;
GP.onebit.bit3 = 1;
GP.onebit.bit4 = 0;
P1 = 0X00;
//P14=0;
//P15=0;
}
anniu1(); //按钮子程序
anniu2(); //按钮子程序
if (YY7 )
nianzij();
if (YY6)
yuezij();
CD();
}
else //应急工作循环
{
if (YY3)
{
yingjm();
}
else//YY3为关灯标志,按钮下7秒或电池电压低于85% YY3=1.
{
yingjl();
K0 = 1; //应急工作状态标号
}
}
}
}
|
|
|
|
|
|
|
|