Я вот тоже дорисовал
Спойлер


В моей схеме что самое лучшее это мк с оу сидят на так сказать отдельном от силовой части питании (на схеме специально так нарисовано) и по идее не должно быть помех от ключа.oleg110592 писал(а):сильно не всматривался в вашу схему - похоже что должна работать. В моей же схеме, если транзистор будет греться можно поставить полумост из двух транзисторов npn и pnp или драйвер как у вас.


Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int adc_counter,current;
volatile unsigned long current_value;
__attribute__((OS_main))
ISR(ADC_vect)
{
ADCSRA = 0; // Выключаем АЦП
current_value = current_value + ADCH; // Суммируем измеренные значения тока и помещаем в буфер
adc_counter++; // Увеличиваем счетчик выборок АЦП на 1
// Включаем АЦП
ADCSRA |= (1 << ADEN)|(1 << ADSC)|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0)|(1 << ADIE);
}
void main(void)
{
// Crystal Oscillator division factor: 1
CLKPR=0x80;
CLKPR=0x00;
PORTB=0b00000000;
DDRB=0b00001000;
// Enable the PLL
PLLCSR=0x02;
// Wait for the PLL to lock
while ((PLLCSR & 1)==0);
// Enable the 64MHz clock
PLLCSR|=0x04;
TCCR1=0x61; //64
//TCCR1=0x62; //32
//TCCR1=0x63; //16
//TCCR1=0x64; //8
GTCCR=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0xFF;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
OCR1A=128; // шим 50%
ADMUX |= (1 << REFS1)|(0 << REFS0)|(0 << REFS0); // Внутренний ИОН 1,1V
ADMUX |= (0 << MUX3)|(0 << MUX2)|(1 << MUX1)|(1 << MUX0); // Подключаем канал ADC3
ADCSRA |= (1 << ADEN) // разрешение АЦП
|(1 << ADSC)
|(1 << ADLAR) //8-bit ADC
// запуск преобразования
|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64
|(1 << ADIE); // разрешение прерывания от АЦП
sei(); // Глобально разрешаем прерывания
while (1)
{
if (adc_counter>10)
{
ADCSRA = 0;
current = (current_value/adc_counter);
if (current > 93)
{
OCR1A--;
}
if (current<92)
{
OCR1A++;
}
}
current_value = 0;
adc_counter = 0;
ADCSRA |= (1 << ADEN)|(1 << ADSC)|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0)|(1 << ADIE); //включаем ADC
}
}Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int adc_counter,current;
volatile unsigned long current_value;
__attribute__((OS_main))
SIGNAL(SIG_ADC)
{
ADCSRA = 0x00; // Выключаем АЦП
current_value = current_value + ADCH; // Суммируем измеренные значения тока и помещаем в буфер
adc_counter++; // Увеличиваем счетчик выборок АЦП на 1
//Включаем АЦП
ADCSRA=0b11111101;
}
int main(void)
{
// Crystal Oscillator division factor: 1
CLKPR=0x80;
CLKPR=0x00;
PORTB=0b00000000;
DDRB=0b00000010;
// Enable the PLL
PLLCSR=0x02;
// Wait for the PLL to lock
while ((PLLCSR & 1)==0);
// Enable the 64MHz clock
PLLCSR|=0x04;
TCCR1=0x61; //64
//TCCR1=0x62; //32
//TCCR1=0x63; //16
//TCCR1=0x64; //8
GTCCR=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0xFF;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
OCR1A=10; // шим 50%
ADMUX=0b10100011;
ADCSRA=0b11111101;
sei(); // Глобально разрешаем прерывания
while (1)
{
if (adc_counter > 20)
{
ADCSRA = 0x00;
current = (current_value/adc_counter);
if (current_value > 164)
{
OCR1A--;
}
if (current_value<162)
{
OCR1A++;
}
}
current_value = 0;
adc_counter = 0;
ADCSRA=0b11111101;
}
}Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
__attribute__((OS_main))
SIGNAL(SIG_ADC)
{
OCR1A=OCR1A*164/ADCH;
}
int main(void)
{
CLKPR=0x80;
CLKPR=0x00;
PORTB=0b00000000;
DDRB=0b00000010;
PLLCSR=0x02;
while ((PLLCSR & 1)==0);
PLLCSR|=0x04;
TCCR1=0x61; //64
GTCCR=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0xFF;
ACSR=0x80;
ADCSRB=0x00;
OCR1A=10;
ADMUX=0b10100011;
ADCSRA=0b11111101;
sei(); // Глобально разрешаем прерывания
while (1)
{
}
}Код: Выделить всё
while(1)
{
if(P1IN & 0x08)
Threshold = 273;
else
Threshold = 205;
ADC10CTL0 |= ENC + ADC10SC; // start sampling
while(ADC10CTL1 & ADC10BUSY);
ADC_avg = (ADC10MEM + ADC_avg * 7)>>3;
if((ADC_avg > Threshold+100)) tmp--;
if((ADC_avg < Threshold)) reg_counter++;
if((ADC_avg > Threshold)) reg_counter--;
if(reg_counter >500)
{
reg_counter = 0;
if(tmp < MAX_PWM+1) tmp++;
}
else
if(reg_counter <-500)
{
reg_counter = 0;
if(tmp > 0) tmp--;
}
TACCR1 = tmp;
ADC10CTL0 &= ~ENC;
if(!(flags & START_FLAG))
{
wdt_counter++;
if(wdt_counter >= START_DELAY)
{
wdt_counter = 0;
flags |= START_FLAG;
}
}
}