Есть идея сделала ночник которым управляет ATtiny13 с помощью ШИМ одна нога мк является выходом (5) для ШИМ и управляет транзисторным ключом который соответственно регулирует яркость свечения 1Вт светодиода другой порт (например 2) ступенчато регулирует яркость от 0% до 100% другой порт (например 3) регулирует яркость в меньшую сторону еще один порт (6,7) ресет регулировки яркости хорошо было бы регулировалось 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% Прошу помощи в написании программы на Си и если можно то с комментариями так чтобы я этому научился. Спасибо
1) Открываем даташит на тини13 2) Находим описание работы ШИМ модуля 3) рисуем печатку, собираем 4) пишем программу: инициализируем порты; инициализируем ШИМ модуль; пишем обработчик для кнопочек; передаём данные в соотвествующий регистр.
Мои вопросы: 1) а не много ли 110 люмен для ночника? 2) Светодиод прибор чувствительный к перегреву. Одноватник радиатор требует 3) у вас питание каким напряжением планируется? небось вольт 5 минимум? - спалите светодиод при Коэффициенте заполнения > ~0.7
1) насколько я знаю 1ватт это вроде всего 40 люмен,более производительные слишком дорого стоят
2) правильно,предлагаю снабдить систему еще и ограничителем тока диода. 3) тут я могу сослаться на 2 пункт,все равно больше,чем нужно не возьмет.а можно и все ограничить( ток и напряжение).
_________________ В поисках истины человек развивается.
Всем привет, прошу помощи, решил на Attiny13 сделать плавную регулировку яркости диода с помощью аппаратного ШИМ. Пожалуйста укажите на мои ошибки, я вроде как написал программу и протестировал в протеусе, но диод не плавно загорается, а просто моргает. Регулировка осуществляется двумя кнопками. Вот код:
Код:
/***************************************************** This program was produced by the CodeWizardAVR V2.05.0 Professional Project : Shim_4 Version : Date : 10.02.2012 Author : NeVaDa Chip type : ATtiny13 AVR Core Clock frequency: 8,000000 MHz Memory model : Tiny External RAM size : 0 Data Stack size : 16 *****************************************************/
#include <tiny13.h> #include <delay.h>
interrupt [TIM0_OVF] void timer0_ovf_isr(void) { } int i=0; //инициализируем переменную i нулем void main(void) { #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif PORTB=0x3C; DDRB=0x03; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125,000 kHz // Mode: Fast PWM top=0xFF // OC0A output: Non-Inverted PWM // OC0B output: Non-Inverted PWM TCCR0A=0xA3; TCCR0B=0x03; TCNT0=0; //OCR0A=i; //Отключаем управление ШИМ и переносим его в программу OCR0B=0; GIMSK=0x00; MCUCR=0x00; TIMSK0=0x02; ACSR=0x80; ADCSRB=0x00; DIDR0=0x00; ADCSRA=0x00; #asm("sei")
while (1) { OCR0A=i; //инициализируем регулировку ШИМ переменной i if (PINB.3==0 && i<255) //если на входе 3 ноль и переменная меньше 255 то { i++; //увеличиваем переменную i на единицу delay_ms(3); //делаем паузу в милисикундах } else //если же на 3 входе еденица то { //ничего не делаем } if (PINB.4==0 && i>0) //если на входе 4 ноль и переменная больше нуля то { i--; //уменьшаем переменную i на еденицу delay_ms(3); //делаем паузу в миллисекундах } else //если же на входе 4 единица то { //ничего не делаем } } }
Пожалуйста опишите подробно мои ошибки, так как я еще не полностью понял принцип работы ШИМ в этом микроконтроллере.
Можно изменить частоту таймера, а возможно прот не успевает так быстро моргать:) По видео понятно, что все правильно генерируется. Так что собирайте в железе.
По коду могу сказать,что прерывание по переполнению можно убрать:) Также можно убрать пустые else{}
А еще можно в форуме пользоваться командами
Код:
[spoiler] [/spoiler] [code=php][/code]
СпойлерБольшой фрагмент текста
Код:
ADCSRA=0x00;
while (1)//Код си { }
_________________ В поисках истины человек развивается.
while (1) { OCR0A=i; //инициализируем регулировку ШИМ переменной i if (PINB.3==0 && i<255) //если на входе 3 ноль и переменная меньше 255 то { i++; //увеличиваем переменную i на единицу delay_ms(3); //делаем паузу в милисикундах } } }
Ну, вы батенька даёте... Итак, что ВЫ делаете, преверяете нажата ли кнопка, если нажата то инкементируете и, потом поять проверяете если нажата(а она то всё ещё нажата, задержка всего-то 3 мс) и пошло поехало... 255* 3 = 765 мс. значит за 765 мс удержания кнопочки, в OCR будет 255....а чтоб светодиод засветился "на полную" как глазу кажется, достаточно и 50% заполенеия импульса. Вобщем исправлйте вашу работу с кнопками:)
Спасибо! Сейчас проверю и отпишу результат, получается, что протеус не показал это, в нем как то все на много медленнее происходит . На сколько я понимаю, для времени загорания в пять секунд мне нужно выставить 20миллисекунд. Буду экспериментировать. ******************************************************************************************************************
Ура, заработало, даже не пойму что именно было причиной, т.к. изменив время между циклами я просто увеличил время плавного возгорания диода, а проблема была в том, что диод просто моргал при включении, и кнопки ни как не влияли на него.
Но появилась еще одна проблема, диод загорается плавно как положено, но тухнет раз в десять дольше, и тоже не могу понять в чем причина... вот код
Код:
OCR0A=i; //инициализируем регулировку ШИМ переменной i
if (PINB.3==0 && i<255) //если на входе 3 ноль то { i++; //увеличиваем переменную i на единицу delay_ms(20); //делаем паузу в милисикундах }
if (PINB.4==0 && i>0) //если на входе 4 ноль то { i--; //уменьшаем переменную i на еденицу delay_ms(20); //делаем паузу в милисикундах }
Может причина в кроется не в микросхеме и не в коде, а в IRF44N (у меня такой в сборке, а в протеусе другой), мне кажется, что нужно еще что нибудь добавить в схему или я ошибаюсь?
Может и в самом деле микросхема не успевала все просчитать, установил по 50 миллисекунд и все заработало нормально.
Искренне рад, что у вас получилось! На будущие рекомендую делать так:
Код:
if (PINB.3==0) { while(!PINB.3); // ждём пока кнупер нажат, кстати тут же можно реализовать повтор delay_ms(5); // избегаем дребезга контактов // делаем что хотели }
Прелестей сей констукции в том, что при 1 нажатии, действие выполняется 1 раз.
Карма: 1
Рейтинг сообщений: 5
Зарегистрирован: Ср май 11, 2011 21:37:45 Сообщений: 1995 Откуда: Цветочный город
Рейтинг сообщения:0
Shapa писал(а):
На будущие рекомендую делать так:
Код:
if (PINB.3==0) { while(!PINB.3); // ждём пока кнупер нажат, кстати тут же можно реализовать повтор delay_ms(5); // избегаем дребезга контактов // делаем что хотели }
Прелестей сей констукции в том, что при 1 нажатии, действие выполняется 1 раз.
прелесть этой кнострукции в том, что вы всегда сможете надеяться на сюрприз: оно будет срабатывать при каждом нажатии кнопки или 1 раз, или два... или три... и при отпускании тоже иной раз будет срабатывать... как повезет будет очень интересно
_________________ битва с дураками проиграна, победители торжествуют. слава победителям!
if (PINB.3==0) { while(!PINB.3); // ждём пока кнупер нажат, кстати тут же можно реализовать повтор delay_ms(5); // избегаем дребезга контактов // делаем что хотели }
Прелестей сей констукции в том, что при 1 нажатии, действие выполняется 1 раз.
Мне кажется, что так все же не удобно (неудобно именно для моей цели), это мне нужно будет нажать на кнопку 255 рас, чтобы диод засветился в полную силу. В моей же конструкции просто нажимаешь на кнопку и диод в течении пяти секунд плавно загорается до полной мощности, также и тухнет плавно в течении пяти секунд пока держу кнопку.
Здравствуйте. Я собрал данную схему, вроде все работает, вот только одна проблема, если отключить МК и включить его вновь, то яркость диодов опять на минимуме. Я так понимаю это из-за того что мы инициируем переменную i нулем. может нужно сохранять ее в память и потом из памяти извлекать ее значение? может кто помочь с этим?
Дак эта.... проще пареной репы при изменении данной переменной сохраняем её в ЕЕПРОМ, а при инициализации вытаскиваем её оттуда
У спросившего не тот уровень, что бы понять это на пальцах.... Просто я сам не очень в теме, осмысливание вашего ответа у меня заняло 4 часа! В этот раз результат обдумывания был положительным, действительно это делается проще пареной репы. У меня подобный вопрос. Скажите ШИМ регулируется только от 0 до 255. Мне интересен вариант от 0 до 1023, если это возможно , пожалуйста покажите в небольшом примере. Спасибо.
У меня подобный вопрос. Скажите ШИМ регулируется только от 0 до 255. Мне интересен вариант от 0 до 1023, если это возможно , пожалуйста покажите в небольшом примере. Спасибо.
Для ШИМа от 0 до 1023 нужен 16 битный счетчик, если реализовать аппаратно, с другой стороны, если делать программно, то можно любой счетчик.
Пример настройки аппаратного ШИМа 0-255 и 0-1023: Спойлер
Код:
.include "m8def.inc" ; Используем ATMega8
; ROM ===============
.CSEG ; ROM
.org $000 rjmp RESET ; External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset reti ; INT0 Внешнее прерывание 0 reti ; INT1 Внешнее прерывание 1 reti ; TIMER2 COMP Совпадение таймера/счетчика Т2 reti ; TIMER2 OVF Переполнение таймера/счетчика Т2 reti ; TIMER1 CAPT Захват таймера/счетчика Т1 reti ; TIMER1 COMPA Совпадение «А» таймера/счетчика Т1 reti ; TIMER1 COMPB Совпадение «В» таймера/счетчика Т1 reti ; TIMER1 OVF Переполнение таймера/счетчика Т1 reti ; TIMER0 OVF Переполнение таймера/счетчика Т0 reti ; SPI, STC Передача по SPI завершена reti ; USART,RXC USART, прием завершен reti ; USART,UDRE Регистр данных USART пуст reti ; USART,TXC USART, передача завершена reti ; ADC Преобразование АЦП завершено reti ; EE_RDY EEPROM, готово reti ; ANA_COMP Аналоговый компаратор reti ; TWI Two-wire Serial Interface reti ; SPM_RDY Готовность Store Program Memory
; ---------- R E S E T ----------
.ORG INT_VECTORS_SIZE ; Конец таблицы прерываний
RESET: cli ldi r16, high(RAMEND) ; Set Stack Pointer to top of RAM out SPH, r16 ; ldi r16, low(RAMEND) ; out SPL, r16 ;
; ---------- M A I N P R O G R A M M ----------
PORTS_Init: ldi r16, 0b00001010 out DDRB, r16 ldi r16, 0b00000000 out PORTB, r16
PWM_8_Init: ldi r16, 100 ; этим меняем скважность out OCR2, r16 ldi r16, (0b11<<WGM20) ; Set Fast PWM mode ori r16, (0b11<<COM20) ; Вкл OC2 при совпадении, сбрасываем OC2 при максимуме ori r16, (0b010<<CS20) ; Prescaler 010=1:8 out TCCR2, r16 ; Enable TCNT2 PWM_16_Init: ldi r16, 254 ; этим и ldi r17, 3 ; этим меняем скважность от 0 до 1023 out OCR1AH, r17 out OCR1AL, r16 ldi r16, (0b11<<WGM10) ; Set low Fast PWM mode, 10-bit ldi r17, (0b01<<WGM12) ; Set hig Fast PWM mode, 10-bit ori r16, (0b11<<COM1A0); Вкл OC1A при совпадении, сбрасываем OC1A при максимуме ori r17, (0b010<<CS10) ; Prescaler 010=1:8 out TCCR1A, r16 ; out TCCR1B, r17 ; Enable TCNT1 sei
MAIN_loop: in r16,MCUCR ori r16, 0x80 out MCUCR, r16 sleep ; Отдыхаем пока не началось rjmp MAIN_loop ; Go again
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения