Top.Mail.Ru
Ответы

Помогите с кодом С++ для Atmega8A. Из-за уменьшения скважности ШИМ PWM почему-то меняются показания АЦП.

Где ШИМ там и АЦП соответственно напряжение на АЦП не выше 2,67 вольт.
Чем меньше делаю скважность тем меньше становится напряжение на АЦП, на схеме проблемм нет. По сути я безусловно зарезал ШИМ на схеме в сторону АЦП тоесть АЦП слышит красивое напряжение не ШИМ.

И на последок, может у кого код за валялся код с ШИМ и АЦП на одной атмеге8? Готов даже отблагодарить, большой печенкой)))

Вот код
Весь код не влез, там дальше только кнопки больше-меньше и индикатор.
ISR (TIMER2_OVF_vect)
{
PORTC|=((1<<2)|(1<<1)|(1<<0));
if (count==0)
{
PORTD=SEGMENTE[first_register];
//PORTD = SEGMENTE[display % 1000 / 100];
PORTC&=~(1<<PC1);
}
if (count==1)
{
PORTD=SEGMENTE[second_register];
//PORTD = SEGMENTE[display % 100 / 10];
PORTC&=~(1<<PC2);
}
count++;
if (count==2)count=0;
}
volatile unsigned long value;
volatile unsigned int adc_counter;
// Прерывание по окончанию преобразования АЦП
ISR (ADC_vect)
{
value = value + (ADC*11/4); // Суммируем старое и новое значения АЦП, преобразуем
adc_counter++; // Увеличиваем счетчик измерений
}
// Главная функция

int main (void)
{
//Segments all catoude
DDRC |= (1<<PC0 | 1<<PC1 | 1<<PC2); // Выходы на общие аноды
PORTC = 0; // Ноль на выходе
DDRD = 0xFF; // Выходы на сегменты
PORTD = 0xFF; // Ноль на выходе
//Segments all catoude
// Настройка Таймера 2
TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
TCCR2 |= (1 << CS21); // Предделитель на 8
// Настройка АЦП
ADCSRA |= (1 << ADEN) // Разрешение АЦП
|(1 << ADSC) // Запуск преобразования
|(1 << ADFR) // Непрерывный режим работы АЦП
|(1 << ADPS2)|(1 << ADPS1) // Предделитель на 64 (частота АЦП 125kHz)
|(1 << ADIE); // Разрешение прерывания от АЦП
ADMUX |= (1 << REFS1)|(1 << REFS0)
|(0 << MUX3)|(1 << MUX2)|(0 << MUX1)|(1 << MUX0);//Вход АЦП - PC5
sei(); // Глобально разрешаем прерывания
// Главный цикл
//Доп запуск
//DDRB |= (1<<PB1);
//Доп запуск
//Кнопки
DDRC &= ~(1 << PC3);
PORTC |= (1 << PC3);
DDRC &= ~(1 << PC4);
PORTC |= (1 << PC4);
//Кнопки
while(1)
{
OCR1A = scvaj;
//Voltmeter
if(adc_counter > 100) // Если количество измерений больше 300
{
display = value/adc_counter; // Вычисляем среднее значение АЦП
adc_counter = 0; // Обнуляем счетчик измерений
value = 0; // Обнуляем буфер АЦП
}
//Voltmeter

//Value 12VTotal OFF
if(in_process == 0){
if(start_pulse == 1){
TCCR1A &= ~(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //OFF x64
TCCR1B &= ~(1<<WGM13)|(1<<WGM12)|(1<<CS10); //OFF set prescaler=1
start_pulse = 0;
}
if(start_charge == 1){
DDRB &= ~(1<<PB0); //OFF IO
PORTB &= ~(1 << PB0); //OFF LED
start_charge = 0;
}
if(complite == 0){
DDRB |= (1< 9){
in_process = 0;
}
// Set value 0
if(start_test == 50){
// Sin PWM
if((display % 100 / 10) >= 1){
if((display % 100 / 10) < 9){
if(start_pulse == 0){
if(in_process == 0){
in_process = 1;
}
//PWM
DDRB |= (1<50Hz
TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10); //set prescaler=1
OCR1A = scvaj;
//PWM
start_pulse = 1;
if(start_charge == 1){
PORTB &= ~(1 << PB0);
start_charge = 0;
}

}
}
}
// Sin PWM

По дате
По Рейтингу
Аватар пользователя
Просветленный
8лет

Чувак, тебе лучше с такими вопросами пойти на спец. форумы. Тут тебе по широтно-импульсной модуляции, преобразователям вряд ли помогут.