вот ссылочка на описанное устройство, автор Сергей ака Слон
про ШИМ знаю, жаль мои способности не позволяют писать код самому. Проблема в том, что в варианте "плавного увеличения яркости" в самом начале, когда "светодиод" должен едва светиться, он начинает "дёргаться", "моргать", а уж потом начинает набирать яркость... хочу отписать напрямую автору, но там подтверждение регистрации "ручное", жду админа...
Описание устройства:
В зависимости от Ваших потребностей, Вы можете запрограммировать четыре различных поведения радиовыключателя. ============================================
1) Просто выключатель. Ручка (тумблер) внизу - нагрузка выключена ,ручка (тумблер) вверху - нагрузка включена. Этот режим пригоден для включения бортовых огней, имитатора звука мотора и пр.
2) Плавное включение в зависимости от положения ручки. Ручка внизу - выключено, ручка идет вверх - на нагрузке плавно увеличивается напряжение , ручка вверху - напряжение максимально. Это может пригодится для имитатора сопел турбин. В сопло турбины вставить яркие красные светодиоды, а вход радиоывключателя подсоединить через Y-кабель к каналу газа. Тогда чем больше газ, тем ярче красным светом горят сопла.
3) Режим мигания. Ручка (тумблер) внизу - выключено, ручка (тумблер) вверху - нагрузка мигает с частотой 2 раза в секунду. Это необходимо для имитации указателей поворота и аварийной сигнализации на автомоделях, так-же можно организовать бортовые огни на самолетах.
4)Защита от помех. Этот режим аналогичен первому. Ручка (тумблер) внизу - нагрузка выключена, ручка (тумблер) вверху - нагрузка включена. От первого режима этот отличается надежной защитой от помех - включение нагрузки происходит только если ручка передвинута вверх на время более 2 секунд. Этот режим используется для открытия тормозных парашутов и воспламенения запалов дымов.
=========================================== схемка внутри
Project : Version : Date : 08.06.2010 Author : F4CG Company : F4CG Comments:
Chip type : ATtiny13 Clock frequency : 4,800000 MHz Memory model : Tiny External SRAM size : 0 Data Stack size : 16 *****************************************************/
#include <tiny13.h> #include <delay.h>
#define OUT PORTB.2 #define KEY PINB.4
bit out_en=0; int tmp,ch,cmp1,cmp2,cmp3; char hi_byte,mode=0,tmp_del; char buf[0x0F]; char tmp_buf,buf_cnt; int tmp_ch;
eeprom char e_mode;
// Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { // работать только в плавной моде и с разрешенным выходом if ((mode==1) && (OCR0A < 250) && (out_en))OUT=1; }
// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { if (mode==1) OUT=0; //выключать только в плавной моде hi_byte++; }
// Pin change interrupt service routine interrupt [PCINT0] void pin_change_isr(void) { // 0.833 микросекунды на тик cmp1= ( ((int)TCNT0) + (((int)hi_byte)<<8) ); cmp2= ( ((int)TCNT0) + (((int)hi_byte)<<8) ); //читая два раза регистры, сравниваем if (cmp1==cmp2)cmp3=cmp1; // если совпали - все нормально else cmp3= ( ((int)TCNT0) + (((int)hi_byte)<<8) ); // если нет- перечитываем
if (PINB.3==1) tmp=cmp3; // фронт else ch= cmp3 - tmp; // спад 1000 - 2000 микросекунд (1200-2400 на тик)
}
void stick(void) { delay_ms(400); while (ch < 1700){}; //ждем ручку вверх delay_ms(400); while (ch > 1700){}; // ждем ручку вниз } ;
// мигнуть выходом void blink(void) { OUT=1; delay_ms(400); OUT=0; delay_ms(400); } // Declare your global variables here
void main(void) { // Declare your local variables here
out_en=0; delay_ms(500); // ждем корректного появления РРМа на входе
#asm("sei") while (KEY){// если разрезали перемычку - то это вход в сетап delay_ms(500); while (KEY) // войдем, если действительно разрезали { stick(); // // ручку туда - сюда e_mode=0; // сохранить в ЕЕПРОМе blink(); // одна вспышка - вкл-выкл
stick(); e_mode=1; // две вспышки - плавно blink(); blink();
stick(); e_mode=2; // три вспышки - мигалка blink(); blink(); blink();
stick(); e_mode=3; // четыре - вкл с защитой в 2 сек blink(); blink(); blink(); blink(); } }
mode=e_mode; // режим из ЕЕПРОМа в ОЗУ delay_ms(500); // ждем корректного появления РРМа на входе ch=1200; out_en=1; // разрешить работу выхода delay_ms(100);
while (1) { switch (mode) // выбор поведения от режима (ch - это длительность канального импульса от 1200 до 2200 ед.) { case 0: if (ch>1700) OUT=1; // включено - выключено else OUT=0; break;
case 1: if (ch > 2300) ch=2300; if (ch < 1300) ch= 1300; // плавно buf[buf_cnt]=0xFF - (char)( (ch-1299)/4 ); buf_cnt++; if (buf_cnt>0x0F)buf_cnt=0;
tmp_ch=0; for (tmp_buf=0;tmp_buf<0x0F;tmp_buf++){tmp_ch=tmp_ch+buf[tmp_buf];}
tmp_buf=(char)(tmp_ch/0x0f);
if (tmp_buf > 254) tmp_buf=254; if (tmp_buf < 1) tmp_buf= 1; // плавно OCR0A=tmp_buf; delay_ms(15); break;
case 2: if (ch > 1700) {if (OUT) OUT=0; else OUT=1; delay_ms(500);} // мигалка else OUT=0; break;
case 3: // с задержкой срабатывания 2 секунды if (ch > 1700) {tmp_del++; delay_ms(50);} else tmp_del=0; if (tmp_del > 40) {tmp_del=41; OUT=1;} else OUT=0; break;
default: // если ошибка ЕЕПРОМа то возврат к вкл-выкл mode=0; e_mode=0; break; } // end switch }; // end while1 } // end main
ещё не совсем понятно включение резистора R3 но это уже мелочи...
Сообщение отредактировал Plohish - Воскресенье, 21.04.2013, 19:31
а чего их не хватит? два входа, два выхода... всего 4 ножки
Добавлено (03.05.2013, 22:01) --------------------------------------------- ради интереса собрал все свои скудные знания, написал прошиву на тиньку13 по дискретному включению светодиода при определённой длительности импульса, думал потом переделаю в ШИМ, а не тут то было...
Уважаемый ВитГо, может подскажете... Я для определения длительности импульса использую единственный присутствующий в 13 тиньке таймер, т.е. каждый "восходящий" фронт я его запускаю, и каждый "спадающий" читаю значение счётчика, всё работает... однако когда вопрос коснулся ШИМ, там тоже нужно использовать таймер, но ведь этот таймер каждые 20мс отвлекается на подсчёт длительности...
Короче я впал в ступор и не знаю что делать далее...
нужно настроить таймер и выбрать режим ШИМ с вершиной в OCRA ( ШИМ аппаратный отдельный таймер настраивать не нужно ) затем замерить длину импульса ( с помощью таймера ) исходя из длины входящего импульса - задать длину импульса/скважности в ШИМ вроде все... не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Пятница, 03.05.2013, 23:03
вероятно нужно определять длительность импульса каким то иным способом, не трогая таймера... по-моему это единственный путь... в программе "слона" похоже так и делается... но мозга не хватает разобраться как
жаль что в ней ШИМ работает не совсем корректно... она бы меня устроила полностью... автор отказался ковыряться... сослался на занятость и то что уже сто лет не кодил...
Сообщение отредактировал Plohish - Пятница, 03.05.2013, 23:13
Мне то-же в голову лезет лишь один вариант - определить длительность без таймера. Может соорудить какой ни-будь самодельный таймер ? не успеваю за своими мыслями......
да о программном, только вот не могу придумать как его организовать. может, например, крутимся в цикле и к числу ( в R16 например ), каждый раз, добавляем единицу - вот и самый простой таймер таймер выходим из цикла по падающему фронту, а по нарастающему фронту входим в этот цикл
_______________ на ноге 4 логический нуль ? ( допусти приемник к RC SWITCH подключен через 4 ногу тини 13 ) _______________ если логический нуль, то выходим из цикла _______________ если логическая единица то переходим на метку cicle не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Пятница, 03.05.2013, 23:46
Вопрос в том, как определять "что на ноге"... и сколько времени это займёт... в соответствии с этим насколько ваш таймер будет точным...
даже используя встроенный таймер тиньки, я получаю раз от разу цифры с некоторой погрешностью, что в принципе не есть хорошо, приходится городить механизм усреднения...
с другой стороны большой точности тут не нужно, идея вполне реальная... надо подумать
Сообщение отредактировал Plohish - Пятница, 03.05.2013, 23:55