простые интересные РАДИОСХЕМЫ сделанные своими руками

» СХЕМЫ
» ДАТАШИТЫ
Например: TDA1562
» Гость

Мы рады вас видеть. Пожалуйста зарегистрируйтесь или авторизируйтесь!





Отметить прочитанными   -   Поиск   -   Правила   -   Новые сообщения

  • Страница 1 из 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • »
Модератор форума: Электродыч, Sam, ВIOS  
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Драйвер для кемпингового фонаря на ATTiny13A (Нужна помощь)
Драйвер для кемпингового фонаря на ATTiny13A
Сб, 22.06.2019, 11:22 | Сообщение # 1        
34kilowatt
аватар
  Постов: 70  Offline ОК 
Всем доброго времени! Прошу помощи или направления для решения проблемы. Ситуfция такая - решил заменить драйвер светодиодного фонаря на неизвестном китайском МК, который ушел в мир иной на Тини13а. Набросал программку. На порту 0 и 1 сделал шим, 3 порт хочу сделать, как выход у управлять им полевиком, чтобы включать делитель напряжения в цепь АКБ и не жрать через него аккумулятор, когда фонарь не работает. На 4ом кнопка с внутренней подтяжкой. Порты нагружены светодиодами через резисторы 4.7к. Но столкнулся с проблемой - если включаю 3й порт, то все начинает глючить... Диоды на 0 и 3 порте или на 1 и 3м (если переключить кнопкой) начинают мигать с частотой герц 15-20 в пол накала. В протеусе тоже ситуация странная на выводах шим амплитуда всего чуть больше вольта, как закомментирую выделенные строки, все начинает работать нормально.
Листинг АтмельСтудио:

Код
#define F_CPU 9600000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//#include <avr/sleep.h>  // здесь описаны режимы сна

#define true 1    // логическое состояние правда
#define false 0    // логическое состояние ложь

volatile uint16_t voltVal = 0;   // переменная для накопления значений АЦП
volatile uint8_t sss1 = 0;    // счетчик значений АЦП
volatile uint8_t sleep_MODE = true;  // режим сна

uint8_t PWM_MODE[4] = {255, 0, 86, 172};  // режимы PWM (100%, 67%, 33%)
uint8_t LedMode = false;  // переключатель светодиодов

uint8_t butCount = 0;     // счетчик времени нажатия
uint8_t flgPress = false;    // признак кнопка в нажатом состоянии
uint8_t flgClick = false;    // признак отпускания кнопки
uint8_t switchLED = false;    // признак переключения диодов
uint8_t flgLngPress = false;   // признак удержания кнопки
uint8_t i = 0;       // счетчик

void Set_PWM (void) {

switch (LedMode) {
case 0:
DDRB &= (0 << PINB1);
DDRB |= (1 << PINB0);
OCR0A = PWM_MODE[i];
OCR0B = PWM_MODE[0];
break;

case 1:
DDRB &= (0 << PINB0);
DDRB |= (1 << PINB1);
OCR0A = PWM_MODE[0];
OCR0B = PWM_MODE[i];
break;
}// end switch

}// end Set_PWM()

/*
ISR(PCINT0_vect){

GIMSK=0x00; // Pin Change Interrupt выкл.
PCMSK=0x00; // PCINT4 откл.
if (sleep_MODE) sleep_MODE = false;
DDRB |= (1 << PINB3);  // порт 3 на выход (для подключения делителя)
PORTB |= (1 << PINB3);    // порт 3 высокий уровень

}// ISR(PCINT0_vect)
*/
/*
ISR (ADC_vect){

voltVal += ADCW;
sss1++;

if (sss1 > 10) {
voltVal = voltVal / sss1;
sss1 = 0;
}// end if

if (voltVal < 690){
sleep_MODE = true;
}// end if

}// end ISR (ADC_vect)
*/

int main(void){
/*
ADMUX |= (1 << REFS0) | (0 << ADLAR) | (1 << MUX0);    // внутреннее опорное напряжение,
// левое ориентирование данных, выбран вход ADC1
ADCSRA = 0xEF;    // АЦП включен, запуск преобразования, режим автоизмерения,
// прерывание по окончанию преобразования, частота CLK/128
ADCSRB = 0x00;    // режим автоизмерения: постоянно запущено
DIDR0 |= (1 << PINB2); // запрещаем цифровой вход на ноге аналогового входа
*/

PORTB |= (1 << PINB4);    // подтяжка кнопки порт 4, высокий на порт 3 (для включения делителя в цепь)
//DDRB |= (1 << PINB3);  // порт 3 на выход (для подключения делителя)

// Режим Fast PWM, частота сигнала=F_CPU / делитель*256
TCCR0A |= (1<<WGM00) | (1<<WGM01);    // Режим Fast PWM, таймер считает до 255 и сбрасывается в 0
TCCR0A |= (1<<COM0A1) | (1<<COM0A0); // 0 при равенстве регистров TCNT0 и OCROA. 1 при переполнении (инвертированный ШИМ-сигнал)
TCCR0A |= (1<<COM0B1) | (1<<COM0B0); // 1 при равенстве регистров TCNT0 и OCROB. 0 при переполнении (неинвертированный ШИМ-сигнал)
TCCR0B |= (1<<CS01);    // делитель 8
OCR0A = 255; // регистр сравнения (инвертированный сигнал ШИМ 255)
OCR0B = 255; // регистр сравнения (инвертированный сигнал ШИМ 0)

//_delay_ms(50);

//asm("sei");  //разрешаем глобально прерывания

//set_sleep_mode(SLEEP_MODE_PWR_DOWN); // если спать - то на полную

while(1) {

if ((PINB & (1 << PINB4)) == 0 && !flgLngPress) {
_delay_ms(10);  // задержка (защита от дребезга)
if ((PINB & (1 << PINB4)) == 0) {
flgPress = true;  // кнопка нажата (устанавливаем флаг в 1)
butCount++;    // начало отсчета нажатия кнопки
if (butCount > 100){
flgLngPress = true;
flgPress = false;    // сбрасываем флаг нажатия
butCount = 0;  // обнуляем счетчик времени нажатия
}// end if
}// end if
}// end if

if ((PINB & (1 << PINB4)) && flgLngPress){    // если отпустили после длительного нажатия
switchLED = false;
flgLngPress = false;
flgPress = false;    // сбрасываем флаг нажатия
flgClick = false;
}// end if

if (flgPress && (PINB & (1 << PINB4))){    // отпустили кнопку
flgClick = true;    // устанавливаем флаг клика
flgPress = false;    // сбрасываем флаг нажатия
butCount = 0;  // обнуляем счетчик времени нажатия
}// end if

if (flgLngPress && !switchLED){    // было удержание кнопки
LedMode++;  // переключаем на другой светодиод
if (LedMode > 1) LedMode = 0;
i = 1;
Set_PWM();    // устанавливаем режим светодиода
switchLED = true;
}// end if

if (flgClick){   // был клик
flgClick = false;    // сбрасываем флаг клика
i++;    // инкрементируем режим PWM
if (i > 3) i = 0;    // обнуляем счетчик
Set_PWM();   // устанавливаем режим светодиода
[b] if (i == 0){
sleep_MODE = true;
// отладка
//DDRB |= (1 << PINB3);    // порт 3 на выход
//PORTB |= (1 << PINB3);    // высокий уровень
}// end if
else{
// отладка
sleep_MODE = false;
//PORTB &= (0 << PINB3);    // низкий уровень
//DDRB &= (0 << PINB3);    // порт 3 на вход
}// end else
}// end if[/b]

/*if (sleep_MODE){

GIMSK=0x20; // Pin Change Interrupt Enable
PCMSK=0x10; // PCINT4 set для возращения в нормальный режим из сна
DDRB &= (0 << PINB3) | (0 << PINB1) | (0 << PINB0);    // выключаем светодиоды, делитель
PORTB = 0x00;   // отключаем подтяжку и высокий уровень на всех портах
sleep_enable(); // разрешаем сон
sleep_cpu(); // спать!

}// end if*/

}// end while(1)
}// end main


Схема Протеуса:


Отредактировал 34kilowatt - Сб, 22.06.2019, 11:25
Сб, 22.06.2019, 21:05 | Сообщение # 2        
DarkRus66
аватар
  Постов: 642  Offline Друзья 
Надо бы вначале огласить, что вы хотите от этого драйвера (плавная регулировка яркости, ступенчатая), какая мощность светодиодов в сумме (ток).
Готовые решения аналогичной проблемы уже были в этом разделе (или вам просто интересно написать свою программу?). https://radioskot.ru/publ....-0-1364
https://radioskot.ru/publ/remont/uluchshenie_raboty_fonarika/4-1-0-997
Для кемпингового же фонаря (IMHO), в большинстве случаев достаточно примитивного ШИМа на 7555 КМОП таймере с регулировкой (так обычно сделаны китайские фонари).
Сб, 22.06.2019, 22:53 | Сообщение # 3        
msmmmm
аватар
  Постов: 1089  Offline Друзья 
34kilowatt, у тебя сброс правильно подключен?
Пн, 24.06.2019, 08:45 | Сообщение # 4        
34kilowatt
аватар
  Постов: 70  Offline ОК 
В том фонаре, в который пытаюсь сделать драйвер, установлены 2 светодиода, 3 Вт и COB (кемпинговый режим). Для первого светодиода 2 режима яркости + стробоскоп, у второго - только 1 режим, затем фонарь выключается. При этом потребляет 3мА - что, как мне кажется, много. Ко всему этому отсутствует контроль разряда - фонарь будет высаживать АКБ вплоть до 1.5В, пока не отключится МК (по распиновке похож на 12F679, но китайцы затерли название).
Меня не устраивали режимы работы (сторобоскоп), и то что еще нужно заряжать каждые 1-1.5 месяца, чтобы АКБ не умерли. Плюс ко всему драйвер стал глючить, то не включается, то не выключается.
Вот и решил сделать на тиньке, т.к. ее функционала, по идее, должно хватить: 2 канала шим, 1 АЦП - отслеживание напряжения, 1 кнопка на несколько режимов, плюс при переключении переход в режим Power Down (для экономии АКБ). Выход из него по нажатию кнопки.
Но сейчас стоит вопрос, не в схеме фонаря, а в правильной работе самой тинки (прошивки).
Если у меня включены только 2 канада шим, кнопка, а остальные выходы на вход - то все работает как нужно. Но если устанавливаю 3-й порт на выход и включаю высокий уровень, начинает все глючить - диод на канале ШИМ мигает по переменно с диодом на 3 порте, переключая на другой канал ШИМ, тоже самое, только начинает мигать другой диод канала ШИМ.
Резет подключен на питание через резистор 10к, светодиоды через 4.7к, кнопка подтянута внутренним резистором.
Пн, 24.06.2019, 09:47 | Сообщение # 5        
msmmmm
аватар
  Постов: 1089  Offline Друзья 
Тщательно не смотрел, но что-то мне подсказывает, что эти команды делают совсем не то, что задумывалось smile :

PORTB &= (0 << PINB3); // низкий уровень
DDRB &= (0 << PINB3); // порт 3 на вход
Пн, 24.06.2019, 12:54 | Сообщение # 6        
34kilowatt
аватар
  Постов: 70  Offline ОК 
Здесь все нормально - сброс битов порта регистра в 0. Ошибку нашел "дело было не в бобине" (не включил порты 0 и 1 после выключения), в протеусе заработало. Но в железе все равно нормально не работает. Разбираюсь дальше. Видимо еще кнопку к минусу подтягивать придется...
Пн, 24.06.2019, 13:53 | Сообщение # 7        
msmmmm
аватар
  Постов: 1089  Offline Друзья 
Цитата 34kilowatt ()
Здесь все нормально

Ну, пусть будет "нормально" biggrin , в описании функции Set_PWM тот же косяк.
Если нужно сбросить весь регистр, достаточно написать
PORTB = 0 ;
А если нужно сбросить 1 бит, то:
DDRB &=~ (1 << PINB3); // порт 3 на вход,
Пн, 24.06.2019, 15:49 | Сообщение # 8        
34kilowatt
аватар
  Постов: 70  Offline ОК 
Да, все верно, написание сброса бита(ов) именно так и должно выглядеть. После ардуины (хотя и она в процессе изучения), бывает... Да прошивки не так часто пишу, забывается... Поправил, теперь пытаюсь в сон загнать, в протеусе работает, в железе не просыпается.


Отредактировал 34kilowatt - Пн, 24.06.2019, 16:21
Пн, 24.06.2019, 21:44 | Сообщение # 9        
msmmmm
аватар
  Постов: 1089  Offline Друзья 
34kilowatt, могу посмотреть, но нужна последняя версия исходника. С месяц назад делал жене измеритель влажности для цветов на тини13 с питанием от литиевого элемента - потребление в режиме сна - меньше 0,1мкА. Пока не забыл, может подскажу чего-нибудь. Хотя ковыряться в чужой программе - быстрее и проще свою написать smile .
Пн, 24.06.2019, 23:32 | Сообщение # 10        
nolpofaze
аватар
  Постов: 518  Offline Друзья 
34kilowatt, из сна, в железе и не должен выходить мк, в шпроте может выйти, у Вас подтяжка на инт4, там где кнопка, выключена в режиме сна. Вопрос, как мк отследить изменение уровня сигнала, при нажатии кнопки? Только, когда словит помеху.
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Драйвер для кемпингового фонаря на ATTiny13A (Нужна помощь)
  • Страница 1 из 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • »
Поиск:

Кто есть кто на форуме радиолюбителей: Администратор Модераторы Друзья Проверенные Новички
Группа вконтакте Канал ютуб Группа в фэйсбук Моб. версия © 2010-2020, "Радиосхемы". Все права защищены. Почта