Материал прислал Александр.
Зарядное устройство
Программа
//****************************************************************************************
//****************************************************************************************
//зарядное устройство V1
//****************************************************************************************
//****************************************************************************************
#include
#include
#include
/*
// I2C Bus functions
#asm
.equ __i2c_port=0x18 ;PORTB
.equ __sda_bit=5
.equ __scl_bit=6
#endasm
#include
*/
//****************************************************************************************
#define SHDN PORTA.6 //on/off current sensor amplifier
#define B_OFF PORTA.5 //battery off
#define ERROR PORTB.0 //error indicator led(red)
#define CHARGE PORTB.1 //charge indicator led(green)
//constants
#define HIST 20 //voltage histerezis
#define Imin 550
#define Umin 700
#define PWmax 250 //max pulse width
#define PWmin 1 //min pulse width
//****************************************************************************************
#define ADC_VREF_TYPE 0x00
void init(void);
void timer_off(void);
void timer_on(void);
bit i2c_run=0;
register unsigned char PW=0;
register unsigned int CURRENT=0,
U1=0,
U2=0,
Izar=925, //1000ma
Uzar=740; //8.4V
interrupt [ADC_INT]
void adc_isr(void){
static register unsigned char ch=0;
switch(ch){
case 0: U1=((U1+ADCW)>>1); //U1=((U1+ADCW)/2)
ADMUX=2;
ch=2;
break;
case 2: CURRENT=((CURRENT+ADCW)>>1);
ADMUX=6;
ch=6;
break;
case 6: U2=ADCW;
ADMUX=0;
ch=0;
break;
};//switch
if(CURRENT>Izar)PW--;
if(U1Izar)PW--;
else PW++;
};//if
if(U1>Uzar)PW--;
if(PWPWmax)PW=PWmax;
OCR1B=PW;
i2c_run=1;//start i2c transmission
ADCSR|=0x40;//start next conversion
#asm("wdr")
}//adc_isr
void init(){
PORTA=0x00;
DDRA=0b00100000;
PORTB=0x00;
DDRB=0b00001111;
// Timer/Counter 1 initialization
PLLCSR=0x02;// Enable the PLL
while ((PLLCSR & 1)==0);// Wait for the PLL to lock
PLLCSR|=0x04;// Enable the 64MHz clock
TCCR1A=0x11;
TCCR1B=0x81;
//TCNT1=0x00;
//OCR1A=0x00;
OCR1B=0; //pulse width (PW)
OCR1C=0xff; //freqency (~250kHz)
// ADC initialization
ADMUX=ADC_VREF_TYPE;
ADCSR=0b11001111;
/*
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/16k
#asm("wdr")
WDTCR=0x08; */
//i2c_init();
sleep_enable();
#asm("sei")// Global enable interrupts
}//init()
void timer_off(){
TCCR1A=0;
TCCR1B=0;
OCR1B=0;
PW=0;
ERROR=1;
CHARGE=0;
}//timer_off
void timer_on(){
TCCR1A=0x11;
TCCR1B=0x81;
CHARGE=1;
ERROR=0;
}//timer_on
//********************************************************************************************
void main(void){
init();
CHARGE=1;
ERROR=0;
SHDN=1;
B_OFF=1;
while(1){
#asm("wdr")
if((U1>Uzar)&&(CURRENT800)){ //short circuit protection
timer_off();
delay_ms(5000);
};//if
if(U1<(Uzar-HIST))timer_on();//charge start
/*
if(i2c_run){
i2c_start();
i2c_write((unsigned char)U1);
i2c_write((unsigned char)CURRENT);
i2c_stop();
i2c_run=0;
};//if
B_OFF=0;
delay_ms(2000);
B_OFF=1;
delay_ms(2000);
*/
};//while
}//main()