📄 discharger.c
字号:
//项目名称:电池容量测试器V2.0
//功能描述:通过对电池放电,测量出电池的容量
//外部模块:1602LCD
//开发人员:李卓生
//开发日期:2006年2月16日
//最后修正: 2006年2月27日
//*********************************************************
#include <iom8v.h>
#include <macros.h>
#include "discharge.h"
#include "LCD_1602.h"
#include "eeprom.h"
#define key_delay 64
#define keyboard_scan 16
#define lcd_write 32
#define timer_dealy 125
const char *Menu[]=//系统菜单
{"Menu","Discharging","D882","Record","Clear","USART","#"};
unsigned char path_top,path;
//系统参数
unsigned char sec=0;
unsigned char min=0;
unsigned char hour=0;
unsigned char keyboard;
unsigned char RunTab=1;
unsigned char RunTab_old;
unsigned char sc_timer_dealy,sc_keyboard_scan,sc_lcd_write,sc_key_delay;//定时小于255*31.25ms的
unsigned int sc_bt1,sc_bt_ctrl,sc_eeprom,sc_discharge,sc_bt1_record,sc_bt1_v_temp;
/*//LED灯控制参数
unsigned int G_led,G_led_cy,G_led_ht;
unsigned int sc_G_cy,sc_G_ht;
unsigned int R_led,R_led_cy,R_led_ht;
unsigned int sc_R_cy,sc_R_ht;
*/
// discharge
unsigned char BT1_state;
unsigned int BT1_V;
unsigned int BT1_I;
unsigned int BT1_T;
unsigned int BT1_V_num;
unsigned int BT1_V_num_temp;
unsigned int bt1_v_temp;
unsigned int bt1_v_temp_1;
unsigned int BT1_I_SET;
unsigned int PWM;
unsigned long BT1_mAh;
unsigned long BT1_time;
unsigned int mAh;
unsigned int D882_P;
unsigned int mAh_set=1000;
unsigned char speed=10;
unsigned int BT1_P;
//T2溢出中断服务程序 8ms
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
TCNT2 = 0x06;//重装计时值0xFF=32us 0x00=8.192ms
system_clock();//系统定时器
system();//系统后台服务程序
//Green_led(); Red_led();
if(RunTab_old!=RunTab)
{LCD_clear();RunTab_old=RunTab;}
}
/*----------------------------------
系统后台服务程序
-----------------------------------*/
void system(void)
{
if(sc_timer_dealy==0){timer(); sc_timer_dealy=timer_dealy;}
if((sc_key_delay==0)&&(keyboard!=0)){sc_key_delay=key_delay;}
if(sc_key_delay==1){keyboard=0;}
if(sc_keyboard_scan==0)
{keyboard=key(keyboard);sc_keyboard_scan=keyboard_scan;}
if(sc_lcd_write==0)
{Run_Turn();LCD_write_new();sc_lcd_write=lcd_write;}
if((BT1_I_SET)/*&&(sc_bt1_record==0)*/)
{
if(sc_bt1==0)
{BT1_mAh+=BT1_I;sc_bt1=450;}//容量统计,每3.6秒计一次
if(sc_discharge==0)
{BT1_time++;sc_discharge=125;}//放电时间统计
if(sc_bt1_v_temp==0)
{bt1_v_temp+=BT1_V;sc_bt1_v_temp=500;}
if(sc_bt1_record==0)
{bt1_v_record();sc_bt1_record=7500;}//每分钟记录一次电压
if(sc_eeprom==0)
{
if(BT1_V<2000)
{discharge_stop();}
EEPROM_WRITE(0x01F0,BT1_mAh);
EEPROM_WRITE(0x01F4,BT1_time);
sc_eeprom=1250;//每10秒保存一次
}
}
if(sc_bt_ctrl==0)
{
BT1_I_Ctrl();
if((BT1_I>BT1_I_SET+5)||(BT1_I<BT1_I_SET-5))
sc_bt_ctrl=2;//PWM高速调节
else sc_bt_ctrl=48;//PWM低速调节
}
}
void system_clock(void)
{ //每个节拍为8ms
if(sc_timer_dealy!=0) sc_timer_dealy--;
if(sc_keyboard_scan!=0) sc_keyboard_scan--;
if(sc_key_delay!=0) sc_key_delay--;
if(sc_lcd_write!=0) sc_lcd_write--;
/*
if(sc_G_ht!=0) sc_G_ht--;
if(sc_G_cy!=0) sc_G_cy--;
if(sc_R_ht!=0) sc_R_ht--;
if(sc_R_cy!=0) sc_R_cy--;
*/
if(sc_bt1!=0) sc_bt1--;
if(sc_discharge!=0) sc_discharge--;
if(sc_eeprom!=0) sc_eeprom--;
if(sc_bt1_record!=0) sc_bt1_record--;
if(sc_bt1_v_temp!=0) sc_bt1_v_temp--;
if(sc_bt_ctrl!=0) sc_bt_ctrl--;
}
/*----------------------------------
任务调度程序
----------------------------------*/
void Run_Turn(void)
{
switch(RunTab)
{
case 1:desktop();break;
case 2:system_menu();break;
case 11:Discharging();break;
case 12:D882();break;
case 13:Record();break;
case 14:Clear();break;
case 15:usart();break;
case 20:Capacitance_setting();break;
case 21:discharge_speed();break;
case 22:record_setting();break;
}
}
void bt1_v_record(void)
{
bt1_v_temp/=15;
EEPROM_READ(0x01F8,BT1_V_num);
EEPROM_WRITE(BT1_V_num*2,bt1_v_temp);
put_number(BT1_V_num," ",' ');
put_number(bt1_v_temp," mV",'\n');
if(BT1_V_num<249)
{BT1_V_num++;EEPROM_WRITE(0x01F8,BT1_V_num);}
bt1_v_temp=0;
}
/*------------------------------------
主程序
-------------------------------------*/
void main(void)
{
init_devices();
system_menu_init();
while(1)
{
discharge_init();
discharge();
delay_nms(100);
}
}
void desktop(void)
{
unsigned char ID=1;
if(RunTab==ID)
{
if(keyboard==up){keyboard=0;RunTab=2;}
LCD_write_string(0,1,"Start",10);
LCD_write_time(11,1,hour,min,sec,5);
}
}
void Discharging(void)
{
unsigned char ID=11;
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=2;}
keyboard=0;
}
//LCD_write_string(0,0,Menu[path],15);
LCD_write_number(0,0,3,BT1_V,"V",6);
LCD_write_number(0,1,3,BT1_I,"A",6);
if(BT1_state&(1<<2))
LCD_write_string(7,0,"Finish",15);
else
LCD_write_number(7,0,0,PWM,"PWM",0);
LCD_write_number(7,1,1,BT1_mAh/100,"mAh",15);
}
}
void D882(void)
{
unsigned char ID=12;
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=2;}
keyboard=0;
}
LCD_write_string(0,0,Menu[path],6);
LCD_write_number(7,0,0,BT1_time,"sec",10);
LCD_write_number(0,1,1,BT1_T,"C",0);
LCD_write_number(7,1,0,D882_P,"mW",0);
}
}
void Record(void)
{
unsigned char ID=13; //程序标识
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=2;}
if((BT1_V_num_temp<BT1_V_num-1)&&BT1_V_num!=0)
{
if(keyboard==up)
{
BT1_V_num_temp++;
EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
}
}
if(BT1_V_num_temp>0)
{
if(keyboard==down)
{
BT1_V_num_temp--;
EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
}
}
keyboard=0;
}
LCD_write_number(0,1,3,bt1_v_temp_1,"V",8);
LCD_write_number(0,0,0,BT1_V_num_temp,"min",8);
LCD_write_number(10,0,0,BT1_V_num,"min",15);
LCD_write_number(10,1,3,BT1_V,"V",15);
}
}
void Clear (void)
{
unsigned char ID=14;
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=2;}
if(keyboard==enter_long)
{
BT1_mAh=0;
BT1_time=0;
EEPROM_WRITE(0x01F0,BT1_mAh);
EEPROM_WRITE(0x01F4,BT1_time);
BT1_V_num=0;BT1_V_num_temp=0;
EEPROM_WRITE(0x01F8,BT1_V_num);
sc_bt1_record=7500;
}
keyboard=0;
}
LCD_write_string(0,0,Menu[path],15);
LCD_write_number(7,1,1,BT1_mAh/100,"mAh",15);
}
}
void usart(void)
{
unsigned char ID=15;
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=2;}
if((keyboard==enter)&&BT1_V_num!=0)
{
BT1_state|=(1<<7);
BT1_V_num_temp=0;
}
keyboard=0;
}
if(BT1_state&(1<<7))
{
EEPROM_READ(BT1_V_num_temp*2,bt1_v_temp_1);
put_number(BT1_V_num_temp," ",' ');
put_number(bt1_v_temp_1," mV",'\n');
BT1_V_num_temp++;
if(BT1_V_num_temp>BT1_V_num-1)
{
put_number(mAh_set,"mAh @",' ');
put_number(mAh_set/100*speed,"mA ",' ');
put_number(BT1_mAh/1000,"mAh",'\n');
BT1_state&=~(1<<7);}
}
LCD_write_string(0,0,Menu[path],15);
}
}
void put_number(unsigned int dat,const unsigned char *s,signed char n)
{
signed char i;
unsigned char b=0;
unsigned char uart[5]={0};
G_N;
for (i=0;i<=4;i++)
{
uart[i]=dat%10+48;
dat=dat/10;
}
i=4;
while((uart[i]==48)&&i!=0){i--;}
for(;i>=0;i--)
{
while(!(UCSRA&(1<<UDRE)));
UDR=uart[i];
}
while (*s)
{
while(!(UCSRA&(1<<UDRE)));
UDR=*s;//要显示的数据存入显存
s ++;//指针加1
}
while(!(UCSRA&(1<<UDRE)));
UDR=n;
G_F;
}
void system_menu_init(void)
{
path=1;
for(path_top=0;Menu[path_top]!="#";path_top++){;}
path_top--; //计算当前菜单的项目数
}
void system_menu(void)
{
unsigned char ID=2;
if(RunTab==ID)
{
if(keyboard!=0)
{
if(keyboard==back){RunTab=1;path=1;}
if(keyboard==down){if(path<path_top){path++;}else path=1;}
if(keyboard==up){if(path>1){path--;}else path=path_top;}
if(keyboard==enter){RunTab=path+10;}
keyboard=0;
}
LCD_write_string(0,0,Menu[0],10);
LCD_write_string(0,1,Menu[path],15);
LCD_write_number(12,0,0,path_top,"-",10);
LCD_write_number(13,2,0,path,"",15);
}
}
void discharge_stop(void)
{
BT1_I_SET=0;BT1_I=0;
BT1_state&=~(1<<1);//已停止放电
BT1_state|=(1<<2);//已放完电
PWM_OFF;R_F;
PWM=100;
}
void discharge_init(void)
{
/* PWM_ON;
OCR1A=700;
delay_nms(100);
PWM_OFF;*/
BT1_V=T_BT1_V();
if((BT1_V>2000)&&BT1_state==0)//
{
BT1_state|=(1<<0);
RunTab=20;
}
}
void Capacitance_setting(void)
{
unsigned char ID=20;
if(RunTab==ID)
{
if((keyboard==up)&&mAh_set<4000)
{keyboard=0;mAh_set+=100;}
else if((keyboard==down)&&mAh_set>100)
{keyboard=0;mAh_set-=100;}
else if(keyboard==back)
{
keyboard=0;
EEPROM_READ(0x01F0,BT1_mAh);
EEPROM_READ(0x01F4,BT1_time);
EEPROM_READ(0x01FC,mAh_set);
EEPROM_READ(0x01FE,speed);
RunTab=22;
}
else if(keyboard==enter){keyboard=0;RunTab++;}
LCD_write_string(0,0,"Capacitance",0);
LCD_write_number(0,1,0,mAh_set,"mAh",8);
LCD_write_number(10,1,3,BT1_V,"V",15);
}
}
void discharge_speed(void)
{
unsigned char ID=21;
if(RunTab==ID)
{
LCD_write_string(0,0,"speed",0);
LCD_write_number(9,0,0,6000/speed,"min",15);
LCD_write_number(0,1,2,speed,"C",8);
LCD_write_number(9,1,3,mAh_set/100*speed,"A",15);
if((keyboard==up)&&speed<120)
{keyboard=0;speed+=5;}
else if((keyboard==down)&&speed>5)
{keyboard=0;speed-=5;}
else if(keyboard==back)
{keyboard=0;RunTab--;}
else if(keyboard==enter)
{keyboard=0;RunTab++;BT1_V_num=0;}
}
}
void record_setting(void)
{
unsigned char ID=22;
if(RunTab==ID)
{
EEPROM_WRITE(0x01FC,mAh_set);
EEPROM_WRITE(0x01FE,speed);
PWM=500;sc_bt1_record=7500;
sc_eeprom=1250;sc_bt1_v_temp=500;
BT1_I_SET=mAh_set/100*speed;
PWM_ON;R_N;
BT1_state|=(1<<1);
RunTab=1;
}
}
/*---------------------------------------
放电程序
----------------------------------------*/
void discharge (void)
{
unsigned long v_temp,i_temp,t_temp;
unsigned char v,i,t;
while(BT1_state&(1<<1))
{
if(i<16)
{i_temp+=T_BT1_I();i++;delay_nms(1);}
else
{i=0;BT1_I=i_temp>>4;i_temp=0;}
if(v<64)
{v_temp+=T_BT1_V()+(BT1_I>>1); v++;
delay_nms(1);}
else
{v=0;BT1_V=v_temp>>6;v_temp=0;}
if(t<16)
{t_temp+=T_BT1_T(); t++;
delay_nms(1);}
else
{t=0;BT1_T=t_temp>>4;t_temp=0;}
D882_P=(BT1_V-(BT1_I>>1))/100;
D882_P*=(BT1_I/10);
}
}
void BT1_I_Ctrl (void)
{
if(BT1_I_SET!=0)
{
if(BT1_I>BT1_I_SET+1)
{
if(PWM!=0)
PWM-=1;
OCR1A=PWM;
}
else if(BT1_I<BT1_I_SET-1)
{
if(PWM!=1900)
PWM+=1;
OCR1A=PWM;
}
}
else
{PWM=300;OCR1A=PWM;}
}
/*-------------------------
实时时钟
--------------------------*/
void timer(void)
{
++sec;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
/*
void Green_led(void)
{
if(G_led||sc_G_cy)
{
if(sc_G_cy==0)
{sc_G_cy=G_led_cy;sc_G_ht=G_led_ht;G_led--;}
if(sc_G_ht)G_N;else G_F;
}
}
void G_init(unsigned int t,unsigned int cy,unsigned char ht)
{
CLI();
if((G_led==0)&&(sc_G_cy==0))
{
G_led=t;//
G_led_cy=(cy>>3);
G_led_ht=(G_led_cy*ht/10);
if(G_led==1){G_led_cy++;}
G_led--;
DDRC|=(1<<4);G_N;
sc_G_cy=G_led_cy;
sc_G_ht=G_led_ht;
}
SEI();
}
void Red_led(void)
{
if(R_led||sc_R_cy)
{
if(sc_R_cy==0)
{sc_R_cy=R_led_cy;sc_R_ht=R_led_ht;R_led--;}
if(sc_R_ht)R_N;else R_F;
}
}
void R_init(unsigned int t,unsigned int cy,unsigned char ht)
{
CLI();
if((R_led==0)&&(sc_R_cy==0))
{
R_led=t;//
R_led_cy=(cy>>3);
R_led_ht=(R_led_cy*ht/10);
if(R_led==1){R_led_cy++;}
R_led--;
DDRC|=(1<<5);R_N;
sc_R_cy=R_led_cy;
sc_R_ht=R_led_ht;
}
SEI();
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -