# include & ltmacros.h & gt
# include & ltstdio.h & gt
# include & ltRD _ UseAvrPortBit.h & gt
# include & ltRD _ UseBITs.h & gt
#包含“delay.h”
#定義uint無符號整數
#定義uchar無符號字符
#定義lint無符號長整型
#定義采樣_電池0x20
#define samping_cap 0x21
#定義fixed_bc_volt0 7
//#定義fixed_bc_volt1 20
#定義固定_cb_volt 0
uchar batt_volt0,batt_volt1,cap _ volt0
uint batt_volt0_temp,batt_volt1_temp,cap _ volt0 _ temp
uchar flag_c=0,flag_nc=0,flag_b=0,flag_nb=0,flag_ncharge=0,frist _ charge _ flag = 0;
uchar timecount,ad _ time flag = 1;
////////////////////////////////////////////////////////////////////////////////
void port_init(void)
{
PORTB = 0x00//數據寄存器
DDRB = 0x 02;//PB1 out數據方向寄存器0為輸入端口。
PORTC = 0x00
DDRC = 0x 00;
PORTD = 0xFF
DDRD = 0x ff;//Hi_Z
}
//ADC初始化
//轉換時間:6uS
void adc_init(void)
{
ADCSRA = 0x00//禁用adc
ADMUX = 0x20//香奈兒0,aref和leftorder8bit,ad轉換結果左對齊。
//ADMUX = 0x 00;//10位
ACSR = 0x 80;//禁用ACD模擬比較器被禁用。
ADCSRB = 0x00//連續轉換模式
ADCSRA = 0x96//使能ADC,清零ADC IF 128 PScan-1001 0110:啟動ADC,ADC中斷標誌,ADC預分頻器64。
}
//看門狗初始化
//預分頻:128K 1s
void看門狗_init(void)
{
WDR();//這可以防止使能復位看門狗超時。
wdt CSR | =(1 & lt;& ltWDCE)|(1 & lt;& ltWDE);/* 2006年10月30日Umesh*/看門狗修改使能,四個周期後自動復位。看門狗系統復位使能,
wdt CSR = 0x 1E;//看門狗使能-不要忘記發出WDRs——0001 11110
}//看門狗修改使能,看門狗系統復位使能,振蕩周期128K,溢出時間1.0S。
//調用此例程初始化所有外設
//定時器0初始化-預分頻:1
// WGM: PWM快速
//期望值:46.875KHz
//實際值:46.875KHz (0.00%)
void定時器0_init(void)
{
TCCR0B = 0x00///stop——WGM02=0 = 0,無時鐘,TC不工作。
tcnt 0 = 0x 01;//集合計數——0000 0001
OCR0A = 0x00
TCCR0A = 0xC3//110011:wgm 01,0 = 11,011快速PWM模式,TOP = 0xFFCOM0A1:0=11。當匹配發生時,OC0A置位,當計數到最大值時,OC0A清零。
//TCCR0B = 0x 01;//啟動定時器COM0B1:0=00,端口正常工作,OC0B未連接。
}
//定時器2初始化-預分頻:1024
// WGM:正常
//所需的值:10毫秒
//實際值:9.984毫秒(0.2%)
//晶體:12.0000Mhz
void定時器2_init(void)
{
TCCR2B = 0x00//stop——WGM22波形產生模式= 0;沒有時鐘,TC不起作用。
ASSR = 0x00//設置async模式異步狀態寄存器=0,可以寫新值。
TCNT2 = 0x8B//設置8B @ 12 MHz D9 @ 4 MHz——1000 1011,139
//OCR2A = 0x 75;——117
//OCR2B = 0x 00;——0
TCCR2A = 0x00WGM21:0=00,正常工作模式,COM2A1:0=00,COM2B1:0=00正常端口運行,OC2A和OC2B不連接。
//TCCR2B = 0x 07;//開始
}
void初始化設備(void)
{
//停止錯誤中斷,直到設置完畢
CLI();//禁用所有中斷全局中斷禁用
port _ init();//初始化端口
看門狗_ init();//初始化看門狗
定時器0 _ init();//初始化定時器0
timer 2 _ init();//初始化定時器2
ADC _ init();//初始化AD
MCUCR = 0x00//忍不住用上拉電阻。
EICRA = 0x00//擴展ext ints外部中斷控制寄存器,當INT1為低時,產生中斷請求,當INT0為低時,產生中斷請求。
EIMSK = 0x00//外部中斷屏蔽寄存器,外部中斷請求使能位INT0,INT1為0。
TIMSK0 = 0x00//定時器0中斷源OCIE0A inturp使能
//TC0輸出比較匹配AB中斷使能=00,TC0溢出中斷使能位=0。
timsk 1 = 0x 00;//定時器1中斷源
//TC1輸入捕獲中斷使能= 0;TC1輸出比較AB匹配中斷使能=00,TC1溢出中斷使能=0。
tims k2 = 0x 01;//定時器2中斷源
//TC2輸出比較匹配AB中斷使能=00,TC2溢出中斷使能=1。
PCMSK0 = 0x00//引腳更改屏蔽0引腳更改屏蔽寄存器被禁用。
pcmsk 1 = 0x 00;//pin更改掩碼1
PCMSK2 = 0x00//引腳改變屏蔽2
PCICR = 0x00//引腳更改使能引腳電平更改中斷控制寄存器
PRR = 0x 00;//電源控制器功耗抑制寄存器
SEI();//重新啟用中斷全局中斷打開。
//所有外設現在都已初始化
}
////////////////////////////////////////////////////////////////////////////////
#pragma中斷處理程序定時器2_ovf_isr:iv_TIM2_OVF
void定時器2_ovf_isr(void)
{
TCNT2 = 0x8B//重載計數器值8B 12MHz D9@4MHz
//if(ad_timeflag==1)
//ad _ time flag = 0;//10ms停止AD采樣
if(++timecount==170)
{
WDR();
time count = 0;
OCR0A = 0x00
ad _ time flag = 1;//ad可以采樣。
TCCR2B = 0x00//停止時間2
}
}
////////////////////////////////////////////////////////////////////////////////
//8位AD轉換器admux_value是通道選擇參數。
int adconver(uchar admux_value)
{
uchar get_ad_value=0,I;
uint ad _ value = 0;
const uchar getad _ value[255];
//ADCSRA = 0x 97;//亞丁ADIF 1 128預掃描69us @12MHz
ADMUX = admux _ value
for(I = 0;我& lt255;i++)
{
WDR();
ADCSRA | =位(ADSC);//啟動ADC
而(ADCSRA & amp(1 & lt;& ltADSC));
ADCSRA | =(1 & lt;& ltADIF);
//get _ ad _ value = ADCL;
//get _ ad _ value | =(uint)(ADCH & lt;& lt8);
get _ ad _ value = ADCH;
getad _ value[I]= get _ ad _ value;
}
//ADCSRA = 0x 00;//停止adc
for(I = 1;我& lt255;i++)
{
ad _ value+= getad _ value[I];//丟棄第壹個結果
}
ad _ value/= 254;
return(ad _ value);
}
////////////////////////////////////////////////////////////////////////////////
//10位AD轉換器admux_value為通道選擇參數。
/*int adconver(uchar admux_value)
{
烏恰爾壹世;
uint get_ad_value=0,ad _ value = 0;
const uint getad _ value[61];
ADMUX = admux _ value
for(I = 0;我& lt61;i++)
{
ADCSRA | =位(ADSC);//啟動ADC
而(ADCSRA & amp(1 & lt;& ltADSC));
ADCSRA | =(1 & lt;& ltADIF);
get _ ad _ value = ADCL;
get _ ad _ value | =(uint)(ADCH & lt;& lt8);
getad _ value[I]= get _ ad _ value;
}
for(I = 1;我& lt61;i++)
{
ad _ value+= getad _ value[I];//丟棄第壹個結果
}
ad _ value = ad _ value/60;
return(ad _ value);
}*/
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
無效費用_控制_上限(無效)
{
if(flag_c==0)
{
//TCCR0B | = BIT(CS00);//起始定時器0
TCCR0B = 0x 01;//TCCR0B = 0x 02 8預掃描= 0x 01 1預掃描
OCR0A = 0x00
PORTD |=位(PD0);//off SW1
flag _ c = 1;
//flag _ NC = 0;
//delay _ ms(1000);
PORTB | = BIT(Pb 1);//on +12V_1
frist _ charge _ flag = 0;//清除第壹個充電標誌。
}
否則返回;
}
無效費用_控制_ncap(無效)
{
WDR();
港口& amp= ~ BIT(Pb 1);//off +12V_1
OCR0A = 0x00
TCCR0B = 0x00//關閉定時器0
PORTD | =位(PD6);
波特德& amp= ~ BIT(PD0);//在SW1上
}
///////////////////////////////////////////////////////////////////////////////
void scan_key(void)
{
WDR();
//PORTD _ 0 = PINB _ 2;
PORTD _ 1 = PINB _ 3;
PORTD _ 2 = PINB _ 4;
波特德_ 3 = PINB _ 5;
}
////////////////////////////////////////////////////////////////////////////////
主()
{
uchar充電開關;
uint ocr0a _ temp
init _ devices();
frist _ charge _ flag = 0;
港口& amp= ~ BIT(Pb 1);//off +12V_1
delay _ ms(80);
batt _ volt 0 = ad conver(samping _ batt);//采樣Vbatte
batt _ volt 0 _ temp = batt _ volt 0 * 3/10;//實際電池電壓值
while(1)
{
WDR();
scan _ key();
if(ad_timeflag==1)
{
delay _ ms(10);
batt _ volt 1 = ad conver(samping _ batt);//采樣Vbatte
batt _ volt 1 _ temp = batt _ volt 1 * 3/10;//實際電池電壓值
cap _ volt 0 = ad conver(samping _ cap);//采樣Vcap
cap _ volt 0 _ temp = cap _ volt 0 * 3/10;//實際電容電壓值
if(batt _ volt 1 _ temp & gt;電容_電壓_溫度)
{
if((batt _ volt 1 _ temp-cap _ volt 0 _ temp)>3) //充電閾值壓差4V
{
//charge _ control _ cap();
TCCR0B|=位(cs 01);//(1 & lt;& ltcs 01)|(1 & lt;& ltCS00);// on PWM位(CS01)5.89KHz@12MHz位(CS00)15.6 khz 1預掃描@4MHz
PORTD |=位(PD0);//off SW1
PORTB | = BIT(Pb 1);//on +12V_1
charge _ switch = cap _ volt 0 _ temp/5;
開關(charge_switch) //5V是電壓等級。
{
情況0: //0~4.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-20;//50
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例1: //5~9.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-15;//75
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例二://10~14.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-10;//105
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例三://15~19.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-5;//135
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
情況4: //20~24.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp;//165
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例五://25~29.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp;//195
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例6: //30~34.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp;//215
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例7: //35~39.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-4;//221
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例8: //40~44.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-9;//258
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例9: //45~49.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-15;//279
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例10: //50~54.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-21;//300
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
案例11: //55~59.9V
ocr0a _ temp =((fixed _ BC _ volt 0+charge _ switch * 5)* 255)/batt _ volt 0 _ temp-28;//320
if(ocr0a _ temp & gt;255)
OCR0A = 255
其他
OCR0A = ocr0a _ temp
打破;
默認值:
電荷_控制_ ncap();
打破;
}
}
其他
電荷_控制_ ncap();
}
其他
電荷_控制_ ncap();
ad _ time flag = 0;//時間到了才能采樣。
TCCR2B = 0x07//啟動定時器2*/
}
}
}