搜档网
当前位置:搜档网 › 合泰单片机移动电源带电量指示功能c语言程序

合泰单片机移动电源带电量指示功能c语言程序

#include "HT46R064B.h"

#define TRUE 1
#define FALSE 0
#define TURN_ON 1
#define TURN_OFF 0
#define LED1PORT _pb0
#define LED2PORT _pb1
#define LED3PORT _pb2
#define LED4PORT _pb3
//#define LED5PORT _pb4
//#define LED6PORT _pb4
#define BUTTON1PORT _pa6
#define BUTTON1_PRESSED (_pa6==0)
#define BUTTON1_NOPRESSED (_pa6==1)
#define CHARGER_PLUGGED (_pa5==0)
#define CHARGER_UNPLUGGED (_pa5==1)
#define CHARGE_FULL (_pa3==1)
#define CHARGE_UNFULL (_pa3==0)
#define DISCHARGE_ENABLE (_pa4=1)
#define DISCHARGE_DISABLE (_pa4=0)
#define DISCHARGE_SENSOR_VALUE_EXIST_LOAD 24 //50mA电流流经100毫欧电阻时的ADC采样值
#define DISCHARGE_SENSOR_VALUE_OVER_CURRENT 0xea //100毫欧的电阻,1.6安电流过流


#define VOLTAGE_VALUE_CHARGE_1 0xa92 //ADC采样3.7/2伏电压的值
#define VOLTAGE_VALUE_CHARGE_2 0xb49 //ADC采样3.95/2伏电压的值
#define VOLTAGE_VALUE_DISCHARGE_1 0x892 //ADC采样3.0/2伏电压的值
#define VOLTAGE_VALUE_DISCHARGE_2 0xa92 //ADC采样3.7/2伏电压的值
#define VOLTAGE_VALUE_DISCHARGE_3 0xb49 //ADC采样3.95/2伏电压的值

unsigned char
Counter_100ms_background,
Counter_100ms_background1,
Counter_1second_background,
Counter_8ms_counter,
Counter_8ms_counter_2,
Counter_100ms_counter,
Counter_100ms_LED,
Counter_1second_Counter,
Counter_1second_Counter2,
Counter_1second_Counter3,
Counter_10second_counter,
Timer0_temp_data,
Button_Process_frame,
Button_Value;
char Previous_Level,
tempchara;
bit Blink_state,
Blink_state_fast,
Blink_state_slow,
Charge_Full_flag;
unsigned short battery_voltage,Discharge_Sensor_Voltage;
unsigned long templonga;


void LED_Light(char number)
{
if(number==1) {LED1PORT=TURN_ON;LED2PORT=TURN_OFF;LED3PORT=TURN_OFF;}
else if(number==2) {LED1PORT=TURN_ON;LED2PORT=TURN_ON;LED3PORT=TURN_OFF;}
else if(number==3) {LED1PORT=TURN_ON;LED2PORT=TURN_ON;LED3PORT=TURN_ON;}
else {LED1PORT=TURN_OFF;LED2PORT=TURN_OFF;LED3PORT=TURN_OFF;}
}

void All_LED_Off(void)
{
LED1PORT=TURN_OFF;
LED2PORT=TURN_OFF;
LED3PORT=TURN_OFF;
// LED4PORT=TURN_OFF;
// LED5PORT=TURN_OFF;
}

void All_LED_ON(void)
{
LED1PORT=TURN_ON;
LED2PORT=TURN_ON;
LED3PORT=TURN_ON;
// LED4PORT=TURN_ON;
// LED5PORT=TURN_ON;
}

unsigned short ADC(unsigned char ADC_Channel)
{
unsigned short tempinta;
_adcr&=0b11111000;//ADC通道切换到0
_adcr|=ADC_Channel;
for(Counter_8ms_counter=0;Counter_8ms_counter<1;);//等待MCU内外部采样电路的稳定
_start=0;
_start=1;
_start=0;
do
{
#asm
clr wdt
#endasm
}while(_eocb==1);
tem

pinta=_adrh;
tempinta*=16;
tempinta+=_adrl/16;
//计算真实的MCU的电源电压,以毫伏为单位
/* templonga=2800;
templonga*=tempinta;
templonga/=4096;
*/ return (tempinta);
}


unsigned short ADC_GetData(unsigned char ADC_Channel)
{
unsigned short tempint_add,tempinta,tempint_big,tempint_small;
tempint_big=ADC(ADC_Channel);
tempint_small=ADC(ADC_Channel);
tempint_add=tempint_big+tempint_small;
for(tempchara=0;tempchara<4;tempchara++)
{
tempinta=ADC(ADC_Channel);
tempint_add+=tempinta;
if(tempinta>tempint_big) tempint_big=tempinta;
if(tempinta}
tempint_add-=tempint_big;
tempint_add-=tempint_small;
tempint_add/=4;
return (tempint_add);
}


#pragma vector ISR_Timer @ 0x08
void ISR_Timer(void)
{
Timer0_temp_data++;
Counter_8ms_counter++;
Counter_8ms_counter_2++;
if(Timer0_temp_data==12)//100毫秒进位
{
Timer0_temp_data=0;
Counter_100ms_background++;
Counter_100ms_background1++;
Counter_100ms_counter++;
Counter_100ms_LED++;
if(Counter_100ms_background==0b00001010) //1秒进位
{
Counter_100ms_background=0;
Counter_1second_background++;
Counter_1second_Counter++;
Counter_1second_Counter2++;
Counter_1second_Counter3++;
}
if(Counter_1second_background==0b00001010) //10秒进位
{
Counter_1second_background=0;
Counter_10second_counter++;
}

if((Counter_100ms_background1&0b00000111) <4)
Blink_state=0;
else
Blink_state=1;

if((Counter_100ms_background&0b00000011) <2)
Blink_state_fast=0;
else
Blink_state_fast=1;

if((Counter_100ms_background&0b00001111) <8)
Blink_state_slow=0;
else
Blink_state_slow=1;
}

switch(Button_Process_frame)//按键判断,单击时Button_Value为1,双击时Button_Value为2,长按为3,按键失败则Button_Value为0。
{
case 0:
if(BUTTON1_PRESSED) Button_Process_frame=1;
break;
case 1:
Button_Process_frame=2;

break;
case 2:
if(BUTTON1_PRESSED) Button_Process_frame=3;
else Button_Process_frame=0;
Counter_8ms_counter_2=0;
break;
case 3:
if(Counter_8ms_counter_2>250)//长按判断
{
Button_Value=3;
Button_Process_frame=20;
}
else if(BUTTON1_NOPRESSED) Button_Process_frame=4;
break;
case 4:
Button_Process_frame=5;
break;
case 5:
Button_Process_frame=6;
Counter_8ms_counter_2=0;
break;
case 6:
if(BUTTON1_PRESSED)
{
Button_Process_frame=7;
}
else if(Counter_8ms_counter_2>40)//320豪秒内没有再次按键,则判断按键为单击。
{
Button_Value=1;
Button_Process_frame=0;
}
break;
case 7:
Button_Process_frame=8;
break;
case 8:
if(BUTTON1_PRESSED) Button_Process_frame=9;
else
{
Button_Value=1;
Button_Process_frame=0;
}
break;
case 9:
if(BUTTON1_NOPRESSED) Button_Process_frame=10;
break;
case 10:
Button_Process_frame=11;
break;

case 11:
Button_Value=2;
Button_Process_frame=0;
break;
case 20:
if(BUTTON1_NOPRESSED) Button_Process_frame=21;
break;
case 21:
Button_Process_frame=22;
break;
case 22:
Button_Process_frame=0;
break

;

default:
Button_Process_frame=0;

}
}

bit Batt_Vol_LessThan(unsigned short COMP_Value)
{
if(battery_voltageelse return FALSE;
}

char BATT_VOL_SEG_Charge_Just()
{
unsigned char tempchar4;
if(Batt_Vol_LessThan(VOLTAGE_VALUE_CHARGE_1)==TRUE)
{
tempchar4=1;
}
else if(Batt_Vol_LessThan(VOLTAGE_VALUE_CHARGE_2)==TRUE)
{
tempchar4=2;
}
else
{
tempchar4=3;
}

return(tempchar4);
}



char BATT_VOL_SEG_Discharge_Just()
{
char tempchar5;
if(Batt_Vol_LessThan(VOLTAGE_VALUE_DISCHARGE_1)==TRUE)
{
tempchar5=0;
}
else if(Batt_Vol_LessThan(VOLTAGE_VALUE_DISCHARGE_2)==TRUE)
{
tempchar5=1;
}
else if(Batt_Vol_LessThan(VOLTAGE_VALUE_DISCHARGE_3)==TRUE)
{
tempchar5=2;
}
else
{
tempchar5=3;
}

return(tempchar5);
}



void sys_init()
{
Counter_100ms_background=0;
Counter_100ms_background1=0;
Counter_1second_background=0;
Counter_10second_counter=0;
Button_Value=0;
//PA0,USB输出电流采样
_pa0=0;
_pac0=0;
_papu0=0;
//PA1,电芯电压采样
_pa1=0;
_pac1=0;
_papu1=0;
//PA2,悬空
_pawk2=0;
_pac2=0;
_pa2=0;
_papu2=0;
//PA3,充满侦测
_pawk3=1;
_pac3=1;
// _pa3=0;
_papu3=1;
//PA4,输出使能控制
_papu4=0;
_pawk4=0;
_pa4=0;
_pac4=0;
//PA5,充电器插入侦测
_pawk5=1;
_pac5=1;
_papu5=1;
//PA6,按键
// _pa6=0;
_pac6=1;
_papu6=1;
_pawk6=1;
//PA7,悬空
_pa7=0;
_pac7=0;
_pawk7=0;

//PB0~PB3为LED,PB4、PB5悬空未用。
_pb0=0;
_pb1=0;
_pb2=0;
_pb3=0;
_pb4=0;
_pb5=0;

_pbc=0x00;
_pbpu=0x00; //PB口无需上拉

//初始化timer0
_tmr0c=0b10000111; //设定timer0的时钟源为4MHZ/128(31250 HZ)
_tmr0=0; //设定timer0预装数为0,使得其中断频率约为122 HZ
_t0f=0; //清timer0 interrupt request flag
_et0i=1; //开timer0中断
Timer0_temp_data=0;
//初始化ADC
_acsr=0b00000001; //使能ADC的电源,并设置ADC的时钟为system clock/8
_adcr=0b00010000; //PA0~PA1 enabled as AN0~AN1,并选择ADC的通道为AN0

_t0on=1;//启动timer0


_emi = 1 ; // Enable global interrupt
_wdts=0b00000111;
_ctrl1=0b10000101;//Enable WDT;
}

void main()
{

if(_to==0) //上电复位
{
sys_init();
for(Counter_100ms_counter=0;Counter_100ms_counter<3;)
{
#asm
clr wdt
#endasm
}
battery_voltage=ADC_GetData(1);//执行一次ADC转换
Previous_Level=BATT_VOL_SEG_Charge_Just();
LED_Light(Previous_Level);
for(Counter_100ms_counter=0;Counter_100ms_counter<30;)
{
#asm
clr wdt
#endasm
}
goto sleep;
}

main_infinity_loop:
sys_init();

for(Counter_100ms_counter=0;Counter_100ms_counter<2;)//延时0.2秒,等待外围电路工作稳定。
{
#asm
clr wdt
#endasm
}

if(CHARGER_PLUGGED)//充电中
{
Charging:

DISCHARGE_DISABLE;
Counter_1second_Counter=0;
All_LED_Off();
LED4PORT=TURN_OFF;
#asm
clr wdt
#endasm
for(Counter_100ms_counter=0;Counter_100ms_counter<4;){}//
LED1PORT=TURN_ON;
for(;Counter_100ms_counter<7;){}//
LED2PORT=TURN_ON;
for(;Counter_100ms_counter<10;){}//
LED3PORT=TURN_ON;
for(;Counter_100ms_counter<15;){}//

for(;CHARGER_PLUGGED;)//充电中
{
if(Previous_Level<=1) Previous_Level=1;
battery_voltage=ADC_GetData(1);//执行一次ADC转换
tempchara=BATT_VOL_SEG_Charge_Just();
if(tempchara==Previous_Level) Counter_1second_Counter=0;
if(Counter_1second_Counter>60)//如果在60秒内,每次采样得到的电压段与之前都不一样,则说明电压真的改变了。
{
if(tempchara>Previous_Level)Previous_Level++;
Counter_1second_Counter=0;
}

if(Previous_Level<=1)//电压显示
{
if(Counter_100ms_LED<3){LED1PORT=TURN_ON;}
else if(Counter_100ms_LED<6){LED2PORT=TURN_ON;}
else if(Counter_100ms_LED<12){LED3PORT=TURN_ON;}
else if(Counter_

100ms_LED<14){All_LED_Off();}
else {Counter_100ms_LED=0;}
}
else if(Previous_Level==2)
{
if(Counter_100ms_LED<5){LED2PORT=TURN_ON;}
else if(Counter_100ms_LED<10){LED3PORT=TURN_ON;}
else if(Counter_100ms_LED<14){LED1PORT=TURN_ON;LED2PORT=TURN_OFF;LED3PORT=TURN_OFF;}
else {Counter_100ms_LED=0;}
}
else if(Previous_Level==3)
{
if(Blink_state==1){LED3PORT=TURN_ON;}
else LED3PORT=TURN_OFF;

LED1PORT=TURN_ON;
LED2PORT=TURN_ON;
}

//充滿的判断..........
Charge_Full_flag=FALSE;
if(CHARGER_PLUGGED && CHARGE_FULL && (Previous_Level>=3))
{
Counter_100ms_counter=0;
Charge_Full_flag=TRUE;
while(Counter_100ms_counter<30)//在充电器接入时满充信号长达3秒,则判为已充满
{
if(CHARGER_UNPLUGGED || CHARGE_UNFULL)
{
Charge_Full_flag=FALSE;
break;
}
#asm
clr wdt
#endasm
}
}
if(Charge_Full_flag==TRUE)//已经充满
{
All_LED_ON();
Previous_Level=3;
while(CHARGER_PLUGGED)//充满后,等待充电器移除
{
#asm
clr wdt
#endasm
if(CHARGE_UNFULL) goto sleep;
}
}
}
goto sleep;
}

while(BUTTON1_PRESSED)
{
#asm
clr wdt
#endasm
}
for(Counter_8ms_counter=0;Counter_8ms_counter<50;)//等待按键值更新
{
#asm
clr wdt
#endasm
}
if(Button_Value!=1) goto sleep;

if(Previous_Leve

l==0)
{
All_LED_Off();
LED4PORT=TURN_OFF;
for(Counter_100ms_counter=0;Counter_100ms_counter<50;)//电压太低,等待LED1闪5秒后关机
{
#asm
clr wdt
#endasm
if(Blink_state_fast==1){LED1PORT=TURN_ON;}
else LED1PORT=TURN_OFF;
}
goto sleep;
}




Discharging:
Counter_1second_Counter=0;
Counter_1second_Counter2=0;
Counter_1second_Counter3=0;
DISCHARGE_ENABLE;
Button_Value=0;
for(;;)//放电中
{
battery_voltage=ADC_GetData(1);//执行一次ADC转换
tempchara=BATT_VOL_SEG_Discharge_Just();
if(tempchara==Previous_Level) Counter_1second_Counter=0;
if(Counter_1second_Counter>30 )//如果在30秒内,每次采样得到的电压段与之前都不一样,则说明电压真的改变了。
{
if(tempcharaCounter_1second_Counter=0;
}

Discharge_Sensor_Voltage=ADC_GetData(0);//获取输出电流
if(Discharge_Sensor_Voltage>DISCHARGE_SENSOR_VALUE_EXIST_LOAD) Counter_1second_Counter2=0;
if(Counter_1second_Counter2>80 ||
(Counter_1second_Counter2>3 && (Previous_Level==0))) break; //放电电流低于50mA的时间长达60秒;或在电压段为0时,放电电流低于50mA的时间长达3秒

if(Discharge_Sensor_Voltageif(Counter_1second_Counter3>=2) break; //放电过流的时间超过2秒钟

if(CHARGER_PLUGGED) goto Charging;
if(Button_Value==3) goto sleep;

if(Counter_1second_Counter2>=2)//无负载时间超过2秒。
{
LED4PORT=TURN_OFF;
}
else//有负载时,电LED4闪。
{
if(Blink_state==1)LED4PORT=TURN_ON;
else LED4PORT=TURN_OFF;
}

if(Previous_Level==0)
{
All_LED_Off();
LED4PORT=TURN_OFF;
for(Counter_100ms_counter=0;Counter_100ms_counter<50;)//电压太低,等待LED3闪5秒后关机
{
#asm
clr wdt
#endasm
if(Blink_state_fast==1){LED1PORT=TURN_ON;}
else LED1PORT=TURN_OFF;
}

goto sleep;
}
else if(Previous_Level==1)//电压显示,有几格电就第显示几个灯。
{LED1PORT=TURN_ON;LED2PORT=TURN_OFF;LED3PORT=TURN_OFF;}
else if(Previous_Level==2)
{LED1PORT=TURN_ON;LED2PORT=TURN_ON;LED3PORT=TURN_OFF;}
else if(Previous_Level==3)
{LED1PORT=TURN_ON;LED2PORT=TURN_ON;LED3PORT=TURN_ON;}


}
goto sleep;

sleep:
if(CHARGER_PLUGGED)
goto Charging;
_t0on=0;//停止timer0
_adonb=1; //关闭ADC的电源
_adcr=0;
_emi = 0; // Disable global interrupt
All_LED_Off();
LED4PORT=TURN_OFF;
DISCHARGE_DISABLE;
_ctrl1=0b10001010;//Disable WDT;
#asm
clr wdt
NOP
HALT //进入sleep
NOP
NOP
clr wdt
#endasm
goto main_infinity_loop;

}

相关主题