Например TDA7294

Форум РадиоКот • Просмотр темы - Подскажите по ШИМ
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Ср июл 30, 2025 23:30:17

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Форум закрыт Эта тема закрыта, Вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 10 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Подскажите по ШИМ
СообщениеДобавлено: Пт ноя 04, 2011 20:21:56 
Встал на лапы

Карма: 2
Рейтинг сообщений: 6
Зарегистрирован: Вт сен 20, 2011 18:41:41
Сообщений: 131
Откуда: Вьетнам
Рейтинг сообщения: 0
Подскажите как плавно включить а через 10 секунд плавно выключить все светодиоды на порту PORTD.

Сейчас включаю поочередно

void led_on(unsigned int mask){
unsigned char on_time;
for (on_time = 1; on_time < 100; on_time++) {
PORTC &= ~mask; // выключаем светодиод
delay(100-on_time); // отсчитываем время в выключенном состоянии
PORTC |= mask; // включаем светодиод
delay(on_time); // отсчитываем время во включенном состоянии
}


for (mask = 0x01; mask; mask <<= 1)
{
led_on(mask);
delay_ms(100);
}


как переделать под плавное включение всего порта сразу


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Сб ноя 05, 2011 20:35:53 
Прорезались зубы

Зарегистрирован: Вс авг 15, 2010 20:42:44
Сообщений: 249
Откуда: Тюмень
Рейтинг сообщения: 0
Извините, но решил написать здесь. Может есть у кого-нибудь код на асме для Мега8 ШИМ плавное зажигание светодиода? или подскажите пожалуйста алгоритм, чтобы я мог сравнить со своими додумками :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Сб ноя 05, 2011 20:41:24 
Мудрый кот
Аватар пользователя

Карма: 2
Рейтинг сообщений: 5
Зарегистрирован: Ср янв 23, 2008 22:11:54
Сообщений: 1867
Откуда: Калининград
Рейтинг сообщения: 0
ururur писал(а):
как переделать под плавное включение всего порта сразу

Включить все светодиоды к одной ноге с аппаратной ШИМ через транзистор и резисторы.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Вс ноя 06, 2011 15:27:57 
Встал на лапы

Карма: 2
Рейтинг сообщений: 6
Зарегистрирован: Вт сен 20, 2011 18:41:41
Сообщений: 131
Откуда: Вьетнам
Рейтинг сообщения: 0
Serhio писал(а):
Извините, но решил написать здесь. Может есть у кого-нибудь код на асме для Мега8 ШИМ плавное зажигание светодиода? или подскажите пожалуйста алгоритм, чтобы я мог сравнить со своими додумками :)


Могу дать на C. Код под мегу 8. Светодиод вешать на ножку PB1

Код:
#include <avr/io.h>//библиотека ввода/вывода
 
//Програма задержки
void wait (unsigned int a)
{
unsigned int i;
for (i=a;i>0;i--);
}
 
//Програма инициализации ШИМ
void pwm (void)
{
  TCCR1A=(1<<COM1A1)|(1<<WGM10);
  TCCR1B=(1<<CS10);      
  OCR1A=0x00;         //Начальная яркость нулевая
}
 
//Основная програма
int main(void)
{
unsigned char i;
 
 DDRB=0x02;            //Делаем PB1  на выход
 pwm();
 
 while (1)
  {
    for (i=0;i<255;i++)      //Плавно повышаем яркость
    {
     OCR1A++;
     wait(1000);                       // Ждем
    }
    for (i=0;i<255;i++)      //Плавно понижаем яркость
    {
     OCR1A--;
     wait(1000);                     Ждем
    }
  }
 
 return 1;
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Вс ноя 06, 2011 16:02:54 
Прорезались зубы

Зарегистрирован: Вс авг 15, 2010 20:42:44
Сообщений: 249
Откуда: Тюмень
Рейтинг сообщения: 0
Благодарю :)

Подскажите пожалуйста как расчитать время задержки для ШИМ. Есть с обучалки задержка
Delay: out PortB,Temp

ldi Temp1,1
ldi Temp2,1
ldi Temp3,2

Loop: dec Temp1
brne Loop

dec Temp2
brne Loop

dec Temp3
brne Loop

ret

как узнать сколько миллисекунд она длится?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Пн апр 23, 2012 20:52:39 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 09:14:18
Сообщений: 51
Откуда: Липецк
Рейтинг сообщения: 0
Здравствуйте. Написал примитивный код без прерываний для мигания 2х светодиодов, на таймере 1(aTMEGA32A).Свтодиод на канале А плавно гаснит, а на В зажигается. Предделитель поставил 1, период = 0,125мкс, но при задержки в 0,01с(_delay_ms(10)) период составляет 0,01*255+0,000125*255=2,55с. _delay_ms(100) - использую как-бы для "устаявшегося значения", но вопрос ни в этом.
1. Подскажите как реализовать задержку, не используя _delay_ms(10), потому как при этой функции микроконроллер просто отсчитывает время не делая больше ничего?
2. Таймер считает до 255 потому что мы взяли (0<<WGM13)|(1<<WGM12) = WGM1Х - Fast PWM 8 бит?
Код:
#include<avr/io.h>
#include<util/delay.h>
int main(void) {
 DDRD=(1<<PD4)|(1<<PD5);//PORTD ненадо настраивать
 TCCR1A=(1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(0<<WGM11)|(1<<WGM10);
 TCCR1B=(0<<WGM13)|(1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10);
 OCR1A = 0;
 OCR1B = 255;
 asm("cli");//Запрещаем прерывания
  while(1) {
   OCR1A++;
   OCR1B--;
   _delay_ms(10);
   if(OCR1A==255) {
    _delay_ms(100);
   OCR1A = 0;
   OCR1B = 255;
    _delay_ms(100);
   }
  }
}

Затем решил перевести на прерывания, но пока без задержек. Коэф-нт деления поставил 1024, чтобы было видно затухание и зажигание соответственно. Написал код ниже:
Код:
#include<avr/io.h>
#include <avr/interrupt.h>
//Прерывание по совпадению канала А. Таймер 1
ISR (TIMER1_COMPA_vect) {
   PORTD|=(1<<PD5);
   OCR1A++;
}
//Прерывание по совпадению канала B. Таймер 1
ISR (TIMER1_COMPB_vect) {
   PORTD|=(1<<PD4);
   OCR1B--;
}
//Прерывание по переполнению Таймера 1
ISR (TIMER1_OVF_vect) {
//   flz=1;
   PORTD&=~(1<<PD5);
   PORTD&=~(1<<PD4);
}
int main(void) {
//Главое все эти настройки регистров прописывать в главном теле
 DDRD=(1<<PD4)|(1<<PD5);//PORTD ненадо настраивать
 PORTD=(0<<PD4)|(0<<PD5);
 TCCR1A=(0<<WGM11)|(1<<WGM10);
 TCCR1B=(0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);
 //Вкл. прер. по совпадению в А, В и переполнению Т1
 TIMSK=(1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1);
 OCR1A=2;
 OCR1B=253;
 asm("sei");//Разрешаем все прерывания
 TCNT1=0;
  while(1) {
     if(OCR1A==255 || OCR1B==0) {
    OCR1A=0;
    OCR1B=255;
   }
  }
}
}

2. Но как сделать более плавное затухание и зажигание? Частоту снизить не получится(если только взять внешний кварц с меньшей частотой), т.к. делитель самый высокий 1024.
Помогите разобраться с этими 3мя вопросами. С уважением Дмитрий.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Пн апр 23, 2012 21:04:48 
Друг Кота

Карма: -25
Рейтинг сообщений: 187
Зарегистрирован: Сб апр 21, 2012 19:21:43
Сообщений: 4753
Рейтинг сообщения: 1
1. Для этих целей используют таймеры. Если задач немного, то можно для каждой использовать свой таймер. В последних Атмегах их 3. Если задач больше, надо реализовывать конвейер. Об этом хорошо написано на http://easyelectronics.ru/

3. Если не хватает встроенного счетчика, можно устроить свой, подсчитывая число срабатываний таймера. Для этого в обработчике прерывания инкрементируем переменную, а в теле программы проверяем ее значение. Если больше, запускаем обработчик и обнуляем. На инкремент тратится мало тактов, на проверку - тоже. Так что задержек не будет


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Пн апр 23, 2012 22:42:30 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 09:14:18
Сообщений: 51
Откуда: Липецк
Рейтинг сообщения: 0
Orion33 писал(а):
3. Если не хватает встроенного счетчика, можно устроить свой, подсчитывая число срабатываний таймера. Для этого в обработчике прерывания инкрементируем переменную, а в теле программы проверяем ее значение. Если больше, запускаем обработчик и обнуляем. На инкремент тратится мало тактов, на проверку - тоже. Так что задержек не будет

Пробывал добавить инкремент в обработчик прерываний, для снижения частоты(более долгом затухании и разгорании). Время затухания увелилось вдвое, но мерцание сильное. Надо подумать над плавностью смены сигнала. Хотя при делители 512 мерцания невидно.
Код:
#include<avr/io.h>
#include <avr/interrupt.h>
volatile char flza=0;//Флаг задержек А
volatile char flzb=0;//Флаг задержек В

//Прерывание по совпадению канала А. Таймер 1
ISR (TIMER1_COMPA_vect) {
   if(flza==0) {
   flza=1;
   PORTD|=(1<<PD5);
   OCR1A++;
   } else {flza=0;}
}
//Прерывание по совпадению канала B. Таймер 1
ISR (TIMER1_COMPB_vect) {
   if(flzb==0) {
   flzb=1;
   PORTD|=(1<<PD4);
   OCR1B--;
   } else {flzb=0;}
}
//Прерывание по переполнению Таймера 1
ISR (TIMER1_OVF_vect) {
   PORTD&=~(1<<PD5);
   PORTD&=~(1<<PD4);
}
int main(void) {
 DDRD=(1<<PD4)|(1<<PD5);//PORTD ненадо настраивать
 PORTD=(0<<PD4)|(0<<PD5);
 TCCR1A=(0<<WGM11)|(1<<WGM10);//WGM1Х - Fast PWM 8 бит
 TCCR1B=(0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);
 TIMSK=(1<<OCIE1A)|(1<<OCIE1B)|(1<<TOIE1);
 OCR1A=2;
 OCR1B=253;
 asm("sei");
 TCNT1=0;
  while(1) {
     if(OCR1A==255 || OCR1B==0) {
    OCR1A=0;
    OCR1B=255;
   }
  }
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Пн апр 23, 2012 23:14:20 
Открыл глаза

Зарегистрирован: Чт мар 22, 2012 09:14:18
Сообщений: 51
Откуда: Липецк
Рейтинг сообщения: 0
Решено: надо использовать предделитель 512, а в обработчике прерываний просто добавлять 'конечные автоматы' или промежуточные значения if(flza==0) {..} else { if(flza==1) {flza=2;} else {flza=0;}} Наглядней через switch.
Может кто знает как проще сделать напишите пожалуста.
Orion33 писал(а):
Если задач больше, надо реализовывать конвейер. Об этом хорошо написано на http://easyelectronics.ru/

Я как раз там статьи и читал про ШИМ, но она на асме, и попробывал написать на Си. Только я не понял про какой 'конвейер' идет речь?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Подскажите по ШИМ
СообщениеДобавлено: Вт апр 24, 2012 09:06:44 
Друг Кота

Карма: -25
Рейтинг сообщений: 187
Зарегистрирован: Сб апр 21, 2012 19:21:43
Сообщений: 4753
Рейтинг сообщения: 0
EmDmAl писал(а):
Orion33 писал(а):
Если задач больше, надо реализовывать конвейер. Об этом хорошо написано на http://easyelectronics.ru/

Я как раз там статьи и читал про ШИМ, но она на асме, и попробывал написать на Си. Только я не понял про какой 'конвейер' идет речь?

Там про RTOS есть цикл статей, точно название сейчас не помню. Смысл в том, что единый таймер через определенные промежутки времени опрашивает очередь, выполняет операцию из начала и сдигает очередь. Другие прерывания могут вмешиваться в эту очередь и вставлять свои обработчики согласно приоритету. Сложно, но ИМХО правильное решение. Если один раз разобраться, можно потом просто задачи новые в конвейер добавлять, а ядро останется всегда одним)


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Форум закрыт Эта тема закрыта, Вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y