?? main.c.bak
字號(hào):
/******************************************************************************
* name: main.c
* project: 智能充電器
* author: fengzai(panda)
* date: 2007.1.14
*
* 感謝ouravr一直以來對(duì)我提供的幫助,感謝論壇上的朋友。
* 特別向 armork 章其波bozai 表示感謝,謝謝你們不厭其煩的回答我的提問。
* 功能描述:
* 自動(dòng)判斷電池狀態(tài),對(duì)空電池進(jìn)行預(yù)放電,250ma預(yù)充電,800ma快充電,當(dāng)溫度
* 參數(shù)呈現(xiàn)下降趨勢(shì)的時(shí)候,停止充電,進(jìn)行15分鐘的涓流充電。
* 其中的各項(xiàng)參數(shù)可以在頭文件里修改。
* 具有自動(dòng)保護(hù)功能。
* 溫度測(cè)量采用芝浦熱敏電阻,電路連接見temp.h頭文件。
* 暫時(shí)未設(shè)計(jì)人機(jī)界面,打算用個(gè)8字LED,后續(xù)版本推出。
*
* 特別說明:這是本人第一個(gè)GCC項(xiàng)目,很多地方很不成熟,充電器的各項(xiàng)充電參數(shù)也是
* 想當(dāng)然的,沒有經(jīng)過嚴(yán)格的測(cè)試。我的實(shí)驗(yàn)電池為600ma 7號(hào)GP充電電池,可能代表性
* 也不強(qiáng)。我會(huì)逐步完善代碼。敬請(qǐng)各位大蝦指出問題所在,謝謝!
*
* 楓 仔fengzai martin7wind martin7wind@163.com
* 2007.1.28
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "i_output.h"
#include "adc.h"
#include "usart.h"
#include "temp.h"
#include "time.h"
#include "main.h"
#define uchar unsigned char
#define uint unsigned int
#define BIT(x) (1<<(x))
#define NOP() asm("nop")
#define WDR() asm("wdr")
uint time_t=0;
volatile uint time=0; //全局變量,定義系統(tǒng)時(shí)鐘
volatile uint detect_dt_time=0; //全局變量,用來判斷合適檢測(cè)溫度
volatile uint purling_time=0; //標(biāo)志開始涓流充電的時(shí)間
volatile uchar purling_status=1;
volatile uchar work_status=2; //全局變量,定義系統(tǒng)工作狀態(tài)
volatile uint dt = 50; //溫度上升幅度
volatile uchar current_status = CURRENT_WAIT; //充電標(biāo)志,描述電流是否調(diào)整完畢
uint c_current; //充電電流
uint b_vol; //電池電壓
uint b_temp; //電池溫度
uint b_temp_pre = 0; //用來計(jì)算溫度變化的量
/*------------------------------------------------------------------------------
* 系統(tǒng)時(shí)鐘程序,OK!
*-----------------------------------------------------------------------------*/
//T2溢出中斷服務(wù)程序
//#pragma interrupt_handler timer2_ovf_isr:6
//void timer2_ovf_isr(void)
SIGNAL(SIG_OVERFLOW2)
{
TCNT2 = 0x28;
time_t++;
if(time_t==100)
{
time++;
detect_dt_time++;
time_t=0;
}
TCCR2 = 0x07;//啟動(dòng)定時(shí)器
}
//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00; //DDRA = 0b00000000
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0x22; //PORTD = 0x00000010
DDRD = 0xa2; //DDRD = 0x10000010
}
void init_devices(void)
{
cli(); //禁止所有中斷
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer1_init();
timer2_init();
usart_init();
sei();//開全局中斷
}
/*------------------------------------------------------------------------------
* 測(cè)量模塊,測(cè)量系統(tǒng)各參數(shù),
*-----------------------------------------------------------------------------*/
void system_test(void)
{
if (work_status==WORK_DISCHARGE)
STOP_DISCHARGE;
_delay_ms(100);
c_current = charge_current(); //充電電流
b_vol = battery_vol(); //電池電壓
b_temp = temp();
put_s("I:"); //分別測(cè)出電流、電壓、溫度
send_int(c_current);
put_s("V:");
send_int(b_vol);
put_s("T:");
send_int(b_temp);
put_s("Time:");
send_int(time);
if (work_status==WORK_DISCHARGE)
START_DISCHARGE;
_delay_ms(100);
}
/*------------------------------------------------------------------------------
* 測(cè)量dt,即溫度變化的曲線,每2分鐘檢測(cè)一次dt
*-----------------------------------------------------------------------------*/
void detect_dt(void)
{
if(detect_dt_time>=40)
{
detect_dt_time = 0;
dt = b_temp - b_temp_pre;
b_temp_pre = b_temp;
put_s("dt=\n");
send_int(dt);
}
}
/*------------------------------------------------------------------------------
* 第一次決定充電工作狀態(tài)
* TOP_CHARGE_VOL 1350
* NORMAL_CHARGE_VOL 1300
* START_DISCHARGE_VOL 1200
* STOP_DISCHARGE_VOL 1000
*------------------------------------------------------------------------------*/
void pre_choose_work(void)
{
if( b_vol > TOP_CHARGE_VOL )
{
work_status = WORK_FULL; //電壓大于極限電壓,表示電池本來就是滿的。
put_s("Battery is Full!");
}
if( b_vol > NORMAL_CHARGE_VOL && b_vol <= TOP_CHARGE_VOL ) //是否進(jìn)行涓流充電
{
work_status = WORK_PURLING;
put_s("Purling Charge!\n");
}
if( b_vol > START_DISCHARGE_VOL && b_vol <= NORMAL_CHARGE_VOL) //是否直接進(jìn)入正常充電
{
work_status = WORK_CHARGE;
put_s("Charging!\n");
}
if( b_vol > STOP_DISCHARGE_VOL && b_vol <= START_DISCHARGE_VOL ) //放入電池,如果小于設(shè)定值,進(jìn)入放電狀態(tài)
{
work_status = WORK_DISCHARGE;
put_s("Start Discharge!\n");
}
if( b_vol > EMPTY_VOL && b_vol < STOP_DISCHARGE_VOL ) //電池小于空電壓,直接進(jìn)入充電狀態(tài)
{
work_status = WORK_PRE_CHARGE;
put_s("Start PreCharge!\n");
}
if( b_vol <= EMPTY_VOL ) //電池小于最低電壓,認(rèn)為沒有電池存在或電池已損壞
{
work_status = WORK_EMPTY;
put_s("No Battery In!\n");
}
}
/*------------------------------------------------------------------------------
* 保護(hù)函數(shù),當(dāng)電壓過高,溫度過高,充電時(shí)間過長(zhǎng)時(shí),自動(dòng)停止一切動(dòng)作
*------------------------------------------------------------------------------*/
void protect(void)
{
/* while( (b_vol > DANGER_VOL) || (b_temp > DANGER_T) || (time > MAX_TIME) )*/
//put_s("protecting!\n");
if ( b_temp > DANGER_T )
{
put_s("The temprature is too high! Stop charging!\n");
work_status = WORK_ERROR;
}
if ( time > MAX_TIME )
{
put_s("The charging is too long! Stop charging1\n");
work_status = WORK_ERROR;
}
if ( b_vol > DANGER_VOL )
{
put_s("The voltage is too high! Stop Charging!\n");
work_status = WORK_ERROR;
}
}
int main()
{
init_devices();
put_s("ok!\n");
pwm_output(1000);
//current_control(0);
//STOP_DISCHARGE;
put_s("Battery Detecting......\n");
system_test();
put_s("Battery Voltage is:");
send_int(b_vol);
pre_choose_work();
//START_DISCHARGE;
put_c(work_status+48);
put_c('\n');
while(1)
{
system_test();
protect();
//_delay_ms(1000);
//put_c(work_status+48);
//put_c('\n');
//put_s("start dt!\n");
detect_dt(); //第一次結(jié)果舍棄
//detect_dt();
// put_s("?\n");
//put_c(work_status+48);
switch(work_status)
{
case WORK_ERROR: //錯(cuò)誤狀態(tài),停止充電,停止放電,報(bào)錯(cuò)
{
//current_control(1);
STOP_DISCHARGE;
if (b_vol > EMPTY_VOL)
pre_choose_work();
put_s("Error!\n");
}break;
case WORK_EMPTY: //沒有電池,停止放電
{
STOP_DISCHARGE;
//current_control(1); 錯(cuò)誤所在,沒有電池,電流肯定是0
put_s("No Battery!\n");
if (b_vol < EMPTY_VOL)
pre_choose_work();
}break;
case WORK_DISCHARGE: //放電態(tài),檢查是否達(dá)到停止放電的程度
{
put_s("Discharging!\n");
pwm_output(1023); //關(guān)閉充電電流
START_DISCHARGE;
_delay_ms(60000);
_delay_ms(60000);
_delay_ms(60000);
_delay_ms(60000);
_delay_ms(60000);
_delay_ms(60000);
if ( b_vol < STOP_DISCHARGE_VOL && b_vol > EMPTY_VOL )
{
STOP_DISCHARGE;
work_status = WORK_PRE_CHARGE;
}
if ( b_vol <= EMPTY_VOL )
{
STOP_DISCHARGE;
work_status = WORK_EMPTY;
put_s("No Battery In!");
}
}break;
case WORK_PRE_CHARGE: //預(yù)充電態(tài),當(dāng)電池達(dá)到1300mv時(shí),開始快充
{
STOP_DISCHARGE;
put_s("preCharging!\n");
while(current_status)
{
current_control(PRE_CHARGE_CURRENT);
current_status = CURRENT_OK;
}
if ( b_vol >= NORMAL_CHARGE_VOL )
{
work_status = WORK_CHARGE;
current_status = CURRENT_WAIT;
}
if( b_vol < EMPTY_VOL )
{
current_control(1);
work_status = WORK_EMPTY;
put_s("No Battery!\n");
}
}break;
case WORK_CHARGE: //快速充電狀態(tài),默認(rèn)充電電流800MA
{
STOP_DISCHARGE;
put_s("Normal Charging!\n");
while(current_status)
{
current_control(CHARGE_CURRENT);
current_status = CURRENT_OK;
}
if( dt <= STOP_CHARGE_DT )
{
pwm_output(1023); //關(guān)閉電流
work_status = WORK_PURLING;
current_status = CURRENT_WAIT;
}
if( b_vol < EMPTY_VOL )
{
pwm_output(1023); //關(guān)閉電流
work_status = WORK_EMPTY;
put_s("No Battery!\n");
}
}break;
case WORK_PURLING: //涓流充電,大約持續(xù)10分鐘就充滿電池了,OK!
{
STOP_DISCHARGE;
uint dtime;
while(purling_status)
{
purling_status = 0;
purling_time = time;
}
put_s("Purling Charging!\n");
pwm_output(1023); //關(guān)閉電流
_delay_ms(PURLING_DELAY);
purling_current_control(PURLING_CURRENT);
dtime = time;
dtime -= purling_time;
send_int(dtime);
if( dtime >= PURLING_TIME )
{
work_status = WORK_FULL;
current_control(1); //涓流充電完成,關(guān)閉電流
purling_status = 1;
}
if( b_vol < EMPTY_VOL )
{
current_control(1);
work_status = WORK_EMPTY;
put_s("No Battery!\n");
}
}break;
case WORK_FULL: //電池已經(jīng)滿的狀態(tài)。OK!
{
put_s("The Battery is Full!\n");
system_test();
if( b_vol < EMPTY_VOL )
{
work_status = WORK_EMPTY;
put_s("No Battery!\n");
}
}break;
}
}
}
/*------------------------------------------------------------------------------
* end of file
*-----------------------------------------------------------------------------*/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -