Есть идея сделала ночник которым управляет 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{}
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 (у меня такой в сборке, а в протеусе другой), мне кажется, что нужно еще что нибудь добавить в схему или я ошибаюсь?
if (PINB.3==0 && i<255) //если на входе 3 ноль то
{
i++; //увеличиваем переменную i на единицу
delay_ms(50); //делаем паузу в милисикундах
}
if (PINB.4==0 && i>0) //если на входе 4 ноль то
{
i--; //уменьшаем переменную i на еденицу
delay_ms(50); //делаем паузу в милисикундах
}
PORTB.2=1;
теперь планирую сделать регулировку скорости двигателя )))))))
[url=http://www.unch.ru][color=#FF0000]Практически все схемы усилителей низкой частоты!!![/color][/url]
if (PINB.3==0)
{
while(!PINB.3); // ждём пока кнупер нажат, кстати тут же можно реализовать повтор
delay_ms(5); // избегаем дребезга контактов
// делаем что хотели
}
Прелестей сей констукции в том, что при 1 нажатии, действие выполняется 1 раз.
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 рас, чтобы диод засветился в полную силу. В моей же конструкции просто нажимаешь на кнопку и диод в течении пяти секунд плавно загорается до полной мощности, также и тухнет плавно в течении пяти секунд пока держу кнопку.
[url=http://www.unch.ru][color=#FF0000]Практически все схемы усилителей низкой частоты!!![/color][/url]
Здравствуйте. Я собрал данную схему, вроде все работает, вот только одна проблема, если отключить МК и включить его вновь, то яркость диодов опять на минимуме. Я так понимаю это из-за того что мы инициируем переменную i нулем. может нужно сохранять ее в память и потом из памяти извлекать ее значение? может кто помочь с этим?
zero648 писал(а):Дак эта.... проще пареной репы при изменении данной переменной сохраняем её в ЕЕПРОМ, а при инициализации вытаскиваем её оттуда
У спросившего не тот уровень, что бы понять это на пальцах.... Просто я сам не очень в теме, осмысливание вашего ответа у меня заняло 4 часа!
В этот раз результат обдумывания был положительным, действительно это делается проще пареной репы.
У меня подобный вопрос.
Скажите ШИМ регулируется только от 0 до 255. Мне интересен вариант от 0 до 1023, если это возможно , пожалуйста покажите в небольшом примере.
Спасибо.
TovsCat писал(а):У меня подобный вопрос.
Скажите ШИМ регулируется только от 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