Контроллер заряда акб от ветрогенератора на атмега8
Добавлено: 04 фев 2015, 09:44
Здравствуйте уважаемые форумчане! Пришел к вам за помощью.
Собираю контроллер ветрогенератора, в интернете нашел приемлемый проект - несложный и дешевый, с готовой прошивкой и схемой в протеусе.
http://articles.greenchip.com.ua/3-0-24-0.html
Кое-что нужно изменить/доработать в прошивке МК с измерением напряжения на шунте и заряда аккумулятора.
Кое-что мне просто не понятно, напишу по порядку.
У автора проекта максимальный ток заряда АКБ 10А (судя по протеусу). У меня макс. ток заряда будет 19А, поэтому желательно, делая с запасом, сделать шкалу до 25А. То есть при входе на МК 4,5вольт (усиливаем сигнал с шунта операционником) максимальный измеренный ток составлял 25А. Шунт уже подобрал - при 25А падение напряжение 375мВ, => коэффициент усиления ОУ равен 12.
Аналогично с измерением напряжения. Шкалу надо до 45вольт при 4,5вольтах на входе МК. Коэффициент делителя получится равен 10.
При настройке тока и напряжения через дисплей, у автора шаг настройки составляет 10 милливольт/миллиампер, получается очень медленно, хотелось чтобы шаг был 100 - но это на работоспособность не влияет - можно оставить и так.
Скорректировать это в прошивке я не могу - не хватает знаний.
И еще пара вопросов:
1. Зачем нужно опорное напряжение? Почему нельзя (или можно) задать в МК, что при входе на ногу 5воль это соответствует например 25А, а промежуточные значения он посчитает. В чем плюсы и минусы этих вариантов?
2. На схеме нет, но вроде в прошивке указан кварц 1МГц. В продаже такой не нашел, есть на 2 и 4, что нужно переделать чтоб применить их?
3. В строке где вычисляется напряжение в программе МК прибавляют 400 – не пойму зачем.
Ну вроде все, очень надеюсь на вашу помощь, автор проекта на связь не выходит.
Заранее большое спасибо.
программа вроде эта(у автора выложенно несколько, вроде все одинаковые)
Собираю контроллер ветрогенератора, в интернете нашел приемлемый проект - несложный и дешевый, с готовой прошивкой и схемой в протеусе.
http://articles.greenchip.com.ua/3-0-24-0.html
Кое-что нужно изменить/доработать в прошивке МК с измерением напряжения на шунте и заряда аккумулятора.
Кое-что мне просто не понятно, напишу по порядку.
У автора проекта максимальный ток заряда АКБ 10А (судя по протеусу). У меня макс. ток заряда будет 19А, поэтому желательно, делая с запасом, сделать шкалу до 25А. То есть при входе на МК 4,5вольт (усиливаем сигнал с шунта операционником) максимальный измеренный ток составлял 25А. Шунт уже подобрал - при 25А падение напряжение 375мВ, => коэффициент усиления ОУ равен 12.
Аналогично с измерением напряжения. Шкалу надо до 45вольт при 4,5вольтах на входе МК. Коэффициент делителя получится равен 10.
При настройке тока и напряжения через дисплей, у автора шаг настройки составляет 10 милливольт/миллиампер, получается очень медленно, хотелось чтобы шаг был 100 - но это на работоспособность не влияет - можно оставить и так.
Скорректировать это в прошивке я не могу - не хватает знаний.
И еще пара вопросов:
1. Зачем нужно опорное напряжение? Почему нельзя (или можно) задать в МК, что при входе на ногу 5воль это соответствует например 25А, а промежуточные значения он посчитает. В чем плюсы и минусы этих вариантов?
2. На схеме нет, но вроде в прошивке указан кварц 1МГц. В продаже такой не нашел, есть на 2 и 4, что нужно переделать чтоб применить их?
3. В строке где вычисляется напряжение в программе МК прибавляют 400 – не пойму зачем.
Ну вроде все, очень надеюсь на вашу помощь, автор проекта на связь не выходит.
Заранее большое спасибо.
программа вроде эта(у автора выложенно несколько, вроде все одинаковые)
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h> //библиотека в которой лежыт функция sprintf
int Af=4000,Uf=14200;
unsigned long int u; //переменная для хранения напряжения в миливольтах
unsigned long int a; //переменная для хранения тока
unsigned long int w; //переменная для хранения значений потребляемой мощности
void incSkvag()
{
if (OCR1AL!=0) OCR1AL--;
}
void decSkvag()
{
if (OCR1AL!=255) OCR1AL++;
}
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x64;
a=read_adc(3); // читаем значения ацп с порта 0
u=read_adc(5); // читаем значения ацп с порта 1
/*
Измеряем ток Ток протекающий через шунт вичесляется по закону Ома I=U/R R=0,1 ом, a U(падения напряжения на шунте) мы будем измерять. Так как АЦП у нас 10 битный то максимальное число которое вернет функция read_adc() будет равно 1024, ето число будет еквивалентом напряжения на входе adc0. Например если read_adc() вернул 512 то ето значит што на вход adc0 ми подали половину опорного напряжения Штобы вычеслить реальное напряжения нам нужно сложыть пропорцию опорное напряжения - 1024 искомое напряжения - a В нас опорное напряжения=5.12 Искомое напряжения = 5.12*a/1024 или Искомое напряжения = 0,005*a для простоты переведьом вольти в миливольты домножыв на 1000 Искомое напряжения = 0,005*a*1000 Здесь всьо хорошо но мы не учли коефициент усиления ОУ разщитывается по формуле Кус=1+R1/R2 подставив получим Кус=(1+4)=5 Реальное напряжения = 0,005*a*1000/5 получаем просто a
Измеряем напряжение Дальше измеряем напряжение на резисторном делителе Сложым пропорцию как описано выше и получим Искомое напряжения = 0,005*u*1000 Надо еще учесть коефициент резисторного делителя напряжения в нас он равен Кдел=(R1+R2)/R2 подставив получим Кдел=(10+1)/1=11 Рельное напряжения = 0,005*u*1000*11 */
u=55*u+400; //вычисляем значения напряжения в миливольтах
a=a*10; // вычесляем значения тока по закону ома I=U/R=a/100*1000=a*10, в милиамперах
w=a*u; //вычесляем потребляемую мощность
//регулировка напряжения и тока
if ( (a>Af) || (a>8000) )//регулировка по току
{
incSkvag();
}
else
{
if (u>Uf)//регулировка по напряжению
{
incSkvag();
}
else
{
decSkvag();
}
}
}
void main(void)
{
// Declare local variables here
unsigned char i=2,k[3][32];
sprintf( k[0],"Setup A=%i",Af);
sprintf( k[1],"Setup U=%i",Uf);
// Input/Output Ports initialization
PORTB=0b00011100;
DDRB= 0b00000010;
// Port C initialization
PORTC=0x00;
DDRC=0x00;
// Port D initialization
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
TCCR0=0x03;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Inverted
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xC1;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0xff;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 500,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x81;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Alphanumeric LCD initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
sprintf( k[2],"I=%u,%uA U=%u,%uV\nW=%u,%lu K=%i",
a/1000, //Целая честь тока
(a%1000)/100, //Дробная часть тока
u/1000, // Целая часть напряжения
(u%1000)/100, //Дробная часть напряжения
w/1000000, // Целая часть мощности
(w%1000000)/100000, //Дробная часть мощности
OCR1AL
); //формируем строку для вывода
//---------------------------------------------------------------
//работа с кнопками
if (PINB.2==0)
{
//переключаем меню
if (++i>2) i=0;
}
if (PINB.3==0) //проверяем нажата ли кнопка плюс
{
if (i==0) {Af=Af+10; sprintf( k[i],"Setup A=%i ma",Af); }
if (i==1) {Uf=Uf+10; sprintf( k[i],"Setup U=%i mv",Uf); }
}
if (PINB.4==0) //проверяем нажата ли кнопка минус
{
if (i==0) { Af=Af-10; sprintf( k[i],"Setup A=%i ma",Af); }
if (i==1) { Uf=Uf-10; sprintf( k[i],"Setup U=%i mv",Uf);}
}
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(k[i]); //выводим сформированую строку на дисплей
delay_ms(100); //делаем задержку
};
}