|
| ||||||||||||||||||||||||||||||||||||||||||||||
|
Опубликовано 2013-04-11 11:24:04 автором Ruslan Контроллер ветрогенератораПосле изготовления ветряка, встал вопрос о контроллере заряда акб.Задача:
Внутрености контроллера Программа написана на c в CVAVR
#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
/* 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
2. Измеряем напряжение
Дальше измеряем напряжение на резисторном делителе
Составим пропорцию, как описано выше, и получим
Искомое напряжение = 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); //делаем задержку
};
}
Для повторения нам понадобится:
Принцип действия Контроллер в динамическом режиме проверяет ток и напряжение заряда батареи. Когда батарея разряжена, ее сопротивление мало, и поэтому при зарядке через нее может пойти большой ток (больше 1/10 емкости). Поэтому в начальном цикле зарядки батереи контроллер следит, чтобы ток не превышал 1/10 емкости батареи. По мере зарядки, сопротивление батереи увеличиватся, ток уменьшается и начинает расти напряжение на акб. Контроллер следит, чтобы напряжение не превышало 14.2 в. Если ток или напряжение превышают установленные нормы, то скважность ШИМ-сигнала на ножке PB1 растет и лишняя энергия скидывается на балласт. Генератор вырабатывает трёхфазное переменное напряжение, а нам для зарядки батареи надо постоянное напряжение. Для выпрямления используется мост, собранный по схеме трёхфазного выпрямителя Ларионова на трёх диодных полумостах (на 6 диодах)
Комментарии - (9)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
||||||||||||||||||||||||||||||||||||||||||||||