Например TDA7294

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





Текущее время: Вт апр 16, 2024 15:25:08

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


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



Начать новую тему Ответить на тему  [ Сообщений: 17 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 12:17:03 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
Здравствуйте! Решил сделать небольшой rgb контроллер для светодиодной ленты. Задача такая: имеется 3 кнопки (одна уменьшает яркость, другая увеличивает, а третья переключает между каналами светодиодов r => g => b). Сейчас пытаюсь сделать регулировку яркости для одного светодиода. Главное условие использовать программный шим! Вот написал подобное:
Код:
/*
 * GccApplication7.c
 *
 * Created: 20.04.2019 01:28:45
 * Author : Timofey
 */

#include <util/delay.h>
#define F_CPU 10000000UL
#include <avr/interrupt.h>
#include <stdlib.h>
#define BitIsSet(reg,bit) ((reg&(1<<bit)) !=0)
#define BitIsClear(reg,bit) ((reg&(1<<bit)) ==0)


#define nop() {asm("nop");}
unsigned int i, p, a, b, c, ms, x;

void delay_ms(int ms){
for (x=ms; x>0; x--) nop ();}


void led0(int led, int i, int p){
   PORTB &= ~_BV(led);   delay_ms(i);
   PORTB |= _BV(led);   delay_ms(p);}

SIGNAL(INT1_vect){
   a = a - 500;
   b = b + 500;
}

SIGNAL(INT0_vect){
   a = a + 500;
   b =  b - 500;
}

int main(void){

   DDRB |= _BV(PB0);
   DDRB |= _BV(PB1);
   DDRB |= _BV(PB2);
   
   PORTB = 0x00;
   GIMSK=0b11000000;
   MCUCR=0b00001111;
   DDRD = 0x00;
   sei();
   
   while(1){
      for(;;){
         led0(PB0, a, b);
         //led0(PB1, a, b);
         //led0(PB2, a, b);
      }
      
   }
}

Но проблема в том, что светодиод горит не плавно, а быстро-быстро мигает. Можно ли программно как-то исправить это (про другой кварц не надо)? Или существует более оптимальный программный способ решить мою задачу?


Вложения:
Комментарий к файлу: Это схема (для одного rgb светодиода)
attiny2313%20rgb%20led_schem.png [119.08 KiB]
Скачиваний: 418
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 12:34:17 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 2
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
kot2004 писал(а):
Можно ли программно как-то исправить это
можно. для этого надо сделать правильно программный ШИМ.
а правильный - это тот, который работает не в главном цикле, а по прерываниям.
настраиваете прерывание таймера на частоту, предположим 100 Гц.
в обработчике прерывания ведете счет в переменной-счетчике, и после каждого изменения счетчика сравниваете его значение со значением величин "каналов ШИМ" (тоже переменные). как только счетчик стал больше переменной канала, канал отключаете, пока счетчик меньше - канал включаете.

далее, по вашему коду:
1. SIGNAL - это устаревший макрос для обработчика прерываний, применяйте ISR
2. ваша функция delay_ms работать не будет. вы же подключили "библиотечный" модуль delay.h, так пользуйтесь "фирменными" функциями _delay_ms и _delay_us, где надо!

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 13:11:04 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
А можете пример кода привести? (Простите, что так наглею!)
Цитата:
далее, по вашему коду:
1. SIGNAL - это устаревший макрос для обработчика прерываний, применяйте ISR
2. ваша функция delay_ms работать не будет. вы же подключили "библиотечный" модуль delay.h, так пользуйтесь "фирменными" функциями _delay_ms и _delay_us, где надо!
Спасибо большое!


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 13:16:18 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
kot2004 писал(а):
А можете пример кода привести?
могу
Код:
volatile uint8_t pwm1; // первый канал
volatile uint8_t pwm2; // второй канал

ISR(TIMER0_OVF_vect){
   static uint8_t counter;
   
   counter++;
   if(counter < pwm1){
      // выключаем канал 1
   } else {
      // включаем канал 1
   }
   if(counter < pwm2){
      // выключаем канал 2
   } else {
      // включаем канал 2
   }
}

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 14:20:35 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
Написал такой код:

Код:
/*
 * GccApplication7.c
 *
 * Created: 20.04.2019 01:28:45
 * Author : Timofey
 */

#define F_CPU 10000000 //fuse LOW=0x7a
#include <avr/interrupt.h>
#include <util/delay.h>
#define BitIsClear(reg,bit) ((reg&(1<<bit)) ==0)

volatile uint8_t pwm1; // первый канал


ISR(TIMER0_OVF_vect)
{
   static uint8_t counter;
   
   counter++;
   if(counter < pwm1){
      // выключаем канал 1
      PORTB &=~(1<<PB0);
      } else {
      // включаем канал 1
      PORTB |= (1<<PB0);
   }
}

ISR(INT1_vect){
   pwm1--;
}

ISR(INT0_vect){
   pwm1++;
}


int main(void)
{
   DDRB=0b00000111; // установка PortB пины 0,1,2 выходы
   DDRD = 0;
   TIMSK = 0b00000010; // включить прерывание по переполнению таймера
   TCCR0B = 0b00000001; // настройка таймера, делитель выкл
   GIMSK=0b11000000;
   MCUCR=0b00001111;
   PORTB = 0;
   sei();               // разрешить прерывания

   while (1)       //бесконечная шарманка
   {

   }

}

Вопрос такой можно ли как-то изменить "разрешение" светодиода (сколько кликов нужно сделать кнопкой, чтобы светодиод загорелся на полную мощь)?


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 14:24:04 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
на сколько вы за 1 клик увеличите pwm1, настолько и яркость увеличится. надо еще контролировать "потолок" и "пол", ибо иначе все пойдет по кругу после перехода через край

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Чт апр 25, 2019 23:45:50 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
Потолок и пол контролирую! Все работает, дело в том, что при минимальной яркости светодиоды на каналах не погашены, а тускло горят. Как можно решить эту проблему?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 03:55:40 
Друг Кота
Аватар пользователя

Карма: 123
Рейтинг сообщений: 7955
Зарегистрирован: Сб сен 13, 2014 16:27:32
Сообщений: 39199
Откуда: СпиртоГонск созвездия Омега
Рейтинг сообщения: 0
выключателем питания

_________________
ZМудрость(Опыт и выдержка) приходит с годами.
Все Ваши беды и проблемы, от недостатка знаний.
Умный и у дурака научится, а дураку и ..
Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 08:26:17 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1384
Рейтинг сообщения: 10
Смотришь на современных новичков и жалко мне вас, и грустно. Засилие интернета отняло память. Зачем, если в любой момент можно кликнуть мышкой и получить информацию. Засилие игровых приставок, компьютеров, смартфонов отняло стимул к поиску нужной информации. Нажатие кнопок и кликание кнопой мышки отняло мелкую моторику. Суммируя все это - отняло интеллект. Моторика, поиск информации, осознанные действия формируют и тренируют синапсы. Взаимосвязи синапсов, память, умение оперировать полученной информацией, объектами - это и есть интеллект. Труд сделал из примата человека. Физический и умственный.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 11:37:35 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
выключателем питания
Я имел ввиду программно!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 12:53:38 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1384
Рейтинг сообщения: 0
Смотрим в даташит микроконтроллера и видим, что у AVR есть баг. При значении ШИМ равным нулю на выходе будут иголки, импульсы. Значит, если значение ШИМ равно нулю, отключаем бит ШИМ-а. Либо порт определяем как ВХОД. DDRX. X = 0, PORTX. X = 0.
Именно это я и имел в виду. Изучаете, соизвольте заглянуть в книжки, даташит. Поиск информации. Нашёл, получил результат. Получил удовлетворение. Заметьте никаких наркотиков даже не нужно. Поработал, получил удовлетворение от процесса, результата.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 13:00:09 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Demiurg писал(а):
у AVR есть баг
не баг, а фича :)

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 13:17:21 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
Demiurg писал(а):
у AVR есть баг
не баг, а фича :)
Вы же ему программный написали, при чем тут аппаратный?
kot2004 писал(а):
Я имел ввиду программно!
Спойлер
Код:
#define F_CPU 10000000 //fuse LOW=0x7a
#include <avr/interrupt.h>
#include <util/delay.h>
#define BitIsClear(reg,bit) ((reg&(1<<bit)) ==0)

volatile uint8_t pwm1; // первый канал


ISR(TIMER0_COMPA_vect)
{
   static uint8_t counter;
   
   counter++;
   if(counter < pwm1){
      // включаем канал 1
      PORTB |= (1<<PB0);
      } else {
      // выключаем канал 1
      PORTB &=~(1<<PB0);
   }
}

ISR(INT1_vect){
   if(--pwm1 == 255) pwm1=0;
}

ISR(INT0_vect){
   if(++pwm1 == 0) pwm1=255;
}


int main(void)
{
// Crystal Oscillator division factor: 1

CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);

// Input/Output Ports initialization
// Port A initialization
// Function: Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDRA2) | (0<<DDRA1) | (0<<DDRA0);
// State: Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port D initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit6=T Bit5=T Bit4=T Bit3=P Bit2=P Bit1=T Bit0=T
PORTD=(0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (1<<PORTD3) | (1<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 1 us
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// 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=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<TOIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<ICIE1) | (0<<OCIE0B) | (0<<TOIE0) | (1<<OCIE0A);

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=(1<<INT1) | (1<<INT0) | (0<<PCIE);
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIFR=(1<<INTF1) | (1<<INTF0) | (0<<PCIF);

// USI initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=(0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR=(0<<AIN0D) | (0<<AIN1D);
   sei();               // разрешить прерывания

   while (1)       //бесконечная шарманка
   {

   }

}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Пт апр 26, 2019 13:22:43 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Dimon456 писал(а):
при чем тут аппаратный?
вопрос не ко мне - я отвечал на упоминание аппаратного :)

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Сб апр 27, 2019 02:54:30 
Открыл глаза

Зарегистрирован: Пн сен 11, 2017 10:49:54
Сообщений: 53
Рейтинг сообщения: 0
Знаю, что наглею, но самим ни как не получается! Собрал такую схему (во вложении) и написал такую программу:
Код:
#define F_CPU 10000000
#include <avr/interrupt.h>
#include <util/delay.h>
volatile uint8_t i;

volatile uint8_t pwm1 = 0;
volatile uint8_t pwm2 = 0;
volatile uint8_t pwm3 = 0;

volatile uint8_t chanel = 2;


ISR(TIMER0_OVF_vect)
{
   static uint8_t counter;
   
   counter++;
   if (pwm1 != 0){
      if(counter < pwm1){

         PORTB &=~(1<<0);
      }
      else {

         PORTB |= (1<<0);
      }
   }
   else {
      PORTB &=~(1<<0);
   }
   
   
   
   if (pwm2 != 0){
      if(counter < pwm2){

         PORTB &=~(1<<1);
      }
      else {

         PORTB |= (1<<1);
      }
   }
   else {
      PORTB &=~(1<<1);
   }
   
   
   
   if (pwm3 != 0){
      if(counter < pwm3){

         PORTB &=~(1<<2);
      }
      else {

         PORTB |= (1<<2);
      }
   }
   else {
      PORTB &=~(1<<2);
   }
   
}


ISR(INT1_vect){
   i = PIND;
   if (!((1 << PD0) & i))
   {
      if (chanel == 1){
         if (pwm1 < 255){
            pwm1 = pwm1 + 2;
         }
      }
      
      if (chanel == 2){
         if (pwm2 < 255){
            pwm2 = pwm2 + 2;
         }
         
      }
      
      if (chanel == 3){
         if (pwm3 < 255){
            pwm3 = pwm3 + 2;
         }
         
      }
   }
   
   
   if (!((1 << PD1) & i))
   {
      if (chanel == 1){
         if (pwm1 > -1){
            pwm1 = pwm1 - 2;
         }
      }
      
      if (chanel == 2){
         if (pwm2 > -1){
            pwm2 = pwm2 - 2;
         }
         
      }
      
      if (chanel == 3){
         if (pwm3 > -1){
            pwm3 = pwm3 - 2;
         }
         
      }
   }
   
   
   if (!((1 << PD3) & i))
   {
      if (chanel < 3){
         chanel++;
      }
      else{
         chanel--;
      }
   }
}


int main(void)
{
   DDRB=0b00000111;
   DDRD = 0;
   TIMSK = 0b00000010;
   TCCR0B = 0b00000001;
   GIMSK=0b10000000;
   MCUCR=0b00001100;
   PORTB = 0;
   sei();         

   while (1)
   {

   }

}

Основная проблема такая: я хочу, чтобы при нажимании кнопки на PD3 происходило изменение канала шим. Даже завел отдельную переменную chanel. Но на практике ничего не происходит. Работает только тот канал, что я задал в начале программы. Что не так? Другой вопрос: как правильно определить пол и потолок, чтобы это не конфликтовало с условием гашения светодиода? Я попытался это как-то реализовать, но думаю, что не правильно! :oops:


Вложения:
dfsfsfsd.png [98.32 KiB]
Скачиваний: 428
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Сб апр 27, 2019 03:27:34 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1384
Рейтинг сообщения: 0
Где то валялся пример программного ШИМ-а на 32 светодиода... Но, на ассемблере...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Изменение яркости светодиода кнопкой
СообщениеДобавлено: Сб апр 27, 2019 08:07:48 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
kot2004 писал(а):
Я попытался это как-то реализовать, но думаю, что не правильно!
Вам же пример дали.
Вот другой пример, с картинками
Спойлер
Код:
#define F_CPU 10000000 //fuse LOW=0x7a
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t pwm0=0; // первый канал
volatile uint8_t pwm1=0; // второй канал
volatile uint8_t pwm2=0; // третий канал

volatile uint8_t chanel = 0;

#define max_chim 25   // 0-255 диапазон значений, чем больше разрешение шим тем меньше частота шим

ISR(TIMER0_COMPA_vect)
{
   static uint8_t counter;
 
   if (++counter==max_chim) { counter=0; }
   if(counter < pwm0){
      // включаем канал 0
      PORTB |= (1<<PB0);
      } else {
      // выключаем канал 0
      PORTB &=~(1<<PB0);
   }
   if(counter < pwm1){
      // включаем канал 1
      PORTB |= (1<<PB1);
      } else {
      // выключаем канал 1
      PORTB &=~(1<<PB1);
   } 
   if(counter < pwm2){
      // включаем канал 2
      PORTB |= (1<<PB2);
      } else {
      // выключаем канал 2
      PORTB &=~(1<<PB2);
   } 
   
}

ISR(INT1_vect){
   if (chanel == 0) if(--pwm0 > max_chim) pwm0=0;
   if (chanel == 1) if(--pwm1 > max_chim) pwm1=0;
   if (chanel == 2) if(--pwm2 > max_chim) pwm2=0;   
}

ISR(INT0_vect){
   if (chanel == 0) if(++pwm0 > max_chim) pwm0=max_chim;
   if (chanel == 1) if(++pwm1 > max_chim) pwm1=max_chim;
   if (chanel == 2) if(++pwm2 > max_chim) pwm2=max_chim;   
}


int main(void)
{
// Crystal Oscillator division factor: 1

CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);

// Input/Output Ports initialization
// Port A initialization
// Function: Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDRA2) | (0<<DDRA1) | (0<<DDRA0);
// State: Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port D initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit6=T Bit5=T Bit4=T Bit3=P Bit2=P Bit1=T Bit0=T
PORTD=(0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (1<<PORTD3) | (1<<PORTD2) | (0<<PORTD1) | (1<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 0,1 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x63;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// 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=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<TOIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<ICIE1) | (0<<OCIE0B) | (0<<TOIE0) | (1<<OCIE0A);

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=(1<<INT1) | (1<<INT0) | (0<<PCIE);
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIFR=(1<<INTF1) | (1<<INTF0) | (0<<PCIF);

// USI initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=(0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR=(0<<AIN0D) | (0<<AIN1D);
   sei();               // разрешить прерывания

   while (1)       //бесконечная шарманка
   {
    if ((PIND & (1<<PD1)) == 0) {
    _delay_ms (5);
     if ((PIND & (1<<PD1)) == 0) {
     _delay_ms (5);
     
   if(++chanel > 2) chanel=0;
   do { } while ((PIND & (1<<PD1)) == 0);   
      }
    }
   }
   
}
Изображение


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 17 ] 

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


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

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


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

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


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